mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'master' into bot-maint
This commit is contained in:
commit
35eeaaa16f
54 changed files with 1528 additions and 615 deletions
|
|
@ -118,8 +118,9 @@ set(SRB2_SDL2_EXE_NAME srb2kart CACHE STRING "Executable binary output name")
|
|||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(assets)
|
||||
|
||||
if(NOT ${SRB2_CONFIG_DEV_BUILD})
|
||||
add_subdirectory(assets)
|
||||
endif()
|
||||
|
||||
## config.h generation
|
||||
set(GIT_EXECUTABLE "git" CACHE FILEPATH "Path to git binary")
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ set(SRB2_CONFIG_YASM OFF CACHE BOOL
|
|||
"Use YASM in place of NASM.")
|
||||
set(SRB2_CONFIG_STATIC_OPENGL OFF CACHE BOOL
|
||||
"Use statically linked OpenGL. NOT RECOMMENDED.")
|
||||
set(SRB2_CONFIG_DEV_BUILD OFF CACHE BOOL
|
||||
"Compile a development build of SRB2Kart.")
|
||||
|
||||
### use internal libraries?
|
||||
if(${CMAKE_SYSTEM} MATCHES "Windows") ###set on Windows only
|
||||
|
|
@ -280,6 +282,10 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|||
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -Wno-absolute-value)
|
||||
endif()
|
||||
|
||||
if(${SRB2_CONFIG_DEV_BUILD})
|
||||
target_compile_definitions(SRB2SDL2 PRIVATE -DDEVELOP)
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -Wno-trigraphs)
|
||||
|
||||
target_compile_definitions(SRB2SDL2 PRIVATE -DCMAKECONFIG)
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ ifdef DEBUGMODE
|
|||
ifdef GCC48
|
||||
opts+=-Og
|
||||
else
|
||||
opts+=O0
|
||||
opts+=-O0
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ tables.c
|
|||
r_bsp.c
|
||||
r_data.c
|
||||
r_draw.c
|
||||
r_fps.c
|
||||
r_main.c
|
||||
r_plane.c
|
||||
r_segs.c
|
||||
|
|
|
|||
|
|
@ -88,6 +88,12 @@ tic_t I_GetTime(void)
|
|||
return (since_start*TICRATE)/1000000;
|
||||
}
|
||||
|
||||
fixed_t I_GetTimeFrac(void)
|
||||
{
|
||||
//stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
void I_Sleep(void){}
|
||||
|
||||
void I_GetEvent(void){}
|
||||
|
|
|
|||
|
|
@ -1916,6 +1916,8 @@ void CON_SetLoadingProgress(con_loadprogress_t newStep)
|
|||
if (con_startup_loadprogress < LOADED_ISTARTUPGRAPHICS) // rendering not possible?
|
||||
return;
|
||||
CON_DrawLoadBar(); // here we display the console text
|
||||
I_OsPolling();
|
||||
I_UpdateNoBlit();
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ UINT8 adminpassmd5[16];
|
|||
boolean adminpasswordset = false;
|
||||
|
||||
// Client specific
|
||||
static ticcmd_t localcmds[MAXSPLITSCREENPLAYERS];
|
||||
static ticcmd_t localcmds[MAXSPLITSCREENPLAYERS][MAXGENTLEMENDELAY];
|
||||
static boolean cl_packetmissed;
|
||||
// here it is for the secondary local player (splitscreen)
|
||||
static UINT8 mynode; // my address pointofview server
|
||||
|
|
@ -440,10 +440,15 @@ static void D_Clearticcmd(tic_t tic)
|
|||
|
||||
void D_ResetTiccmds(void)
|
||||
{
|
||||
INT32 i;
|
||||
INT32 i, j;
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
memset(&localcmds[i], 0, sizeof(ticcmd_t));
|
||||
{
|
||||
for (j = 0; j < MAXGENTLEMENDELAY; j++)
|
||||
{
|
||||
memset(&localcmds[i][j], 0, sizeof(ticcmd_t));
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the net command list
|
||||
for (i = 0; i < TEXTCMD_HASH_SIZE; i++)
|
||||
|
|
@ -2390,6 +2395,7 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
|
|||
|
||||
// remove avatar of player
|
||||
playeringame[playernum] = false;
|
||||
demo_extradata[playernum] |= DXD_PLAYSTATE;
|
||||
playernode[playernum] = UINT8_MAX;
|
||||
while (!playeringame[doomcom->numslots-1] && doomcom->numslots > 1)
|
||||
doomcom->numslots--;
|
||||
|
|
@ -4934,12 +4940,6 @@ static void CL_SendClientCmd(void)
|
|||
size_t packetsize = 0;
|
||||
boolean mis = false;
|
||||
|
||||
if (lowest_lag && ( gametic % lowest_lag ))
|
||||
{
|
||||
cl_packetmissed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
netbuffer->packettype = PT_CLIENTCMD;
|
||||
|
||||
if (cl_packetmissed)
|
||||
|
|
@ -4960,27 +4960,35 @@ static void CL_SendClientCmd(void)
|
|||
}
|
||||
else if (gamestate != GS_NULL && (addedtogame || dedicated))
|
||||
{
|
||||
UINT8 lagDelay = 0;
|
||||
|
||||
if (lowest_lag > 0)
|
||||
{
|
||||
// Gentlemens' ping.
|
||||
lagDelay = min(lowest_lag, MAXGENTLEMENDELAY);
|
||||
}
|
||||
|
||||
packetsize = sizeof (clientcmd_pak);
|
||||
G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds[0], 1);
|
||||
netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%TICQUEUE]);
|
||||
G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds[0][lagDelay], 1);
|
||||
netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic % TICQUEUE]);
|
||||
|
||||
if (splitscreen) // Send a special packet with 2 cmd for splitscreen
|
||||
{
|
||||
netbuffer->packettype = (mis ? PT_CLIENT2MIS : PT_CLIENT2CMD);
|
||||
packetsize = sizeof (client2cmd_pak);
|
||||
G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds[1], 1);
|
||||
G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds[1][lagDelay], 1);
|
||||
|
||||
if (splitscreen > 1)
|
||||
{
|
||||
netbuffer->packettype = (mis ? PT_CLIENT3MIS : PT_CLIENT3CMD);
|
||||
packetsize = sizeof (client3cmd_pak);
|
||||
G_MoveTiccmd(&netbuffer->u.client3pak.cmd3, &localcmds[2], 1);
|
||||
G_MoveTiccmd(&netbuffer->u.client3pak.cmd3, &localcmds[2][lagDelay], 1);
|
||||
|
||||
if (splitscreen > 2)
|
||||
{
|
||||
netbuffer->packettype = (mis ? PT_CLIENT4MIS : PT_CLIENT4CMD);
|
||||
packetsize = sizeof (client4cmd_pak);
|
||||
G_MoveTiccmd(&netbuffer->u.client4pak.cmd4, &localcmds[3], 1);
|
||||
G_MoveTiccmd(&netbuffer->u.client4pak.cmd4, &localcmds[3][lagDelay], 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5143,8 +5151,23 @@ static void SV_SendTics(void)
|
|||
//
|
||||
// TryRunTics
|
||||
//
|
||||
static void CreateNewLocalCMD(UINT8 p, INT32 realtics)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = MAXGENTLEMENDELAY-1; i > 0; i--)
|
||||
{
|
||||
G_MoveTiccmd(&localcmds[p][i], &localcmds[p][i-1], 1);
|
||||
}
|
||||
|
||||
G_BuildTiccmd(&localcmds[p][0], realtics, p+1);
|
||||
localcmds[p][0].flags |= TICCMD_RECEIVED;
|
||||
}
|
||||
|
||||
static void Local_Maketic(INT32 realtics)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
I_OsPolling(); // I_Getevent
|
||||
D_ProcessEvents(); // menu responder, cons responder,
|
||||
// game responder calls HU_Responder, AM_Responder,
|
||||
|
|
@ -5153,25 +5176,9 @@ static void Local_Maketic(INT32 realtics)
|
|||
if (!dedicated) rendergametic = gametic;
|
||||
|
||||
// translate inputs (keyboard/mouse/joystick) into game controls
|
||||
G_BuildTiccmd(&localcmds[0], realtics, 1);
|
||||
localcmds[0].flags |= TICCMD_RECEIVED;
|
||||
|
||||
if (splitscreen)
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
G_BuildTiccmd(&localcmds[1], realtics, 2);
|
||||
localcmds[1].flags |= TICCMD_RECEIVED;
|
||||
|
||||
if (splitscreen > 1)
|
||||
{
|
||||
G_BuildTiccmd(&localcmds[2], realtics, 3);
|
||||
localcmds[2].flags |= TICCMD_RECEIVED;
|
||||
|
||||
if (splitscreen > 2)
|
||||
{
|
||||
G_BuildTiccmd(&localcmds[3], realtics, 4);
|
||||
localcmds[3].flags |= TICCMD_RECEIVED;
|
||||
}
|
||||
}
|
||||
CreateNewLocalCMD(i, realtics);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5264,12 +5271,14 @@ void TryRunTics(tic_t realtics)
|
|||
|
||||
if (neededtic > gametic)
|
||||
{
|
||||
hu_stopped = false;
|
||||
if (realtics)
|
||||
hu_stopped = false;
|
||||
}
|
||||
|
||||
if (player_joining)
|
||||
{
|
||||
hu_stopped = true;
|
||||
if (realtics)
|
||||
hu_stopped = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -5288,6 +5297,7 @@ void TryRunTics(tic_t realtics)
|
|||
while (neededtic > gametic)
|
||||
{
|
||||
DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic));
|
||||
prev_tics = I_GetTime();
|
||||
|
||||
ps_tictime = I_GetPreciseTime();
|
||||
|
||||
|
|
@ -5306,7 +5316,8 @@ void TryRunTics(tic_t realtics)
|
|||
}
|
||||
else
|
||||
{
|
||||
hu_stopped = true;
|
||||
if (realtics)
|
||||
hu_stopped = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,15 @@ applications may follow different packet versions.
|
|||
// Networking and tick handling related.
|
||||
#define TICQUEUE 512 // more than enough for most timeouts....
|
||||
#define MAXTEXTCMD 256
|
||||
|
||||
// No. of tics your controls can be delayed by.
|
||||
|
||||
// TODO: Instead of storing a ton of extra cmds for gentlemens' delay,
|
||||
// keep them in a linked-list, with timestamps to discard everything that's older than already sent.
|
||||
// That will support any amount of lag, and be less wasteful for clients who don't use it.
|
||||
// This just works as a quick implementation.
|
||||
#define MAXGENTLEMENDELAY TICRATE
|
||||
|
||||
//
|
||||
// Packet structure
|
||||
//
|
||||
|
|
|
|||
48
src/d_main.c
48
src/d_main.c
|
|
@ -63,6 +63,7 @@
|
|||
#include "deh_tables.h" // Dehacked list test
|
||||
#include "m_cond.h" // condition initialization
|
||||
#include "fastcmp.h"
|
||||
#include "r_fps.h" // Frame interpolation/uncapped
|
||||
#include "keys.h"
|
||||
#include "filesrch.h" // refreshdirmenu
|
||||
#include "g_input.h" // tutorial mode control scheming
|
||||
|
|
@ -755,7 +756,7 @@ void D_SRB2Loop(void)
|
|||
debugload--;
|
||||
#endif
|
||||
|
||||
if (!realtics && !singletics)
|
||||
if (!realtics && !singletics && cv_frameinterpolation.value != 1)
|
||||
{
|
||||
I_Sleep();
|
||||
continue;
|
||||
|
|
@ -773,13 +774,37 @@ void D_SRB2Loop(void)
|
|||
// process tics (but maybe not if realtic == 0)
|
||||
TryRunTics(realtics);
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
fixed_t entertimefrac = I_GetTimeFrac();
|
||||
// renderdeltatics is a bit awkard to evaluate, since the system time interface is whole tic-based
|
||||
renderdeltatics = realtics * FRACUNIT;
|
||||
if (entertimefrac > rendertimefrac)
|
||||
renderdeltatics += entertimefrac - rendertimefrac;
|
||||
else
|
||||
renderdeltatics -= rendertimefrac - entertimefrac;
|
||||
|
||||
rendertimefrac = entertimefrac;
|
||||
}
|
||||
else
|
||||
{
|
||||
rendertimefrac = FRACUNIT;
|
||||
renderdeltatics = realtics * FRACUNIT;
|
||||
}
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
D_Display();
|
||||
}
|
||||
|
||||
if (lastdraw || singletics || gametic > rendergametic)
|
||||
{
|
||||
rendergametic = gametic;
|
||||
rendertimeout = entertic+TICRATE/17;
|
||||
|
||||
// Update display, next frame, with current state.
|
||||
D_Display();
|
||||
// (Only display if not already done for frame interp)
|
||||
cv_frameinterpolation.value == 0 ? D_Display() : 0;
|
||||
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
|
|
@ -788,7 +813,22 @@ void D_SRB2Loop(void)
|
|||
}
|
||||
else if (rendertimeout < entertic) // in case the server hang or netsplit
|
||||
{
|
||||
D_Display();
|
||||
#if 0
|
||||
// Lagless camera! Yay!
|
||||
if (gamestate == GS_LEVEL && netgame)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
{
|
||||
if (camera[i].chase)
|
||||
P_MoveChaseCamera(&players[displayplayers[i]], &camera[i], false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// (Only display if not already done for frame interp)
|
||||
cv_frameinterpolation.value == 0 ? D_Display() : 0;
|
||||
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
|
|
@ -1639,6 +1679,8 @@ void D_SRB2Main(void)
|
|||
// as having been modified for the first game.
|
||||
M_PushSpecialParameters(); // push all "+" parameter at the command buffer
|
||||
|
||||
COM_BufExecute(); // ensure the command buffer gets executed before the map starts (+skin)
|
||||
|
||||
strncpy(connectedservername, cv_servername.string, MAXSERVERNAME);
|
||||
|
||||
if (M_CheckParm("-gametype") && M_IsNextParm())
|
||||
|
|
|
|||
|
|
@ -768,15 +768,21 @@ void D_RegisterClientCommands(void)
|
|||
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
{
|
||||
Color_cons_t[i].value = Followercolor_cons_t[i].value = i;
|
||||
Color_cons_t[i].strvalue = Followercolor_cons_t[i].strvalue = skincolors[i].name;
|
||||
Color_cons_t[i].value = i;
|
||||
Color_cons_t[i].strvalue = skincolors[i].name;
|
||||
}
|
||||
|
||||
Followercolor_cons_t[MAXSKINCOLORS].value = MAXSKINCOLORS;
|
||||
Followercolor_cons_t[MAXSKINCOLORS].strvalue = "Match"; // Add "Match" option, which will make the follower color match the player's
|
||||
for (i = 2; i < MAXSKINCOLORS; i++)
|
||||
{
|
||||
Followercolor_cons_t[i].value = i-2;
|
||||
Followercolor_cons_t[i].strvalue = skincolors[i-2].name;
|
||||
}
|
||||
|
||||
Followercolor_cons_t[MAXSKINCOLORS+1].value = MAXSKINCOLORS+1;
|
||||
Followercolor_cons_t[MAXSKINCOLORS+1].strvalue = "Opposite"; // Add "Opposite" option, ...which is like "Match", but for coloropposite.
|
||||
Followercolor_cons_t[1].value = -1;
|
||||
Followercolor_cons_t[1].strvalue = "Match"; // Add "Match" option, which will make the follower color match the player's
|
||||
|
||||
Followercolor_cons_t[0].value = -2;
|
||||
Followercolor_cons_t[0].strvalue = "Opposite"; // Add "Opposite" option, ...which is like "Match", but for coloropposite.
|
||||
|
||||
Color_cons_t[MAXSKINCOLORS].value = Followercolor_cons_t[MAXSKINCOLORS+2].value = 0;
|
||||
Color_cons_t[MAXSKINCOLORS].strvalue = Followercolor_cons_t[MAXSKINCOLORS+2].strvalue = NULL;
|
||||
|
|
@ -1398,7 +1404,9 @@ static void SendNameAndColor(UINT8 n)
|
|||
|
||||
if (!strcmp(cv_playername[n].string, player_names[playernum])
|
||||
&& cv_playercolor[n].value == player->skincolor
|
||||
&& !strcmp(cv_skin[n].string, skins[player->skin].name))
|
||||
&& !strcmp(cv_skin[n].string, skins[player->skin].name)
|
||||
&& cv_follower[n].value == player->followerskin
|
||||
&& cv_followercolor[n].value == player->followercolor)
|
||||
return;
|
||||
|
||||
player->availabilities = R_GetSkinAvailabilities();
|
||||
|
|
|
|||
|
|
@ -198,11 +198,18 @@ typedef enum
|
|||
#undef KSPIN_TYPE
|
||||
} kartspinoutflags_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TRIP_NONE,
|
||||
TRIP_PASSED,
|
||||
TRIP_BLOCKED,
|
||||
} tripwirestate_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
// Unsynced, HUD or clientsided effects
|
||||
// Item box
|
||||
khud_itemblink, // Item flashing after roulette, prevents Hyudoro stealing AND serves as a mashing indicator
|
||||
khud_itemblink, // Item flashing after roulette, serves as a mashing indicator
|
||||
khud_itemblinkmode, // Type of flashing: 0 = white (normal), 1 = red (mashing), 2 = rainbow (enhanced items)
|
||||
|
||||
// Rings
|
||||
|
|
@ -470,6 +477,8 @@ typedef struct player_s
|
|||
|
||||
SINT8 glanceDir; // Direction the player is trying to look backwards in
|
||||
|
||||
UINT8 tripWireState; // see tripwirestate_t
|
||||
|
||||
//
|
||||
|
||||
SINT8 lives;
|
||||
|
|
|
|||
|
|
@ -334,7 +334,6 @@ actionpointer_t actionpointers[] =
|
|||
{{A_ReaperThinker}, "A_REAPERTHINKER"},
|
||||
{{A_FlameShieldPaper}, "A_FLAMESHIELDPAPER"},
|
||||
{{A_InvincSparkleRotate}, "A_INVINCSPARKLEROTATE"},
|
||||
{{A_SpawnItemCapsuleParts}, "A_SPAWNITEMCAPSULEPARTS"},
|
||||
|
||||
{{NULL}, "NONE"},
|
||||
|
||||
|
|
@ -3490,9 +3489,9 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
"S_ITEMCAPSULE_TOP_SIDE",
|
||||
"S_ITEMCAPSULE_BOTTOM_SIDE_AIR",
|
||||
"S_ITEMCAPSULE_BOTTOM_SIDE_GROUND",
|
||||
"S_ITEMCAPSULE_TOP",
|
||||
"S_ITEMCAPSULE_BOTTOM",
|
||||
"S_ITEMCAPSULE_INSIDE",
|
||||
//"S_ITEMCAPSULE_TOP",
|
||||
//"S_ITEMCAPSULE_BOTTOM",
|
||||
//"S_ITEMCAPSULE_INSIDE",
|
||||
|
||||
// Signpost sparkles
|
||||
"S_SIGNSPARK1",
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ tic_t I_GetTime(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int I_GetTimeMicros(void)
|
||||
fixed_t I_GetTimeFrac(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
13
src/f_wipe.c
13
src/f_wipe.c
|
|
@ -299,16 +299,23 @@ static void F_DoWipe(fademask_t *fademask, lighttable_t *fadecolormap, boolean r
|
|||
e = e_base + relativepos;
|
||||
draw_rowstogo = draw_rowend - draw_rowstart;
|
||||
|
||||
while (draw_rowstogo--)
|
||||
if (fadecolormap)
|
||||
{
|
||||
if (fadecolormap != NULL)
|
||||
if (reverse)
|
||||
s = e;
|
||||
while (draw_rowstogo--)
|
||||
*w++ = fadecolormap[ ( m << 8 ) + *s++ ];
|
||||
}
|
||||
else while (draw_rowstogo--)
|
||||
{
|
||||
/*if (fadecolormap != NULL)
|
||||
{
|
||||
if (reverse)
|
||||
*w++ = fadecolormap[ ( m << 8 ) + *e++ ];
|
||||
else
|
||||
*w++ = fadecolormap[ ( m << 8 ) + *s++ ];
|
||||
}
|
||||
else
|
||||
else*/
|
||||
*w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
|
||||
}
|
||||
|
||||
|
|
|
|||
50
src/g_demo.c
50
src/g_demo.c
|
|
@ -112,6 +112,10 @@ demoghost *ghosts = NULL;
|
|||
#define DF_BREAKTHECAPSULES 0x04 // This demo is from Break the Capsules and contains its final completion time!
|
||||
#define DF_ATTACKMASK 0x06 // This demo is from ??? attack and contains ???
|
||||
|
||||
// 0x08 free
|
||||
|
||||
#define DF_NONETMP 0x10 // multiplayer but not netgame
|
||||
|
||||
#define DF_LUAVARS 0x20 // this demo contains extra lua vars
|
||||
|
||||
#define DF_ATTACKSHIFT 1
|
||||
|
|
@ -304,11 +308,12 @@ void G_ReadDemoExtraData(void)
|
|||
}
|
||||
if (extradata & DXD_PLAYSTATE)
|
||||
{
|
||||
extradata = READUINT8(demo_p);
|
||||
i = READUINT8(demo_p);
|
||||
|
||||
switch (extradata) {
|
||||
switch (i) {
|
||||
case DXD_PST_PLAYING:
|
||||
players[p].pflags |= PF_WANTSTOJOIN; // fuck you
|
||||
//CONS_Printf("player %s is despectating on tic %d\n", player_names[p], leveltime);
|
||||
break;
|
||||
|
||||
case DXD_PST_SPECTATING:
|
||||
|
|
@ -319,9 +324,11 @@ void G_ReadDemoExtraData(void)
|
|||
playeringame[p] = true;
|
||||
G_AddPlayer(p);
|
||||
players[p].spectator = true;
|
||||
//CONS_Printf("player %s is joining server on tic %d\n", player_names[p], leveltime);
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONS_Printf("player %s is spectating on tic %d\n", player_names[p], leveltime);
|
||||
players[p].spectator = true;
|
||||
if (players[p].mo)
|
||||
P_DamageMobj(players[p].mo, NULL, NULL, 1, DMG_INSTAKILL);
|
||||
|
|
@ -343,11 +350,11 @@ void G_ReadDemoExtraData(void)
|
|||
}
|
||||
if (extradata & DXD_WEAPONPREF)
|
||||
{
|
||||
extradata = READUINT8(demo_p);
|
||||
i = READUINT8(demo_p);
|
||||
players[p].pflags &= ~(PF_KICKSTARTACCEL);
|
||||
if (extradata & 1)
|
||||
if (i & 1)
|
||||
players[p].pflags |= PF_KICKSTARTACCEL;
|
||||
//CONS_Printf("weaponpref is %d for player %d\n", extradata, p);
|
||||
//CONS_Printf("weaponpref is %d for player %d\n", i, p);
|
||||
}
|
||||
|
||||
p = READUINT8(demo_p);
|
||||
|
|
@ -366,7 +373,7 @@ void G_ReadDemoExtraData(void)
|
|||
P_SetRandSeed(rng);
|
||||
|
||||
if (demosynced)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced (RNG)!\n"));
|
||||
demosynced = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -493,6 +500,7 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
|
|||
|
||||
if (!demo_p || !demo.deferstart)
|
||||
return;
|
||||
|
||||
ziptic = READUINT8(demo_p);
|
||||
|
||||
if (ziptic & ZT_FWD)
|
||||
|
|
@ -530,7 +538,7 @@ void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
|
|||
|
||||
if (cmd->forwardmove != oldcmd[playernum].forwardmove)
|
||||
{
|
||||
WRITEUINT8(demo_p,cmd->forwardmove);
|
||||
WRITESINT8(demo_p,cmd->forwardmove);
|
||||
oldcmd[playernum].forwardmove = cmd->forwardmove;
|
||||
ziptic |= ZT_FWD;
|
||||
}
|
||||
|
|
@ -863,7 +871,12 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
|
|||
|
||||
void G_ConsAllGhostTics(void)
|
||||
{
|
||||
UINT8 p = READUINT8(demo_p);
|
||||
UINT8 p;
|
||||
|
||||
if (!demo_p || !demo.deferstart)
|
||||
return;
|
||||
|
||||
p = READUINT8(demo_p);
|
||||
|
||||
while (p != 0xFF)
|
||||
{
|
||||
|
|
@ -888,8 +901,6 @@ void G_ConsGhostTic(INT32 playernum)
|
|||
mobj_t *testmo;
|
||||
UINT32 syncleeway;
|
||||
|
||||
if (!demo_p || !demo.deferstart)
|
||||
return;
|
||||
if (!(demoflags & DF_GHOST))
|
||||
return; // No ghost data to use.
|
||||
|
||||
|
|
@ -966,7 +977,7 @@ void G_ConsGhostTic(INT32 playernum)
|
|||
if (th != &thlist[THINK_MOBJ] && mobj->health != health) // Wasn't damaged?! This is desync! Fix it!
|
||||
{
|
||||
if (demosynced)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced (health)!\n"));
|
||||
demosynced = false;
|
||||
P_DamageMobj(mobj, players[0].mo, players[0].mo, 1, DMG_NORMAL);
|
||||
}
|
||||
|
|
@ -1019,7 +1030,7 @@ void G_ConsGhostTic(INT32 playernum)
|
|||
if (ghostext[playernum].desyncframes >= 2)
|
||||
{
|
||||
if (demosynced)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
|
||||
CONS_Alert(CONS_WARNING, "Demo playback has desynced (player %s)!\n", player_names[playernum]);
|
||||
demosynced = false;
|
||||
|
||||
P_UnsetThingPosition(testmo);
|
||||
|
|
@ -1042,7 +1053,7 @@ void G_ConsGhostTic(INT32 playernum)
|
|||
|| players[playernum].bumpers != ghostext[playernum].kartbumpers)
|
||||
{
|
||||
if (demosynced)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced (item/bumpers)!\n"));
|
||||
demosynced = false;
|
||||
|
||||
players[playernum].itemtype = ghostext[playernum].kartitem;
|
||||
|
|
@ -1580,7 +1591,7 @@ void G_ReadMetalTic(mobj_t *metal)
|
|||
oldmetal.x = READFIXED(metal_p);
|
||||
oldmetal.y = READFIXED(metal_p);
|
||||
oldmetal.z = READFIXED(metal_p);
|
||||
P_TeleportMove(metal, oldmetal.x, oldmetal.y, oldmetal.z);
|
||||
P_MoveOrigin(metal, oldmetal.x, oldmetal.y, oldmetal.z);
|
||||
oldmetal.x = metal->x;
|
||||
oldmetal.y = metal->y;
|
||||
oldmetal.z = metal->z;
|
||||
|
|
@ -1921,6 +1932,9 @@ void G_BeginRecording(void)
|
|||
demo_p = demobuffer;
|
||||
demoflags = DF_GHOST|(multiplayer ? DF_MULTIPLAYER : (modeattacking<<DF_ATTACKSHIFT));
|
||||
|
||||
if (multiplayer && !netgame)
|
||||
demoflags |= DF_NONETMP;
|
||||
|
||||
if (encoremode)
|
||||
demoflags |= DF_ENCORE;
|
||||
|
||||
|
|
@ -2838,6 +2852,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
|
||||
modeattacking = (demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT;
|
||||
multiplayer = !!(demoflags & DF_MULTIPLAYER);
|
||||
demo.netgame = (multiplayer && !(demoflags & DF_NONETMP));
|
||||
CON_ToggleOff();
|
||||
|
||||
hu_demotime = UINT32_MAX;
|
||||
|
|
@ -2927,7 +2942,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
|
||||
while (p != 0xFF)
|
||||
{
|
||||
if ((spectator = (p & DEMO_SPECTATOR)))
|
||||
if ((spectator = !!(p & DEMO_SPECTATOR)))
|
||||
{
|
||||
p &= ~DEMO_SPECTATOR;
|
||||
|
||||
|
|
@ -2975,6 +2990,11 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
M_Memcpy(player_names[p],demo_p,16);
|
||||
demo_p += 16;
|
||||
|
||||
/*if (players[p].spectator)
|
||||
{
|
||||
CONS_Printf("player %s is spectator at start\n", player_names[p]);
|
||||
}*/
|
||||
|
||||
// Skin
|
||||
M_Memcpy(skin,demo_p,16);
|
||||
demo_p += 16;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ struct demovars_s {
|
|||
boolean inreplayhut; // Go back to replayhut after demos
|
||||
boolean quitafterplaying; // quit after playing a demo from cmdline
|
||||
boolean deferstart; // don't start playing demo right away
|
||||
boolean netgame; // multiplayer netgame
|
||||
|
||||
tic_t savebutton; // Used to determine when the local player can choose to save the replay while the race is still going
|
||||
enum {
|
||||
|
|
|
|||
19
src/g_game.c
19
src/g_game.c
|
|
@ -45,8 +45,8 @@
|
|||
#include "y_inter.h"
|
||||
#include "v_video.h"
|
||||
#include "lua_hook.h"
|
||||
#include "k_bot.h"
|
||||
#include "m_cond.h" // condition sets
|
||||
#include "r_fps.h" // frame interpolation/uncapped
|
||||
#include "lua_hud.h"
|
||||
|
||||
// SRB2kart
|
||||
|
|
@ -56,6 +56,7 @@
|
|||
#include "k_color.h"
|
||||
#include "k_respawn.h"
|
||||
#include "k_grandprix.h"
|
||||
#include "k_bot.h"
|
||||
#include "doomstat.h"
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
|
|
@ -1920,6 +1921,8 @@ void G_Ticker(boolean run)
|
|||
F_TextPromptTicker();
|
||||
AM_Ticker();
|
||||
HU_Ticker();
|
||||
R_UpdateViewInterpolation();
|
||||
|
||||
break;
|
||||
|
||||
case GS_INTERMISSION:
|
||||
|
|
@ -1976,7 +1979,12 @@ void G_Ticker(boolean run)
|
|||
break;
|
||||
|
||||
case GS_TITLESCREEN:
|
||||
if (titlemapinaction) P_Ticker(run);
|
||||
if (titlemapinaction)
|
||||
{
|
||||
P_Ticker(run);
|
||||
R_UpdateViewInterpolation();
|
||||
}
|
||||
|
||||
F_TitleScreenTicker(run);
|
||||
break;
|
||||
|
||||
|
|
@ -2287,6 +2295,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
p->karthud[khud_fault] = khudfault;
|
||||
p->nocontrol = nocontrol;
|
||||
p->kickstartaccel = kickstartaccel;
|
||||
p->tripWireState = TRIP_NONE;
|
||||
|
||||
memcpy(&p->respawn, &respawn, sizeof (p->respawn));
|
||||
|
||||
|
|
@ -2551,7 +2560,7 @@ mapthing_t *G_FindRaceStart(INT32 playernum)
|
|||
if (j == i)
|
||||
continue;
|
||||
|
||||
if (netgame && cv_kartusepwrlv.value)
|
||||
if ((netgame || (demo.playback && demo.netgame)) && cv_kartusepwrlv.value)
|
||||
{
|
||||
if (clientpowerlevels[j][PWRLV_RACE] == clientpowerlevels[i][PWRLV_RACE])
|
||||
num++;
|
||||
|
|
@ -2572,7 +2581,7 @@ mapthing_t *G_FindRaceStart(INT32 playernum)
|
|||
pos++;
|
||||
else
|
||||
{
|
||||
if (netgame && cv_kartusepwrlv.value)
|
||||
if ((netgame || (demo.playback && demo.netgame)) && cv_kartusepwrlv.value)
|
||||
{
|
||||
if (clientpowerlevels[i][PWRLV_RACE] > clientpowerlevels[playernum][PWRLV_RACE])
|
||||
pos++;
|
||||
|
|
@ -3112,7 +3121,7 @@ boolean G_GametypeHasTeams(void)
|
|||
//
|
||||
boolean G_GametypeHasSpectators(void)
|
||||
{
|
||||
return (netgame || (multiplayer && demo.playback));
|
||||
return (netgame || (multiplayer && demo.netgame));
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "../m_cheat.h"
|
||||
#include "../f_finale.h"
|
||||
#include "../r_things.h" // R_GetShadowZ
|
||||
#include "../d_main.h"
|
||||
#include "../p_slopes.h"
|
||||
#include "hw_md2.h"
|
||||
|
||||
|
|
@ -1478,7 +1479,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
transnum_t transtable = R_GetLinedefTransTable(gl_linedef);
|
||||
if (transtable == NUMTRANSMAPS)
|
||||
transtable = 0;
|
||||
if (gl_linedef->special == 910)
|
||||
if (gl_linedef->special == 910 ||
|
||||
P_IsLineTripWire(gl_linedef))
|
||||
blend = AST_ADD;
|
||||
else if (gl_linedef->special == 911)
|
||||
blend = AST_SUBTRACT;
|
||||
|
|
@ -3622,10 +3624,6 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v
|
|||
|
||||
static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
||||
{
|
||||
fixed_t thingxpos = thing->x + thing->sprxoff;
|
||||
fixed_t thingypos = thing->y + thing->spryoff;
|
||||
fixed_t thingzpos = thing->z + thing->sprzoff;
|
||||
|
||||
patch_t *gpatch;
|
||||
FOutVector shadowVerts[4];
|
||||
FSurfaceInfo sSurf;
|
||||
|
|
@ -3642,7 +3640,19 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
fixed_t slopez;
|
||||
pslope_t *groundslope;
|
||||
|
||||
// hitlag vibrating
|
||||
fixed_t interpx = thing->x;
|
||||
fixed_t interpy = thing->y;
|
||||
fixed_t interpz = thing->z;
|
||||
|
||||
// do interpolation
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x);
|
||||
interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y);
|
||||
interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z);
|
||||
}
|
||||
|
||||
// hitlag vibrating (todo: interp somehow?)
|
||||
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
|
||||
{
|
||||
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
|
||||
|
|
@ -3652,14 +3662,19 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
mul = -mul;
|
||||
}
|
||||
|
||||
thingxpos += FixedMul(thing->momx, mul);
|
||||
thingypos += FixedMul(thing->momy, mul);
|
||||
thingzpos += FixedMul(thing->momz, mul);
|
||||
interpx += FixedMul(thing->momx, mul);
|
||||
interpy += FixedMul(thing->momy, mul);
|
||||
interpz += FixedMul(thing->momz, mul);
|
||||
}
|
||||
|
||||
// sprite offset
|
||||
interpx += thing->sprxoff;
|
||||
interpy += thing->spryoff;
|
||||
interpz += thing->sprzoff;
|
||||
|
||||
groundz = R_GetShadowZ(thing, &groundslope);
|
||||
|
||||
floordiff = abs((flip < 0 ? thing->height : 0) + thingzpos - groundz);
|
||||
floordiff = abs((flip < 0 ? thing->height : 0) + interpz - groundz);
|
||||
|
||||
alpha = floordiff / (4*FRACUNIT) + 75;
|
||||
if (alpha >= 255) return;
|
||||
|
|
@ -3673,8 +3688,8 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height);
|
||||
|
||||
fscale = FIXED_TO_FLOAT(scalemul);
|
||||
fx = FIXED_TO_FLOAT(thingxpos);
|
||||
fy = FIXED_TO_FLOAT(thingypos);
|
||||
fx = FIXED_TO_FLOAT(interpx);
|
||||
fy = FIXED_TO_FLOAT(interpy);
|
||||
|
||||
// 3--2
|
||||
// | /|
|
||||
|
|
@ -5012,10 +5027,6 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
// BP why not use xtoviexangle/viewangletox like in bsp ?....
|
||||
static void HWR_ProjectSprite(mobj_t *thing)
|
||||
{
|
||||
fixed_t thingxpos = thing->x + thing->sprxoff;
|
||||
fixed_t thingypos = thing->y + thing->spryoff;
|
||||
fixed_t thingzpos = thing->z + thing->sprzoff;
|
||||
|
||||
gl_vissprite_t *vis;
|
||||
float tr_x, tr_y;
|
||||
float tz;
|
||||
|
|
@ -5055,13 +5066,34 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
angle_t spriterotangle = 0;
|
||||
#endif
|
||||
|
||||
// uncapped/interpolation
|
||||
fixed_t interpx;
|
||||
fixed_t interpy;
|
||||
fixed_t interpz;
|
||||
angle_t interpangle;
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
if (thing->spritexscale < 1 || thing->spriteyscale < 1)
|
||||
return;
|
||||
|
||||
// hitlag vibrating
|
||||
dispoffset = thing->info->dispoffset;
|
||||
|
||||
interpx = thing->x;
|
||||
interpy = thing->y;
|
||||
interpz = thing->z;
|
||||
interpangle = mobjangle;
|
||||
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x);
|
||||
interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y);
|
||||
interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z);
|
||||
interpangle = mobjangle;
|
||||
}
|
||||
|
||||
// hitlag vibrating (todo: interp somehow?)
|
||||
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
|
||||
{
|
||||
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
|
||||
|
|
@ -5071,20 +5103,23 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
mul = -mul;
|
||||
}
|
||||
|
||||
thingxpos += FixedMul(thing->momx, mul);
|
||||
thingypos += FixedMul(thing->momy, mul);
|
||||
thingzpos += FixedMul(thing->momz, mul);
|
||||
interpx += FixedMul(thing->momx, mul);
|
||||
interpy += FixedMul(thing->momy, mul);
|
||||
interpz += FixedMul(thing->momz, mul);
|
||||
}
|
||||
|
||||
dispoffset = thing->info->dispoffset;
|
||||
// sprite offset
|
||||
interpx += thing->sprxoff;
|
||||
interpy += thing->spryoff;
|
||||
interpz += thing->sprzoff;
|
||||
|
||||
this_scale = FIXED_TO_FLOAT(thing->scale);
|
||||
spritexscale = FIXED_TO_FLOAT(thing->spritexscale);
|
||||
spriteyscale = FIXED_TO_FLOAT(thing->spriteyscale);
|
||||
|
||||
// transform the origin point
|
||||
tr_x = FIXED_TO_FLOAT(thingxpos) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(thingypos) - gl_viewy;
|
||||
tr_x = FIXED_TO_FLOAT(interpx) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(interpy) - gl_viewy;
|
||||
|
||||
// rotation around vertical axis
|
||||
tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin);
|
||||
|
|
@ -5107,8 +5142,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
}
|
||||
|
||||
// The above can stay as it works for cutting sprites that are too close
|
||||
tr_x = FIXED_TO_FLOAT(thingxpos);
|
||||
tr_y = FIXED_TO_FLOAT(thingypos);
|
||||
tr_x = FIXED_TO_FLOAT(interpx);
|
||||
tr_y = FIXED_TO_FLOAT(interpy);
|
||||
|
||||
// decide which patch to use for sprite relative to player
|
||||
#ifdef RANGECHECK
|
||||
|
|
@ -5156,7 +5191,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
I_Error("sprframes NULL for sprite %d\n", thing->sprite);
|
||||
#endif
|
||||
|
||||
ang = R_PointToAngle (thingxpos, thingypos) - mobjangle;
|
||||
ang = R_PointToAngle (interpx, interpy) - interpangle;
|
||||
if (mirrored)
|
||||
ang = InvAngle(ang);
|
||||
|
||||
|
|
@ -5303,12 +5338,12 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (vflip)
|
||||
{
|
||||
gz = FIXED_TO_FLOAT(thingzpos + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||
gz = FIXED_TO_FLOAT(interpz + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||
gzt = gz + (FIXED_TO_FLOAT(spr_height) * this_yscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
gzt = FIXED_TO_FLOAT(thingzpos) + (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||
gzt = FIXED_TO_FLOAT(interpz) + (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||
gz = gzt - (FIXED_TO_FLOAT(spr_height) * this_yscale);
|
||||
}
|
||||
|
||||
|
|
@ -5319,7 +5354,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
}
|
||||
|
||||
heightsec = thing->subsector->sector->heightsec;
|
||||
if (viewplayer->mo && viewplayer->mo->subsector)
|
||||
if (viewplayer && viewplayer->mo && viewplayer->mo->subsector)
|
||||
phs = viewplayer->mo->subsector->sector->heightsec;
|
||||
else
|
||||
phs = -1;
|
||||
|
|
@ -5327,12 +5362,12 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
|
||||
{
|
||||
if (gl_viewz < FIXED_TO_FLOAT(sectors[phs].floorheight) ?
|
||||
FIXED_TO_FLOAT(thingzpos) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
|
||||
FIXED_TO_FLOAT(interpz) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
|
||||
gzt < FIXED_TO_FLOAT(sectors[heightsec].floorheight))
|
||||
return;
|
||||
if (gl_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ?
|
||||
gzt < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gl_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) :
|
||||
FIXED_TO_FLOAT(thingzpos) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight))
|
||||
FIXED_TO_FLOAT(interpz) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight))
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -5467,9 +5502,29 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
unsigned rot = 0;
|
||||
UINT8 flip;
|
||||
|
||||
// uncapped/interpolation
|
||||
fixed_t interpx;
|
||||
fixed_t interpy;
|
||||
fixed_t interpz;
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
interpx = thing->x;
|
||||
interpy = thing->y;
|
||||
interpz = thing->z;
|
||||
|
||||
// do interpolation
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x);
|
||||
interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y);
|
||||
interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z);
|
||||
}
|
||||
|
||||
// transform the origin point
|
||||
tr_x = FIXED_TO_FLOAT(thing->x) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(thing->y) - gl_viewy;
|
||||
tr_x = FIXED_TO_FLOAT(interpx) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(interpy) - gl_viewy;
|
||||
|
||||
// rotation around vertical axis
|
||||
tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin);
|
||||
|
|
@ -5478,8 +5533,8 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
if (tz < ZCLIP_PLANE)
|
||||
return;
|
||||
|
||||
tr_x = FIXED_TO_FLOAT(thing->x);
|
||||
tr_y = FIXED_TO_FLOAT(thing->y);
|
||||
tr_x = FIXED_TO_FLOAT(interpx);
|
||||
tr_y = FIXED_TO_FLOAT(interpy);
|
||||
|
||||
// decide which patch to use for sprite relative to player
|
||||
if ((unsigned)thing->sprite >= numsprites)
|
||||
|
|
@ -5546,7 +5601,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
#endif
|
||||
|
||||
// set top/bottom coords
|
||||
vis->gzt = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset);
|
||||
vis->gzt = FIXED_TO_FLOAT(interpz + spritecachedinfo[lumpoff].topoffset);
|
||||
vis->gz = vis->gzt - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height);
|
||||
|
||||
vis->precip = true;
|
||||
|
|
@ -6701,6 +6756,8 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
// 10 by 10 grid. 2 coordinates (xy)
|
||||
float v[SCREENVERTS][SCREENVERTS][2];
|
||||
static double disStart = 0;
|
||||
static fixed_t last_fractime = 0;
|
||||
|
||||
UINT8 x, y;
|
||||
INT32 WAVELENGTH;
|
||||
INT32 AMPLITUDE;
|
||||
|
|
@ -6732,6 +6789,15 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
HWD.pfnPostImgRedraw(v);
|
||||
if (!(paused || P_AutoPause()))
|
||||
disStart += 1;
|
||||
if (renderdeltatics > FRACUNIT)
|
||||
{
|
||||
disStart = disStart - FIXED_TO_FLOAT(last_fractime) + 1 + FIXED_TO_FLOAT(rendertimefrac);
|
||||
}
|
||||
else
|
||||
{
|
||||
disStart = disStart - FIXED_TO_FLOAT(last_fractime) + FIXED_TO_FLOAT(rendertimefrac);
|
||||
}
|
||||
last_fractime = rendertimefrac;
|
||||
|
||||
// Capture the screen again for screen waving on the intermission
|
||||
if(gamestate != GS_INTERMISSION)
|
||||
|
|
|
|||
|
|
@ -1355,10 +1355,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
|
||||
// Look at HWR_ProjectSprite for more
|
||||
{
|
||||
fixed_t thingxpos = spr->mobj->x + spr->mobj->sprxoff;
|
||||
fixed_t thingypos = spr->mobj->y + spr->mobj->spryoff;
|
||||
fixed_t thingzpos = spr->mobj->z + spr->mobj->sprzoff;
|
||||
|
||||
patch_t *gpatch, *blendgpatch;
|
||||
GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL;
|
||||
INT32 durs = spr->mobj->state->tics;
|
||||
|
|
@ -1371,6 +1367,18 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
INT32 mod;
|
||||
float finalscale;
|
||||
|
||||
fixed_t interpx = spr->mobj->x;
|
||||
fixed_t interpy = spr->mobj->y;
|
||||
fixed_t interpz = spr->mobj->z;
|
||||
|
||||
// do interpolation
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
interpx = spr->mobj->old_x + FixedMul(rendertimefrac, spr->mobj->x - spr->mobj->old_x);
|
||||
interpy = spr->mobj->old_y + FixedMul(rendertimefrac, spr->mobj->y - spr->mobj->old_y);
|
||||
interpz = spr->mobj->old_z + FixedMul(rendertimefrac, spr->mobj->z - spr->mobj->old_z);
|
||||
}
|
||||
|
||||
// hitlag vibrating
|
||||
if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG))
|
||||
{
|
||||
|
|
@ -1381,11 +1389,16 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
mul = -mul;
|
||||
}
|
||||
|
||||
thingxpos += FixedMul(spr->mobj->momx, mul);
|
||||
thingypos += FixedMul(spr->mobj->momy, mul);
|
||||
thingzpos += FixedMul(spr->mobj->momz, mul);
|
||||
interpx += FixedMul(spr->mobj->momx, mul);
|
||||
interpy += FixedMul(spr->mobj->momy, mul);
|
||||
interpy += FixedMul(spr->mobj->momz, mul);
|
||||
}
|
||||
|
||||
// sprite offset
|
||||
interpx += spr->mobj->sprxoff;
|
||||
interpy += spr->mobj->spryoff;
|
||||
interpz += spr->mobj->sprzoff;
|
||||
|
||||
// Apparently people don't like jump frames like that, so back it goes
|
||||
//if (tics > durs)
|
||||
//durs = tics;
|
||||
|
|
@ -1605,13 +1618,13 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
#endif
|
||||
|
||||
//Hurdler: it seems there is still a small problem with mobj angle
|
||||
p.x = FIXED_TO_FLOAT(thingxpos);
|
||||
p.y = FIXED_TO_FLOAT(thingypos) + md2->offset;
|
||||
p.x = FIXED_TO_FLOAT(interpx);
|
||||
p.y = FIXED_TO_FLOAT(interpy) + md2->offset;
|
||||
|
||||
if (flip)
|
||||
p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height);
|
||||
else
|
||||
p.z = FIXED_TO_FLOAT(thingzpos);
|
||||
p.z = FIXED_TO_FLOAT(interpz);
|
||||
|
||||
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
|
||||
sprdef = &((skin_t *)spr->mobj->skin)->sprites[spr->mobj->sprite2];
|
||||
|
|
@ -1631,7 +1644,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
}
|
||||
else
|
||||
{
|
||||
const fixed_t anglef = AngleFixed((R_PointToAngle(thingxpos, thingypos))-ANGLE_180);
|
||||
const fixed_t anglef = AngleFixed((R_PointToAngle(interpx, interpy))-ANGLE_180);
|
||||
p.angley = FIXED_TO_FLOAT(anglef);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,10 @@ UINT32 I_GetFreeMem(UINT32 *total);
|
|||
*/
|
||||
tic_t I_GetTime(void);
|
||||
|
||||
/** \brief Get the current time as a fraction of a tic since the last tic.
|
||||
*/
|
||||
fixed_t I_GetTimeFrac(void);
|
||||
|
||||
/** \brief Returns precise time value for performance measurement.
|
||||
*/
|
||||
precise_t I_GetPreciseTime(void);
|
||||
|
|
|
|||
12
src/info.c
12
src/info.c
|
|
@ -4068,13 +4068,13 @@ state_t states[NUMSTATES] =
|
|||
|
||||
{SPR_NULL, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMICON
|
||||
|
||||
{SPR_ICAP, FF_ADD|0, -1, {A_SpawnItemCapsuleParts}, 0, 0, S_NULL}, // S_ITEMCAPSULE
|
||||
{SPR_ICAP, FF_ADD|0, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE
|
||||
{SPR_ICAP, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_TOP_SIDE
|
||||
{SPR_ICAP, FF_VERTICALFLIP|FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM_SIDE_AIR
|
||||
{SPR_ICAP, FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM_SIDE_GROUND
|
||||
{SPR_ICAP, FF_FLOORSPRITE|3, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_TOP
|
||||
{SPR_ICAP, FF_FLOORSPRITE|4, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM
|
||||
{SPR_ICAP, FF_FLOORSPRITE|5, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_INSIDE
|
||||
//{SPR_ICAP, FF_FLOORSPRITE|3, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_TOP
|
||||
//{SPR_ICAP, FF_FLOORSPRITE|4, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM
|
||||
//{SPR_ICAP, FF_FLOORSPRITE|5, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_INSIDE
|
||||
|
||||
{SPR_SGNS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SIGNSPARK2}, // S_SIGNSPARK1
|
||||
{SPR_SGNS, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_SIGNSPARK3}, // S_SIGNSPARK2
|
||||
|
|
@ -9199,7 +9199,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NOTHINK|MF_DONTENCOREMAP, // flags
|
||||
MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -23094,7 +23094,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SLIDEME|MF_SPECIAL|MF_RUNSPAWNFUNC|MF_DONTENCOREMAP, // flags
|
||||
MF_SLIDEME|MF_SPECIAL|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -287,7 +287,6 @@ enum actionnum
|
|||
A_REAPERTHINKER,
|
||||
A_FLAMESHIELDPAPER,
|
||||
A_INVINCSPARKLEROTATE,
|
||||
A_SPAWNITEMCAPSULEPARTS,
|
||||
NUMACTIONS
|
||||
};
|
||||
|
||||
|
|
@ -558,7 +557,6 @@ void A_ReaperThinker();
|
|||
void A_MementosTPParticles();
|
||||
void A_FlameShieldPaper();
|
||||
void A_InvincSparkleRotate();
|
||||
void A_SpawnItemCapsuleParts();
|
||||
|
||||
extern boolean actionsoverridden[NUMACTIONS];
|
||||
|
||||
|
|
@ -4466,9 +4464,9 @@ typedef enum state
|
|||
S_ITEMCAPSULE_TOP_SIDE,
|
||||
S_ITEMCAPSULE_BOTTOM_SIDE_AIR,
|
||||
S_ITEMCAPSULE_BOTTOM_SIDE_GROUND,
|
||||
S_ITEMCAPSULE_TOP,
|
||||
S_ITEMCAPSULE_BOTTOM,
|
||||
S_ITEMCAPSULE_INSIDE,
|
||||
//S_ITEMCAPSULE_TOP,
|
||||
//S_ITEMCAPSULE_BOTTOM,
|
||||
//S_ITEMCAPSULE_INSIDE,
|
||||
|
||||
// Signpost sparkles
|
||||
S_SIGNSPARK1,
|
||||
|
|
|
|||
141
src/k_hud.c
141
src/k_hud.c
|
|
@ -761,9 +761,14 @@ void K_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du
|
|||
|
||||
if (lt_exitticker < length)
|
||||
{
|
||||
INT32 offset = screenwidth - ((lt_exitticker * screenwidth) / length);
|
||||
boolean slidefromright = false;
|
||||
|
||||
const INT32 offsetAmount = (screenwidth * FRACUNIT) / length;
|
||||
fixed_t offset = (screenwidth * FRACUNIT) - (lt_exitticker * offsetAmount);
|
||||
|
||||
offset += FixedMul(offsetAmount, renderdeltatics);
|
||||
offset /= FRACUNIT;
|
||||
|
||||
if (r_splitscreen > 1)
|
||||
{
|
||||
if (stplyr == &players[displayplayers[1]] || stplyr == &players[displayplayers[3]])
|
||||
|
|
@ -3041,6 +3046,7 @@ static void K_drawKartMinimap(void)
|
|||
SINT8 numlocalplayers = 0;
|
||||
INT32 hyu = hyudorotime;
|
||||
mobj_t *mobj, *next; // for SPB drawing (or any other item(s) we may wanna draw, I dunno!)
|
||||
fixed_t interpx, interpy;
|
||||
|
||||
// Draw the HUD only when playing in a level.
|
||||
// hu_stuff needs this, unlike st_stuff.
|
||||
|
|
@ -3135,7 +3141,17 @@ static void K_drawKartMinimap(void)
|
|||
}
|
||||
else
|
||||
colormap = NULL;
|
||||
K_drawKartMinimapIcon(g->mo->x, g->mo->y, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
|
||||
|
||||
interpx = g->mo->x;
|
||||
interpy = g->mo->y;
|
||||
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
interpx = g->mo->old_x + FixedMul(rendertimefrac, g->mo->x - g->mo->old_x);
|
||||
interpy = g->mo->old_y + FixedMul(rendertimefrac, g->mo->y - g->mo->old_y);
|
||||
}
|
||||
|
||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
|
||||
g = g->next;
|
||||
}
|
||||
|
||||
|
|
@ -3191,11 +3207,22 @@ static void K_drawKartMinimap(void)
|
|||
else
|
||||
colormap = NULL;
|
||||
|
||||
K_drawKartMinimapIcon(players[i].mo->x, players[i].mo->y, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
|
||||
interpx = players[i].mo->x;
|
||||
interpy = players[i].mo->y;
|
||||
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
interpx = players[i].mo->old_x + FixedMul(rendertimefrac, players[i].mo->x - players[i].mo->old_x);
|
||||
interpy = players[i].mo->old_y + FixedMul(rendertimefrac, players[i].mo->y - players[i].mo->old_y);
|
||||
}
|
||||
|
||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
|
||||
// Target reticule
|
||||
if ((gametype == GT_RACE && players[i].position == spbplace)
|
||||
|| (gametype == GT_BATTLE && K_IsPlayerWanted(&players[i])))
|
||||
K_drawKartMinimapIcon(players[i].mo->x, players[i].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
|
||||
|| (gametype == GT_BATTLE && K_IsPlayerWanted(&players[i])))
|
||||
{
|
||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3215,7 +3242,16 @@ static void K_drawKartMinimap(void)
|
|||
colormap = R_GetTranslationColormap(TC_RAINBOW, mobj->color, GTC_CACHE);
|
||||
}
|
||||
|
||||
K_drawKartMinimapIcon(mobj->x, mobj->y, x, y, splitflags, kp_spbminimap, colormap, AutomapPic);
|
||||
interpx = mobj->x;
|
||||
interpy = mobj->y;
|
||||
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
interpx = mobj->old_x + FixedMul(rendertimefrac, mobj->x - mobj->old_x);
|
||||
interpy = mobj->old_y + FixedMul(rendertimefrac, mobj->y - mobj->old_y);
|
||||
}
|
||||
|
||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_spbminimap, colormap, AutomapPic);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3243,12 +3279,23 @@ static void K_drawKartMinimap(void)
|
|||
else
|
||||
colormap = NULL;
|
||||
|
||||
K_drawKartMinimapIcon(players[localplayers[i]].mo->x, players[localplayers[i]].mo->y, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
|
||||
interpx = players[localplayers[i]].mo->x;
|
||||
interpy = players[localplayers[i]].mo->y;
|
||||
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
interpx = players[localplayers[i]].mo->old_x + FixedMul(rendertimefrac, players[localplayers[i]].mo->x - players[localplayers[i]].mo->old_x);
|
||||
interpy = players[localplayers[i]].mo->old_y + FixedMul(rendertimefrac, players[localplayers[i]].mo->y - players[localplayers[i]].mo->old_y);
|
||||
}
|
||||
|
||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
|
||||
|
||||
// Target reticule
|
||||
if ((gametype == GT_RACE && players[localplayers[i]].position == spbplace)
|
||||
|| (gametype == GT_BATTLE && K_IsPlayerWanted(&players[localplayers[i]])))
|
||||
K_drawKartMinimapIcon(players[localplayers[i]].mo->x, players[localplayers[i]].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
|
||||
|| (gametype == GT_BATTLE && K_IsPlayerWanted(&players[localplayers[i]])))
|
||||
{
|
||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3508,7 +3555,7 @@ static void K_drawKartFinish(void)
|
|||
|
||||
//else -- 1/2p, scrolling FINISH
|
||||
{
|
||||
INT32 x, xval;
|
||||
INT32 x, xval, ox, interpx;
|
||||
|
||||
if (r_splitscreen) // wide splitscreen
|
||||
pnum += 4;
|
||||
|
|
@ -3516,11 +3563,14 @@ static void K_drawKartFinish(void)
|
|||
x = ((vid.width<<FRACBITS)/vid.dupx);
|
||||
xval = (SHORT(kp_racefinish[pnum]->width)<<FRACBITS);
|
||||
x = ((TICRATE - stplyr->karthud[khud_cardanimation])*(xval > x ? xval : x))/TICRATE;
|
||||
ox = ((TICRATE - (stplyr->karthud[khud_cardanimation] - 1))*(xval > x ? xval : x))/TICRATE;
|
||||
|
||||
interpx = ox + FixedMul(rendertimefrac, x - ox);
|
||||
|
||||
if (r_splitscreen && stplyr == &players[displayplayers[1]])
|
||||
x = -x;
|
||||
interpx = -interpx;
|
||||
|
||||
V_DrawFixedPatch(x + (STCD_X<<FRACBITS) - (xval>>1),
|
||||
V_DrawFixedPatch(interpx + (STCD_X<<FRACBITS) - (xval>>1),
|
||||
(STCD_Y<<FRACBITS) - (SHORT(kp_racefinish[pnum]->height)<<(FRACBITS-1)),
|
||||
FRACUNIT,
|
||||
splitflags, kp_racefinish[pnum], NULL);
|
||||
|
|
@ -3909,33 +3959,63 @@ static void K_drawChallengerScreen(void)
|
|||
static void K_drawLapStartAnim(void)
|
||||
{
|
||||
// This is an EVEN MORE insanely complicated animation.
|
||||
const UINT8 progress = 80-stplyr->karthud[khud_lapanimation];
|
||||
const UINT8 t = stplyr->karthud[khud_lapanimation];
|
||||
const UINT8 progress = 80 - t;
|
||||
|
||||
const UINT8 tOld = t - 1;
|
||||
const UINT8 progressOld = 80 - tOld;
|
||||
|
||||
const tic_t leveltimeOld = leveltime - 1;
|
||||
|
||||
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, GTC_CACHE);
|
||||
|
||||
V_DrawFixedPatch((BASEVIDWIDTH/2 + (32*max(0, stplyr->karthud[khud_lapanimation]-76)))*FRACUNIT,
|
||||
(48 - (32*max(0, progress-76)))*FRACUNIT,
|
||||
fixed_t interpx, interpy, newval, oldval;
|
||||
|
||||
newval = (BASEVIDWIDTH/2 + (32 * max(0, t - 76))) * FRACUNIT;
|
||||
oldval = (BASEVIDWIDTH/2 + (32 * max(0, tOld - 76))) * FRACUNIT;
|
||||
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
|
||||
newval = (48 - (32 * max(0, progress - 76))) * FRACUNIT;
|
||||
oldval = (48 - (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||
interpy = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, interpy,
|
||||
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
|
||||
(modeattacking ? kp_lapanim_emblem[1] : kp_lapanim_emblem[0]), colormap);
|
||||
|
||||
if (stplyr->karthud[khud_laphand] >= 1 && stplyr->karthud[khud_laphand] <= 3)
|
||||
{
|
||||
V_DrawFixedPatch((BASEVIDWIDTH/2 + (32*max(0, stplyr->karthud[khud_lapanimation]-76)))*FRACUNIT,
|
||||
(48 - (32*max(0, progress-76))
|
||||
+ 4 - abs((signed)((leveltime % 8) - 4)))*FRACUNIT,
|
||||
newval = (4 - abs((signed)((leveltime % 8) - 4))) * FRACUNIT;
|
||||
oldval = (4 - abs((signed)((leveltimeOld % 8) - 4))) * FRACUNIT;
|
||||
interpy += oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, interpy,
|
||||
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
|
||||
kp_lapanim_hand[stplyr->karthud[khud_laphand]-1], NULL);
|
||||
}
|
||||
|
||||
if (stplyr->laps == (UINT8)(cv_numlaps.value))
|
||||
{
|
||||
V_DrawFixedPatch((62 - (32*max(0, progress-76)))*FRACUNIT, // 27
|
||||
newval = (62 - (32 * max(0, progress - 76))) * FRACUNIT;
|
||||
oldval = (62 - (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, // 27
|
||||
30*FRACUNIT, // 24
|
||||
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
|
||||
kp_lapanim_final[min(progress/2, 10)], NULL);
|
||||
|
||||
if (progress/2-12 >= 0)
|
||||
{
|
||||
V_DrawFixedPatch((188 + (32*max(0, progress-76)))*FRACUNIT, // 194
|
||||
newval = (188 + (32 * max(0, progress - 76))) * FRACUNIT;
|
||||
oldval = (188 + (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, // 194
|
||||
30*FRACUNIT, // 24
|
||||
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
|
||||
kp_lapanim_lap[min(progress/2-12, 6)], NULL);
|
||||
|
|
@ -3943,21 +4023,36 @@ static void K_drawLapStartAnim(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
V_DrawFixedPatch((82 - (32*max(0, progress-76)))*FRACUNIT, // 61
|
||||
newval = (82 - (32 * max(0, progress - 76))) * FRACUNIT;
|
||||
oldval = (82 - (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, // 61
|
||||
30*FRACUNIT, // 24
|
||||
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
|
||||
kp_lapanim_lap[min(progress/2, 6)], NULL);
|
||||
|
||||
if (progress/2-8 >= 0)
|
||||
{
|
||||
V_DrawFixedPatch((188 + (32*max(0, progress-76)))*FRACUNIT, // 194
|
||||
newval = (188 + (32 * max(0, progress - 76))) * FRACUNIT;
|
||||
oldval = (188 + (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, // 194
|
||||
30*FRACUNIT, // 24
|
||||
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
|
||||
kp_lapanim_number[(((UINT32)stplyr->laps) / 10)][min(progress/2-8, 2)], NULL);
|
||||
|
||||
if (progress/2-10 >= 0)
|
||||
{
|
||||
V_DrawFixedPatch((208 + (32*max(0, progress-76)))*FRACUNIT, // 221
|
||||
newval = (208 + (32 * max(0, progress - 76))) * FRACUNIT;
|
||||
oldval = (208 + (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, // 221
|
||||
30*FRACUNIT, // 24
|
||||
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
|
||||
kp_lapanim_number[(((UINT32)stplyr->laps) % 10)][min(progress/2-10, 2)], NULL);
|
||||
|
|
|
|||
142
src/k_kart.c
142
src/k_kart.c
|
|
@ -52,7 +52,7 @@ void K_TimerReset(void)
|
|||
void K_TimerInit(void)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT8 numPlayers = 0;
|
||||
UINT8 numPlayers = 0;//, numspec = 0;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
|
@ -63,6 +63,7 @@ void K_TimerInit(void)
|
|||
|
||||
if (players[i].spectator == true)
|
||||
{
|
||||
//numspec++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -98,6 +99,7 @@ void K_TimerInit(void)
|
|||
|
||||
// NOW you can try to spawn in the Battle capsules, if there's not enough players for a match
|
||||
K_SpawnBattleCapsules();
|
||||
//CONS_Printf("numbulbs set to %d (%d players, %d spectators) on tic %d\n", numbulbs, numPlayers, numspec, leveltime);
|
||||
}
|
||||
|
||||
UINT32 K_GetPlayerDontDrawFlag(player_t *player)
|
||||
|
|
@ -2077,6 +2079,18 @@ void K_SpawnInvincibilitySpeedLines(mobj_t *mo)
|
|||
fast->destscale = 6*((mo->player->invincibilitytimer/TICRATE)*FRACUNIT)/8;
|
||||
}
|
||||
|
||||
void K_SpawnBumpEffect(mobj_t *mo)
|
||||
{
|
||||
mobj_t *fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP);
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
fx->eflags |= MFE_VERTICALFLIP;
|
||||
else
|
||||
fx->eflags &= ~MFE_VERTICALFLIP;
|
||||
fx->scale = mo->scale;
|
||||
|
||||
S_StartSound(mo, sfx_s3k49);
|
||||
}
|
||||
|
||||
static SINT8 K_GlanceAtPlayers(player_t *glancePlayer)
|
||||
{
|
||||
const fixed_t maxdistance = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
|
||||
|
|
@ -2673,6 +2687,19 @@ boolean K_SlopeResistance(player_t *player)
|
|||
return false;
|
||||
}
|
||||
|
||||
boolean K_TripwirePass(player_t *player)
|
||||
{
|
||||
if (
|
||||
player->invincibilitytimer ||
|
||||
player->sneakertimer ||
|
||||
player->growshrinktimer > 0 ||
|
||||
player->flamedash ||
|
||||
player->speed > 2 * K_GetKartSpeed(player, false)
|
||||
)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static fixed_t K_FlameShieldDashVar(INT32 val)
|
||||
{
|
||||
// 1 second = 75% + 50% top speed
|
||||
|
|
@ -3197,10 +3224,18 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source)
|
|||
|
||||
player->tumbleBounces = 1;
|
||||
|
||||
player->mo->momx = 2 * player->mo->momx / 3;
|
||||
player->mo->momy = 2 * player->mo->momy / 3;
|
||||
if (player->tripWireState == TRIP_PASSED)
|
||||
{
|
||||
player->tumbleHeight = 50;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->mo->momx = 2 * player->mo->momx / 3;
|
||||
player->mo->momy = 2 * player->mo->momy / 3;
|
||||
|
||||
player->tumbleHeight = 30;
|
||||
}
|
||||
|
||||
player->tumbleHeight = 30;
|
||||
player->pflags &= ~PF_TUMBLESOUND;
|
||||
|
||||
if (inflictor && !P_MobjWasRemoved(inflictor))
|
||||
|
|
@ -3300,6 +3335,23 @@ static void K_HandleTumbleSound(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
void K_ApplyTripWire(player_t *player, tripwirestate_t state)
|
||||
{
|
||||
if (state == TRIP_PASSED)
|
||||
S_StartSound(player->mo, sfx_ssa015);
|
||||
else if (state == TRIP_BLOCKED)
|
||||
S_StartSound(player->mo, sfx_kc40);
|
||||
|
||||
player->tripWireState = state;
|
||||
K_AddHitLag(player->mo, 10, false);
|
||||
|
||||
if (state == TRIP_PASSED && player->spinouttimer &&
|
||||
player->speed > 2* K_GetKartSpeed(player, false))
|
||||
{
|
||||
K_TumblePlayer(player, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A bit of a hack, we just throw the player up higher here and extend their spinout timer
|
||||
{
|
||||
INT32 ringburst = 10;
|
||||
|
|
@ -3716,7 +3768,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
|
|||
{
|
||||
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
|
||||
// This should set it for FOFs
|
||||
P_TeleportMove(th, th->x, th->y, th->z);
|
||||
P_SetOrigin(th, th->x, th->y, th->z);
|
||||
// spawn on the ground if the player is on the ground
|
||||
if (P_MobjFlip(source) < 0)
|
||||
{
|
||||
|
|
@ -4470,6 +4522,42 @@ void K_DriftDustHandling(mobj_t *spawner)
|
|||
}
|
||||
}
|
||||
|
||||
void K_Squish(mobj_t *mo)
|
||||
{
|
||||
const fixed_t maxstretch = 4*FRACUNIT;
|
||||
const fixed_t factor = 3 * mo->height / 2;
|
||||
const fixed_t threshold = factor / 6;
|
||||
|
||||
const fixed_t old3dspeed = abs(mo->lastmomz);
|
||||
const fixed_t new3dspeed = abs(mo->momz);
|
||||
|
||||
const fixed_t delta = abs(old3dspeed - new3dspeed);
|
||||
|
||||
if (delta > threshold)
|
||||
{
|
||||
mo->spritexscale =
|
||||
FRACUNIT + FixedDiv(delta, factor);
|
||||
|
||||
if (mo->spritexscale > maxstretch)
|
||||
mo->spritexscale = maxstretch;
|
||||
|
||||
if (abs(new3dspeed) > abs(old3dspeed))
|
||||
{
|
||||
mo->spritexscale =
|
||||
FixedDiv(FRACUNIT, mo->spritexscale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mo->spritexscale -=
|
||||
(mo->spritexscale - FRACUNIT)
|
||||
/ (mo->spritexscale < FRACUNIT ? 8 : 2);
|
||||
}
|
||||
|
||||
mo->spriteyscale =
|
||||
FixedDiv(FRACUNIT, mo->spritexscale);
|
||||
}
|
||||
|
||||
static mobj_t *K_FindLastTrailMobj(player_t *player)
|
||||
{
|
||||
mobj_t *trail;
|
||||
|
|
@ -4679,7 +4767,7 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
|
|||
{
|
||||
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
|
||||
// This should set it for FOFs
|
||||
P_TeleportMove(mo, mo->x, mo->y, mo->z); // however, THIS can fuck up your day. just absolutely ruin you.
|
||||
P_SetOrigin(mo, mo->x, mo->y, mo->z); // however, THIS can fuck up your day. just absolutely ruin you.
|
||||
if (P_MobjWasRemoved(mo))
|
||||
return NULL;
|
||||
|
||||
|
|
@ -4885,8 +4973,7 @@ static void K_DoHyudoroSteal(player_t *player)
|
|||
// Has an item
|
||||
&& (players[i].itemtype
|
||||
&& players[i].itemamount
|
||||
&& !(players[i].pflags & PF_ITEMOUT)
|
||||
&& !players[i].karthud[khud_itemblink]))
|
||||
&& !(players[i].pflags & PF_ITEMOUT)))
|
||||
{
|
||||
playerswappable[numplayers] = i;
|
||||
numplayers++;
|
||||
|
|
@ -5309,7 +5396,7 @@ void K_DropHnextList(player_t *player, boolean keepshields)
|
|||
{
|
||||
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
|
||||
// This should set it for FOFs
|
||||
//P_TeleportMove(dropwork, dropwork->x, dropwork->y, dropwork->z); -- handled better by above floorz/ceilingz passing
|
||||
//P_SetOrigin(dropwork, dropwork->x, dropwork->y, dropwork->z); -- handled better by above floorz/ceilingz passing
|
||||
|
||||
if (flip == 1)
|
||||
{
|
||||
|
|
@ -5835,7 +5922,7 @@ static void K_MoveHeldObjects(player_t *player)
|
|||
z = player->mo->z + player->mo->height - cur->height;
|
||||
|
||||
cur->flags |= MF_NOCLIPTHING; // temporarily make them noclip other objects so they can't hit anyone while in the player
|
||||
P_TeleportMove(cur, player->mo->x, player->mo->y, z);
|
||||
P_MoveOrigin(cur, player->mo->x, player->mo->y, z);
|
||||
cur->momx = FixedMul(FINECOSINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1);
|
||||
cur->momy = FixedMul(FINESINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1);
|
||||
cur->flags &= ~MF_NOCLIPTHING;
|
||||
|
|
@ -5948,7 +6035,7 @@ static void K_MoveHeldObjects(player_t *player)
|
|||
P_SetObjectMomZ(cur, FixedMul(targz - cur->z, 7*FRACUNIT/8) - gravity, false);
|
||||
|
||||
if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT)
|
||||
P_TeleportMove(cur, targx, targy, cur->z);
|
||||
P_MoveOrigin(cur, targx, targy, cur->z);
|
||||
|
||||
if (P_IsObjectOnGround(cur))
|
||||
{
|
||||
|
|
@ -6038,12 +6125,12 @@ static void K_MoveHeldObjects(player_t *player)
|
|||
diffy = targy - cur->y;
|
||||
diffz = targz - cur->z;
|
||||
|
||||
P_TeleportMove(cur->tracer, cur->tracer->x + diffx + P_ReturnThrustX(cur, cur->angle + angoffset, 6*cur->scale),
|
||||
P_MoveOrigin(cur->tracer, cur->tracer->x + diffx + P_ReturnThrustX(cur, cur->angle + angoffset, 6*cur->scale),
|
||||
cur->tracer->y + diffy + P_ReturnThrustY(cur, cur->angle + angoffset, 6*cur->scale), cur->tracer->z + diffz);
|
||||
P_SetScale(cur->tracer, (cur->tracer->destscale = 3*cur->scale/4));
|
||||
}
|
||||
|
||||
P_TeleportMove(cur, targx, targy, targz);
|
||||
P_MoveOrigin(cur, targx, targy, targz);
|
||||
K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks.
|
||||
|
||||
cur->roll = player->mo->roll;
|
||||
|
|
@ -6355,6 +6442,12 @@ void K_KartPlayerHUDUpdate(player_t *player)
|
|||
else if (player->karthud[khud_fault] > 0 && player->karthud[khud_fault] < 2*TICRATE)
|
||||
player->karthud[khud_fault]++;
|
||||
|
||||
if (player->karthud[khud_itemblink] && player->karthud[khud_itemblink]-- <= 0)
|
||||
{
|
||||
player->karthud[khud_itemblinkmode] = 0;
|
||||
player->karthud[khud_itemblink] = 0;
|
||||
}
|
||||
|
||||
if (gametype == GT_RACE)
|
||||
{
|
||||
// 0 is the fast spin animation, set at 30 tics of ring boost or higher!
|
||||
|
|
@ -6873,13 +6966,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
K_HandleTumbleBounce(player);
|
||||
}
|
||||
|
||||
// This doesn't go in HUD update because it has potential gameplay ramifications
|
||||
if (player->karthud[khud_itemblink] && player->karthud[khud_itemblink]-- <= 0)
|
||||
{
|
||||
player->karthud[khud_itemblinkmode] = 0;
|
||||
player->karthud[khud_itemblink] = 0;
|
||||
}
|
||||
|
||||
K_KartPlayerHUDUpdate(player);
|
||||
|
||||
if (battleovertime.enabled && !(player->pflags & PF_ELIMINATED) && player->bumpers <= 0 && player->karmadelay <= 0)
|
||||
|
|
@ -6983,6 +7069,16 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
// Handle invincibility sfx
|
||||
K_UpdateInvincibilitySounds(player); // Also thanks, VAda!
|
||||
|
||||
if (player->tripWireState != TRIP_NONE)
|
||||
{
|
||||
if (player->tripWireState == TRIP_PASSED)
|
||||
S_StartSound(player->mo, sfx_cdfm63);
|
||||
else if (player->tripWireState == TRIP_BLOCKED)
|
||||
S_StartSound(player->mo, sfx_kc4c);
|
||||
|
||||
player->tripWireState = TRIP_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
void K_KartPlayerAfterThink(player_t *player)
|
||||
|
|
@ -8432,7 +8528,12 @@ static void K_trickPanelTimingVisual(player_t *player, fixed_t momz)
|
|||
flame->frame = i|FF_FULLBRIGHT;
|
||||
|
||||
if (player->trickpanel <= 1 && !player->tumbleBounces)
|
||||
{
|
||||
flame->tics = 2;
|
||||
flame->momx = player->mo->momx;
|
||||
flame->momy = player->mo->momy;
|
||||
flame->momz = player->mo->momz;
|
||||
}
|
||||
else
|
||||
{
|
||||
flame->tics = TICRATE;
|
||||
|
|
@ -9387,6 +9488,7 @@ void K_CheckSpectateStatus(void)
|
|||
{
|
||||
if (cv_ingamecap.value && numingame+i >= cv_ingamecap.value) // Hit the in-game player cap while adding people?
|
||||
break;
|
||||
//CONS_Printf("player %s is joining on tic %d\n", player_names[respawnlist[i]], leveltime);
|
||||
P_SpectatorJoinGame(&players[respawnlist[i]]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ void K_SpawnDriftBoostClip(player_t *player);
|
|||
void K_SpawnDriftBoostClipSpark(mobj_t *clip);
|
||||
void K_SpawnNormalSpeedLines(player_t *player);
|
||||
void K_SpawnInvincibilitySpeedLines(mobj_t *mo);
|
||||
void K_SpawnBumpEffect(mobj_t *mo);
|
||||
void K_KartMoveAnimation(player_t *player);
|
||||
void K_KartPlayerHUDUpdate(player_t *player);
|
||||
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
|
||||
|
|
@ -76,6 +77,7 @@ void K_SpawnSparkleTrail(mobj_t *mo);
|
|||
void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad);
|
||||
void K_SpawnDraftDust(mobj_t *mo);
|
||||
void K_DriftDustHandling(mobj_t *spawner);
|
||||
void K_Squish(mobj_t *mo);
|
||||
mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, INT32 altthrow);
|
||||
void K_PuntMine(mobj_t *mine, mobj_t *punter);
|
||||
void K_DoSneaker(player_t *player, INT32 type);
|
||||
|
|
@ -105,6 +107,8 @@ void K_StripOther(player_t *player);
|
|||
void K_MomentumToFacing(player_t *player);
|
||||
boolean K_ApplyOffroad(player_t *player);
|
||||
boolean K_SlopeResistance(player_t *player);
|
||||
boolean K_TripwirePass(player_t *player);
|
||||
void K_ApplyTripWire(player_t *player, tripwirestate_t state);
|
||||
INT16 K_GetSpindashChargeTime(player_t *player);
|
||||
fixed_t K_GetSpindashChargeSpeed(player_t *player);
|
||||
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ SINT8 K_UsingPowerLevels(void)
|
|||
{
|
||||
SINT8 pt = PWRLV_DISABLED;
|
||||
|
||||
if (!cv_kartusepwrlv.value || !netgame || grandprixinfo.gp == true)
|
||||
if (!cv_kartusepwrlv.value || !(netgame || (demo.playback && demo.netgame)) || grandprixinfo.gp == true)
|
||||
{
|
||||
return PWRLV_DISABLED;
|
||||
}
|
||||
|
|
@ -346,7 +346,7 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss)
|
|||
|
||||
clientpowerlevels[playernum][powertype] += inc;
|
||||
|
||||
if (playernum == consoleplayer)
|
||||
if (!demo.playback && playernum == consoleplayer)
|
||||
{
|
||||
vspowerlevel[powertype] = clientpowerlevels[playernum][powertype];
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
|
|
|
|||
|
|
@ -1415,7 +1415,42 @@ static int lib_pTeleportMove(lua_State *L)
|
|||
INLEVEL
|
||||
if (!thing)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
lua_pushboolean(L, P_TeleportMove(thing, x, y, z));
|
||||
LUA_Deprecated(L, "P_TeleportMove", "P_SetOrigin or P_MoveOrigin");
|
||||
lua_pushboolean(L, P_SetOrigin(thing, x, y, z));
|
||||
LUA_PushUserdata(L, tmthing, META_MOBJ);
|
||||
P_SetTarget(&tmthing, ptmthing);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int lib_pSetOrigin(lua_State *L)
|
||||
{
|
||||
mobj_t *ptmthing = tmthing;
|
||||
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
fixed_t x = luaL_checkfixed(L, 2);
|
||||
fixed_t y = luaL_checkfixed(L, 3);
|
||||
fixed_t z = luaL_checkfixed(L, 4);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!thing)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
lua_pushboolean(L, P_SetOrigin(thing, x, y, z));
|
||||
LUA_PushUserdata(L, tmthing, META_MOBJ);
|
||||
P_SetTarget(&tmthing, ptmthing);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int lib_pMoveOrigin(lua_State *L)
|
||||
{
|
||||
mobj_t *ptmthing = tmthing;
|
||||
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
fixed_t x = luaL_checkfixed(L, 2);
|
||||
fixed_t y = luaL_checkfixed(L, 3);
|
||||
fixed_t z = luaL_checkfixed(L, 4);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!thing)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
lua_pushboolean(L, P_MoveOrigin(thing, x, y, z));
|
||||
LUA_PushUserdata(L, tmthing, META_MOBJ);
|
||||
P_SetTarget(&tmthing, ptmthing);
|
||||
return 2;
|
||||
|
|
@ -3835,6 +3870,8 @@ static luaL_Reg lib[] = {
|
|||
{"P_TryMove",lib_pTryMove},
|
||||
{"P_Move",lib_pMove},
|
||||
{"P_TeleportMove",lib_pTeleportMove},
|
||||
{"P_SetOrigin",lib_pSetOrigin},
|
||||
{"P_MoveOrigin",lib_pMoveOrigin},
|
||||
{"P_SlideMove",lib_pSlideMove},
|
||||
{"P_BounceMove",lib_pBounceMove},
|
||||
{"P_CheckSight", lib_pCheckSight},
|
||||
|
|
|
|||
|
|
@ -477,7 +477,7 @@ static int mobj_get(lua_State *L)
|
|||
}
|
||||
|
||||
#define NOSET luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly.", mobj_opt[field])
|
||||
#define NOSETPOS luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly. Use " LUA_QL("P_Move") ", " LUA_QL("P_TryMove") ", or " LUA_QL("P_TeleportMove") " instead.", mobj_opt[field])
|
||||
#define NOSETPOS luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly. Use " LUA_QL("P_Move") ", " LUA_QL("P_TryMove") ", or " LUA_QL("P_SetOrigin") ", or " LUA_QL("P_MoveOrigin") " instead.", mobj_opt[field])
|
||||
static int mobj_set(lua_State *L)
|
||||
{
|
||||
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ void Command_RTeleport_f(void)
|
|||
CONS_Printf(M_GetText("Teleporting by %d, %d, %d...\n"), intx, inty, FixedInt((intz-p->mo->z)));
|
||||
|
||||
P_MapStart();
|
||||
if (!P_TeleportMove(p->mo, p->mo->x+intx*FRACUNIT, p->mo->y+inty*FRACUNIT, intz))
|
||||
if (!P_SetOrigin(p->mo, p->mo->x+intx*FRACUNIT, p->mo->y+inty*FRACUNIT, intz))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Unable to teleport to that spot!\n"));
|
||||
else
|
||||
S_StartSound(p->mo, sfx_mixup);
|
||||
|
|
@ -641,7 +641,7 @@ void Command_Teleport_f(void)
|
|||
}
|
||||
|
||||
P_MapStart();
|
||||
if (!P_TeleportMove(p->mo, intx, inty, intz))
|
||||
if (!P_SetOrigin(p->mo, intx, inty, intz))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Unable to teleport to that spot!\n"));
|
||||
else
|
||||
S_StartSound(p->mo, sfx_mixup);
|
||||
|
|
@ -1039,7 +1039,7 @@ void OP_ObjectplaceMovement(player_t *player)
|
|||
if (cmd->forwardmove != 0)
|
||||
{
|
||||
P_Thrust(player->mo, player->mo->angle, (cmd->forwardmove*player->mo->scale/MAXPLMOVE)*cv_speed.value);
|
||||
P_TeleportMove(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z);
|
||||
P_MoveOrigin(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z);
|
||||
player->mo->momx = player->mo->momy = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
223
src/p_enemy.c
223
src/p_enemy.c
|
|
@ -321,7 +321,6 @@ void A_ReaperThinker(mobj_t *actor);
|
|||
void A_MementosTPParticles(mobj_t *actor);
|
||||
void A_FlameShieldPaper(mobj_t *actor);
|
||||
void A_InvincSparkleRotate(mobj_t *actor);
|
||||
void A_SpawnItemCapsuleParts(mobj_t *actor);
|
||||
|
||||
//for p_enemy.c
|
||||
|
||||
|
|
@ -1145,7 +1144,7 @@ void A_FaceStabHurl(mobj_t *actor)
|
|||
hwork->destscale = FixedSqrt(step*basesize);
|
||||
P_SetScale(hwork, hwork->destscale);
|
||||
hwork->fuse = 2;
|
||||
P_TeleportMove(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<<FRACBITS)));
|
||||
P_MoveOrigin(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<<FRACBITS)));
|
||||
step -= NUMGRADS;
|
||||
}
|
||||
|
||||
|
|
@ -1905,7 +1904,7 @@ void A_CrushclawAim(mobj_t *actor)
|
|||
#undef anglimit
|
||||
#undef angfactor
|
||||
|
||||
P_TeleportMove(actor,
|
||||
P_MoveOrigin(actor,
|
||||
crab->x + P_ReturnThrustX(actor, actor->angle, locvar1*crab->scale),
|
||||
crab->y + P_ReturnThrustY(actor, actor->angle, locvar1*crab->scale),
|
||||
crab->z + locvar2*crab->scale);
|
||||
|
|
@ -2043,7 +2042,7 @@ void A_CrushclawLaunch(mobj_t *actor)
|
|||
fixed_t idx = dx, idy = dy, idz = dz;
|
||||
while (chain)
|
||||
{
|
||||
P_TeleportMove(chain, actor->target->x + idx, actor->target->y + idy, actor->target->z + idz);
|
||||
P_MoveOrigin(chain, actor->target->x + idx, actor->target->y + idy, actor->target->z + idz);
|
||||
chain->movefactor = chain->z;
|
||||
idx += dx;
|
||||
idy += dy;
|
||||
|
|
@ -4023,7 +4022,7 @@ void A_AttractChase(mobj_t *actor)
|
|||
//P_SetScale(actor, (actor->destscale = actor->target->scale));
|
||||
actor->z = actor->target->z;
|
||||
K_MatchGenericExtraFlags(actor, actor->target);
|
||||
P_TeleportMove(actor, actor->target->x, actor->target->y,
|
||||
P_MoveOrigin(actor, actor->target->x, actor->target->y,
|
||||
actor->z +
|
||||
( actor->target->height + offz )* P_MobjFlip(actor));
|
||||
actor->extravalue1++;
|
||||
|
|
@ -4052,7 +4051,7 @@ void A_AttractChase(mobj_t *actor)
|
|||
P_SetScale(actor, (actor->destscale = actor->target->scale - ((actor->target->scale/14) * actor->extravalue1)));
|
||||
actor->z = actor->target->z;
|
||||
K_MatchGenericExtraFlags(actor, actor->target);
|
||||
P_TeleportMove(actor,
|
||||
P_MoveOrigin(actor,
|
||||
actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)),
|
||||
actor->target->y + FixedMul(dist, FINESINE(actor->angle >> ANGLETOFINESHIFT)),
|
||||
actor->z + actor->target->scale * 24 * P_MobjFlip(actor));
|
||||
|
|
@ -9911,7 +9910,7 @@ void A_VileAttack(mobj_t *actor)
|
|||
// move the fire between the vile and the player
|
||||
//fire->x = actor->target->x - FixedMul (24*FRACUNIT, finecosine[an]);
|
||||
//fire->y = actor->target->y - FixedMul (24*FRACUNIT, finesine[an]);
|
||||
P_TeleportMove(fire,
|
||||
P_MoveOrigin(fire,
|
||||
actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
fire->z);
|
||||
|
|
@ -9956,7 +9955,7 @@ void A_VileAttack(mobj_t *actor)
|
|||
// move the fire between the vile and the player
|
||||
//fire->x = actor->target->x - FixedMul (24*FRACUNIT, finecosine[an]);
|
||||
//fire->y = actor->target->y - FixedMul (24*FRACUNIT, finesine[an]);
|
||||
P_TeleportMove(fire,
|
||||
P_MoveOrigin(fire,
|
||||
actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
fire->z);
|
||||
|
|
@ -10629,13 +10628,13 @@ void A_FlickyCenter(mobj_t *actor)
|
|||
if (actor->target && P_AproxDistance(actor->target->x - originx, actor->target->y - originy) < actor->extravalue1)
|
||||
{
|
||||
actor->extravalue2 = 1;
|
||||
P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z);
|
||||
P_SetOrigin(actor, actor->target->x, actor->target->y, actor->target->z);
|
||||
tmthing = NULL;
|
||||
}
|
||||
else if(actor->extravalue2)
|
||||
{
|
||||
actor->extravalue2 = 0;
|
||||
P_TeleportMove(actor, originx, originy, originz);
|
||||
P_SetOrigin(actor, originx, originy, originz);
|
||||
tmthing = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -11172,7 +11171,7 @@ void A_LightBeamReset(mobj_t *actor)
|
|||
actor->momy = (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/128;
|
||||
actor->momz = (P_SignedRandom()*FRACUNIT)/128;
|
||||
|
||||
P_TeleportMove(actor,
|
||||
P_SetOrigin(actor,
|
||||
actor->spawnpoint->x*FRACUNIT - (P_SignedRandom()*FINESINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2,
|
||||
actor->spawnpoint->y*FRACUNIT + (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2,
|
||||
actor->spawnpoint->z*FRACUNIT + (P_SignedRandom()*FRACUNIT)/2);
|
||||
|
|
@ -11757,7 +11756,7 @@ void A_DoNPCSkid(mobj_t *actor)
|
|||
actor->momy = (2*actor->momy)/3;
|
||||
}
|
||||
|
||||
P_TeleportMove(actor, x, y, z);
|
||||
P_MoveOrigin(actor, x, y, z);
|
||||
|
||||
// Spawn a particle every 3 tics.
|
||||
if (!(leveltime % 3))
|
||||
|
|
@ -12098,7 +12097,7 @@ void A_Boss5MakeJunk(mobj_t *actor)
|
|||
if (locvar1 > 0)
|
||||
P_SetMobjState(broked, locvar1);
|
||||
if (!P_MobjWasRemoved(broked))
|
||||
P_TeleportMove(broked, broked->x + broked->momx, broked->y + broked->momy, broked->z);
|
||||
P_MoveOrigin(broked, broked->x + broked->momx, broked->y + broked->momy, broked->z);
|
||||
ang += ANGLE_45;
|
||||
}
|
||||
|
||||
|
|
@ -13161,7 +13160,7 @@ void A_DragonWing(mobj_t *actor)
|
|||
actor->angle = target->angle + actor->movedir;
|
||||
x = target->x + P_ReturnThrustX(actor, actor->angle, -target->radius);
|
||||
y = target->y + P_ReturnThrustY(actor, actor->angle, -target->radius);
|
||||
P_TeleportMove(actor, x, y, target->z);
|
||||
P_MoveOrigin(actor, x, y, target->z);
|
||||
}
|
||||
|
||||
// Function: A_DragonSegment
|
||||
|
|
@ -13202,7 +13201,7 @@ void A_DragonSegment(mobj_t *actor)
|
|||
zdist = P_ReturnThrustY(target, zangle, radius);
|
||||
|
||||
actor->angle = hangle;
|
||||
P_TeleportMove(actor, target->x + xdist, target->y + ydist, target->z + zdist);
|
||||
P_MoveOrigin(actor, target->x + xdist, target->y + ydist, target->z + zdist);
|
||||
}
|
||||
|
||||
// Function: A_ChangeHeight
|
||||
|
|
@ -14164,10 +14163,10 @@ void A_LightningFollowPlayer(mobj_t *actor)
|
|||
{
|
||||
sx = actor->target->x + FixedMul((actor->target->scale*actor->extravalue1), FINECOSINE((actor->angle)>>ANGLETOFINESHIFT));
|
||||
sy = actor->target->y + FixedMul((actor->target->scale*actor->extravalue1), FINESINE((actor->angle)>>ANGLETOFINESHIFT));
|
||||
P_TeleportMove(actor, sx, sy, actor->target->z);
|
||||
P_MoveOrigin(actor, sx, sy, actor->target->z);
|
||||
}
|
||||
else // else just teleport to player directly
|
||||
P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z);
|
||||
P_MoveOrigin(actor, actor->target->x, actor->target->y, actor->target->z);
|
||||
|
||||
K_MatchGenericExtraFlags(actor, actor->target); // copy our target for graviflip
|
||||
actor->momx = actor->target->momx;
|
||||
|
|
@ -14644,7 +14643,7 @@ void A_InvincSparkleRotate(mobj_t *actor)
|
|||
sx = actor->target->x + FixedMul((actor->movefactor), FINECOSINE((actor->angle)>>ANGLETOFINESHIFT));
|
||||
sy = actor->target->y + FixedMul((actor->movefactor), FINESINE((actor->angle)>>ANGLETOFINESHIFT));
|
||||
sz = actor->target->z + (actor->extravalue1) + FixedMul((actor->cvmem), FINECOSINE((leveltime*ANG1*10 + actor->angle)>>ANGLETOFINESHIFT));
|
||||
P_TeleportMove(actor, sx, sy, sz);
|
||||
P_MoveOrigin(actor, sx, sy, sz);
|
||||
|
||||
actor->momx = actor->target->momx;
|
||||
actor->momy = actor->target->momy;
|
||||
|
|
@ -14652,191 +14651,3 @@ void A_InvincSparkleRotate(mobj_t *actor)
|
|||
|
||||
actor->angle += ANG1*10*(actor->extravalue2); // Arbitrary value, change this if you want, I suppose.
|
||||
}
|
||||
|
||||
void P_RefreshItemCapsuleParts(mobj_t *mobj)
|
||||
{
|
||||
UINT8 numNumbers = 0;
|
||||
INT32 count = 0;
|
||||
INT32 itemType = mobj->threshold;
|
||||
mobj_t *part;
|
||||
skincolornum_t color;
|
||||
UINT32 newRenderFlags = 0;
|
||||
boolean colorized;
|
||||
|
||||
if (itemType < 1 || itemType >= NUMKARTITEMS)
|
||||
itemType = KITEM_SAD;
|
||||
|
||||
// update invincibility properties
|
||||
if (itemType == KITEM_INVINCIBILITY)
|
||||
{
|
||||
mobj->renderflags = (mobj->renderflags & ~RF_BRIGHTMASK) | RF_FULLBRIGHT;
|
||||
mobj->colorized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->renderflags = (mobj->renderflags & ~RF_BRIGHTMASK) | RF_SEMIBRIGHT;
|
||||
mobj->color = SKINCOLOR_NONE;
|
||||
mobj->colorized = false;
|
||||
}
|
||||
|
||||
// update cap colors
|
||||
if (itemType == KITEM_SUPERRING)
|
||||
{
|
||||
color = SKINCOLOR_GOLD;
|
||||
newRenderFlags |= RF_SEMIBRIGHT;
|
||||
}
|
||||
else if (mobj->spawnpoint && (mobj->spawnpoint->options & MTF_EXTRA))
|
||||
color = SKINCOLOR_SAPPHIRE;
|
||||
else if (itemType == KITEM_SPB)
|
||||
color = SKINCOLOR_JET;
|
||||
else
|
||||
color = SKINCOLOR_NONE;
|
||||
|
||||
colorized = (color != SKINCOLOR_NONE);
|
||||
part = mobj;
|
||||
while (!P_MobjWasRemoved(part->hnext))
|
||||
{
|
||||
part = part->hnext;
|
||||
part->color = color;
|
||||
part->colorized = colorized;
|
||||
part->renderflags = (part->renderflags & ~RF_BRIGHTMASK) | newRenderFlags;
|
||||
}
|
||||
|
||||
// update inside item frame
|
||||
part = mobj->tracer;
|
||||
if (P_MobjWasRemoved(part))
|
||||
return;
|
||||
|
||||
part->threshold = mobj->threshold;
|
||||
part->movecount = mobj->movecount;
|
||||
|
||||
switch (itemType)
|
||||
{
|
||||
case KITEM_ORBINAUT:
|
||||
part->sprite = SPR_ITMO;
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetOrbinautItemFrame(mobj->movecount);
|
||||
break;
|
||||
case KITEM_INVINCIBILITY:
|
||||
part->sprite = SPR_ITMI;
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetInvincibilityItemFrame();
|
||||
break;
|
||||
case KITEM_SAD:
|
||||
part->sprite = SPR_ITEM;
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE;
|
||||
break;
|
||||
default:
|
||||
part->sprite = SPR_ITEM;
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(itemType);
|
||||
break;
|
||||
}
|
||||
|
||||
// update number frame
|
||||
if (K_GetShieldFromItem(itemType) != KSHIELD_NONE) // shields don't stack, so don't show a number
|
||||
;
|
||||
else
|
||||
{
|
||||
switch (itemType)
|
||||
{
|
||||
case KITEM_ORBINAUT: // only display the number when the sprite no longer changes
|
||||
if (mobj->movecount - 1 > K_GetOrbinautItemFrame(mobj->movecount))
|
||||
count = mobj->movecount;
|
||||
break;
|
||||
case KITEM_SUPERRING: // always display the number, and multiply it by 5
|
||||
count = mobj->movecount * 5;
|
||||
break;
|
||||
case KITEM_SAD: // never display the number
|
||||
case KITEM_SPB:
|
||||
break;
|
||||
default:
|
||||
if (mobj->movecount > 1)
|
||||
count = mobj->movecount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
if (P_MobjWasRemoved(part->tracer))
|
||||
{
|
||||
P_SetTarget(&part->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY));
|
||||
P_SetTarget(&part->tracer->target, part);
|
||||
P_SetMobjState(part->tracer, S_INVISIBLE);
|
||||
part->tracer->spriteyoffset = 10*FRACUNIT;
|
||||
part->tracer->spritexoffset = 13*numNumbers*FRACUNIT;
|
||||
}
|
||||
part = part->tracer;
|
||||
part->sprite = SPR_ITMN;
|
||||
part->frame = FF_FULLBRIGHT|(count % 10);
|
||||
count /= 10;
|
||||
numNumbers++;
|
||||
}
|
||||
|
||||
// delete any extra overlays (I guess in case the number changes?)
|
||||
if (part->tracer)
|
||||
{
|
||||
P_RemoveMobj(part->tracer);
|
||||
P_SetTarget(&part->tracer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#define CAPSULESIDES 5
|
||||
#define ANG_CAPSULE (UINT32_MAX / CAPSULESIDES)
|
||||
#define ROTATIONSPEED (2*ANG2)
|
||||
void A_SpawnItemCapsuleParts(mobj_t *actor)
|
||||
{
|
||||
UINT8 i;
|
||||
mobj_t *part;
|
||||
fixed_t buttScale = 0;
|
||||
statenum_t buttState = S_ITEMCAPSULE_BOTTOM_SIDE_AIR;
|
||||
angle_t spin = ANGLE_MAX - ROTATIONSPEED;
|
||||
|
||||
if (LUA_CallAction(A_SPAWNITEMCAPSULEPARTS, actor))
|
||||
return;
|
||||
|
||||
if (P_IsObjectOnGround(actor))
|
||||
{
|
||||
buttScale = 13*FRACUNIT/10;
|
||||
buttState = S_ITEMCAPSULE_BOTTOM_SIDE_GROUND;
|
||||
spin = 0;
|
||||
}
|
||||
|
||||
// inside item
|
||||
part = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_ITEMCAPSULE_PART);
|
||||
P_SetTarget(&part->target, actor);
|
||||
P_SetMobjState(part, S_ITEMICON);
|
||||
part->movedir = ROTATIONSPEED; // rotation speed
|
||||
part->extravalue1 = 175*FRACUNIT/100; // relative scale
|
||||
part->flags2 |= MF2_CLASSICPUSH; // classicpush = centered horizontally
|
||||
P_SetTarget(&actor->tracer, part); // pointer to this item, so we can modify its sprite/frame
|
||||
|
||||
// capsule caps
|
||||
part = actor;
|
||||
for (i = 0; i < CAPSULESIDES; i++)
|
||||
{
|
||||
// a bottom side
|
||||
P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_ITEMCAPSULE_PART));
|
||||
P_SetTarget(&part->hnext->hprev, part);
|
||||
part = part->hnext;
|
||||
P_SetTarget(&part->target, actor);
|
||||
P_SetMobjState(part, buttState);
|
||||
part->angle = i * ANG_CAPSULE;
|
||||
part->movedir = spin; // rotation speed
|
||||
part->movefactor = 0; // z offset
|
||||
part->extravalue1 = buttScale; // relative scale
|
||||
|
||||
// a top side
|
||||
P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_ITEMCAPSULE_PART));
|
||||
P_SetTarget(&part->hnext->hprev, part);
|
||||
part = part->hnext;
|
||||
P_SetTarget(&part->target, actor);
|
||||
P_SetMobjState(part, S_ITEMCAPSULE_TOP_SIDE);
|
||||
part->angle = i * ANG_CAPSULE;
|
||||
part->movedir = spin; // rotation speed
|
||||
part->movefactor = actor->info->height - part->info->height; // z offset
|
||||
}
|
||||
|
||||
P_RefreshItemCapsuleParts(actor);
|
||||
}
|
||||
#undef CAPSULESIDES
|
||||
#undef ANG_CAPSULE
|
||||
#undef ROTATIONSPEED
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (!special->target)
|
||||
return; // foolproof crash prevention check!!!!!
|
||||
|
||||
P_TeleportMove(player->mo, special->target->x, special->target->y, special->target->z + (48<<FRACBITS));
|
||||
P_SetOrigin(player->mo, special->target->x, special->target->y, special->target->z + (48<<FRACBITS));
|
||||
player->mo->angle = special->target->angle;
|
||||
P_SetObjectMomZ(player->mo, 12<<FRACBITS, false);
|
||||
P_InstaThrust(player->mo, player->mo->angle, 20<<FRACBITS);
|
||||
|
|
|
|||
|
|
@ -365,8 +365,6 @@ void P_InternalFlickyBubble(mobj_t *actor);
|
|||
void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fixed_t chasez);
|
||||
void P_InternalFlickyHop(mobj_t *actor, fixed_t momz, fixed_t momh, angle_t angle);
|
||||
|
||||
void P_RefreshItemCapsuleParts(mobj_t *mobj);
|
||||
|
||||
//
|
||||
// P_MAP
|
||||
//
|
||||
|
|
@ -398,11 +396,13 @@ void P_SetThingPosition(mobj_t *thing);
|
|||
void P_SetUnderlayPosition(mobj_t *thing);
|
||||
|
||||
boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing);
|
||||
boolean P_IsLineTripWire(const line_t *ld);
|
||||
boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y);
|
||||
boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam);
|
||||
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);
|
||||
boolean P_Move(mobj_t *actor, fixed_t speed);
|
||||
boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
|
||||
boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
|
||||
boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
|
||||
void P_SlideMove(mobj_t *mo);
|
||||
void P_BouncePlayerMove(mobj_t *mo);
|
||||
void P_BounceMove(mobj_t *mo);
|
||||
|
|
|
|||
92
src/p_map.c
92
src/p_map.c
|
|
@ -96,7 +96,7 @@ camera_t *mapcampointer;
|
|||
//
|
||||
// P_TeleportMove
|
||||
//
|
||||
boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
||||
static boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
||||
{
|
||||
numspechit = 0U;
|
||||
|
||||
|
|
@ -130,6 +130,31 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
|||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// P_SetOrigin - P_TeleportMove which RESETS interpolation values.
|
||||
//
|
||||
boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
||||
{
|
||||
boolean result = P_TeleportMove(thing, x, y, z);
|
||||
|
||||
if (result == true)
|
||||
{
|
||||
thing->old_x = thing->x;
|
||||
thing->old_y = thing->y;
|
||||
thing->old_z = thing->z;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// P_MoveOrigin - P_TeleportMove which KEEPS interpolation values.
|
||||
//
|
||||
boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
||||
{
|
||||
return P_TeleportMove(thing, x, y, z);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// MOVEMENT ITERATOR FUNCTIONS
|
||||
// =========================================================================
|
||||
|
|
@ -206,11 +231,14 @@ static void add_spechit(line_t *ld)
|
|||
numspechit++;
|
||||
}
|
||||
|
||||
static boolean P_SpecialIsLinedefCrossType(UINT16 ldspecial)
|
||||
static boolean P_SpecialIsLinedefCrossType(line_t *ld)
|
||||
{
|
||||
boolean linedefcrossspecial = false;
|
||||
|
||||
switch (ldspecial)
|
||||
if (P_IsLineTripWire(ld))
|
||||
return true;
|
||||
|
||||
switch (ld->special)
|
||||
{
|
||||
case 2001: // Finish line
|
||||
case 2003: // Respawn line
|
||||
|
|
@ -1552,6 +1580,11 @@ boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing)
|
|||
}
|
||||
}
|
||||
|
||||
boolean P_IsLineTripWire(const line_t *ld)
|
||||
{
|
||||
return ld->tripwire;
|
||||
}
|
||||
|
||||
//
|
||||
// PIT_CheckLine
|
||||
// Adjusts tmfloorz and tmceilingz as lines are contacted
|
||||
|
|
@ -1590,7 +1623,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
|||
cosradius = FixedMul(dist, FINECOSINE(langle>>ANGLETOFINESHIFT));
|
||||
sinradius = FixedMul(dist, FINESINE(langle>>ANGLETOFINESHIFT));
|
||||
tmthing->flags |= MF_NOCLIP;
|
||||
P_TeleportMove(tmthing, result.x + cosradius - tmthing->momx, result.y + sinradius - tmthing->momy, tmthing->z);
|
||||
P_MoveOrigin(tmthing, result.x + cosradius - tmthing->momx, result.y + sinradius - tmthing->momy, tmthing->z);
|
||||
tmthing->flags &= ~MF_NOCLIP;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1666,7 +1699,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
|||
tmdropoffz = lowfloor;
|
||||
|
||||
// we've crossed the line
|
||||
if (P_SpecialIsLinedefCrossType(ld->special))
|
||||
if (P_SpecialIsLinedefCrossType(ld))
|
||||
{
|
||||
add_spechit(ld);
|
||||
}
|
||||
|
|
@ -2660,10 +2693,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
oldside = P_PointOnLineSide(oldx, oldy, ld);
|
||||
if (side != oldside)
|
||||
{
|
||||
if (ld->special)
|
||||
{
|
||||
P_CrossSpecialLine(ld, oldside, thing);
|
||||
}
|
||||
P_CrossSpecialLine(ld, oldside, thing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2745,7 +2775,7 @@ static boolean PTR_GetSpecialLines(intercept_t *in)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (P_SpecialIsLinedefCrossType(ld->special))
|
||||
if (P_SpecialIsLinedefCrossType(ld))
|
||||
{
|
||||
add_spechit(ld);
|
||||
}
|
||||
|
|
@ -2815,10 +2845,7 @@ void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_
|
|||
oldside = P_PointOnLineSide(x, y, ld);
|
||||
if (side != oldside)
|
||||
{
|
||||
if (ld->special)
|
||||
{
|
||||
P_CrossSpecialLine(ld, oldside, thing);
|
||||
}
|
||||
P_CrossSpecialLine(ld, oldside, thing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3022,6 +3049,7 @@ static void P_PlayerHitBounceLine(line_t *ld)
|
|||
INT32 side;
|
||||
angle_t lineangle;
|
||||
fixed_t movelen;
|
||||
fixed_t x, y;
|
||||
|
||||
side = P_PointOnLineSide(slidemo->x, slidemo->y, ld);
|
||||
lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy)-ANGLE_90;
|
||||
|
|
@ -3036,8 +3064,19 @@ static void P_PlayerHitBounceLine(line_t *ld)
|
|||
if (slidemo->player && movelen < (15*mapobjectscale))
|
||||
movelen = (15*mapobjectscale);
|
||||
|
||||
tmxmove += FixedMul(movelen, FINECOSINE(lineangle));
|
||||
tmymove += FixedMul(movelen, FINESINE(lineangle));
|
||||
x = FixedMul(movelen, FINECOSINE(lineangle));
|
||||
y = FixedMul(movelen, FINESINE(lineangle));
|
||||
|
||||
if (P_IsLineTripWire(ld))
|
||||
{
|
||||
tmxmove = x * 4;
|
||||
tmymove = y * 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmxmove += x;
|
||||
tmymove += y;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -3675,15 +3714,13 @@ void P_BouncePlayerMove(mobj_t *mo)
|
|||
tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
|
||||
}
|
||||
|
||||
if (P_IsLineTripWire(bestslideline))
|
||||
{
|
||||
mobj_t *fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP);
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
fx->eflags |= MFE_VERTICALFLIP;
|
||||
else
|
||||
fx->eflags &= ~MFE_VERTICALFLIP;
|
||||
fx->scale = mo->scale;
|
||||
|
||||
S_StartSound(mo, sfx_s3k49);
|
||||
K_ApplyTripWire(mo->player, TRIP_BLOCKED);
|
||||
}
|
||||
else
|
||||
{
|
||||
K_SpawnBumpEffect(mo);
|
||||
}
|
||||
|
||||
P_PlayerHitBounceLine(bestslideline);
|
||||
|
|
@ -3694,8 +3731,11 @@ void P_BouncePlayerMove(mobj_t *mo)
|
|||
mo->player->cmomx = tmxmove;
|
||||
mo->player->cmomy = tmymove;
|
||||
|
||||
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) {
|
||||
P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true);
|
||||
if (!P_IsLineTripWire(bestslideline))
|
||||
{
|
||||
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) {
|
||||
P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
|
||||
#include "k_kart.h"
|
||||
#include "p_local.h"
|
||||
#include "r_main.h"
|
||||
#include "r_data.h"
|
||||
|
|
@ -588,7 +589,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if (mobj)
|
||||
{
|
||||
// Check for collision with front side's midtexture if Effect 4 is set
|
||||
if (linedef->flags & ML_EFFECT4
|
||||
if ((linedef->flags & ML_EFFECT4 || (mobj->player && P_IsLineTripWire(linedef) && !K_TripwirePass(mobj->player)))
|
||||
&& !linedef->polyobj // don't do anything for polyobjects! ...for now
|
||||
) {
|
||||
side_t *side = &sides[linedef->sidenum[0]];
|
||||
|
|
|
|||
331
src/p_mobj.c
331
src/p_mobj.c
|
|
@ -2775,6 +2775,15 @@ void P_PlayerZMovement(mobj_t *mo)
|
|||
P_CheckMarioBlocks(mo);
|
||||
|
||||
mo->momz = 0;
|
||||
P_CheckGravity(mo, true);
|
||||
|
||||
if (abs(mo->momz) < 15 * mapobjectscale)
|
||||
{
|
||||
mo->momz = 15 * mapobjectscale
|
||||
* -(P_MobjFlip(mo));
|
||||
}
|
||||
|
||||
K_SpawnBumpEffect(mo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3511,6 +3520,16 @@ static void P_CheckFloatbobPlatforms(mobj_t *mobj)
|
|||
}
|
||||
}
|
||||
|
||||
static void P_SquishThink(mobj_t *mobj)
|
||||
{
|
||||
if (!(mobj->eflags & MFE_SLOPELAUNCHED))
|
||||
{
|
||||
K_Squish(mobj);
|
||||
}
|
||||
|
||||
mobj->lastmomz = mobj->momz;
|
||||
}
|
||||
|
||||
static void P_PlayerMobjThinker(mobj_t *mobj)
|
||||
{
|
||||
I_Assert(mobj != NULL);
|
||||
|
|
@ -3576,6 +3595,8 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|
|||
mobj->eflags &= ~MFE_JUSTHITFLOOR;
|
||||
}
|
||||
|
||||
P_SquishThink(mobj);
|
||||
|
||||
animonly:
|
||||
P_CyclePlayerMobjState(mobj);
|
||||
}
|
||||
|
|
@ -3636,6 +3657,11 @@ void P_NullPrecipThinker(precipmobj_t *mobj)
|
|||
|
||||
void P_PrecipThinker(precipmobj_t *mobj)
|
||||
{
|
||||
// reset old state (for interpolation)
|
||||
mobj->old_x = mobj->x;
|
||||
mobj->old_y = mobj->y;
|
||||
mobj->old_z = mobj->z;
|
||||
|
||||
P_CycleStateAnimation((mobj_t *)mobj);
|
||||
|
||||
if (mobj->state == &states[S_RAINRETURN])
|
||||
|
|
@ -3781,8 +3807,12 @@ static void P_ItemCapsulePartThinker(mobj_t *mobj)
|
|||
P_SetScale(mobj, mobj->destscale = targetScale);
|
||||
|
||||
// find z position
|
||||
K_GenericExtraFlagsNoZAdjust(mobj, target);
|
||||
if (mobj->flags & MFE_VERTICALFLIP)
|
||||
if (mobj->flags2 & MF2_CLASSICPUSH) // centered items should not be flipped
|
||||
mobj->renderflags = (mobj->renderflags & ~RF_DONTDRAW) | (target->renderflags & RF_DONTDRAW);
|
||||
else
|
||||
K_GenericExtraFlagsNoZAdjust(mobj, target);
|
||||
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
z = target->z + target->height - mobj->height - FixedMul(mobj->scale, mobj->movefactor);
|
||||
else
|
||||
z = target->z + FixedMul(mobj->scale, mobj->movefactor);
|
||||
|
|
@ -3790,15 +3820,202 @@ static void P_ItemCapsulePartThinker(mobj_t *mobj)
|
|||
// rotate & move to capsule
|
||||
mobj->angle += mobj->movedir;
|
||||
if (mobj->flags2 & MF2_CLASSICPUSH) // centered
|
||||
P_TeleportMove(mobj, target->x, target->y, z);
|
||||
P_MoveOrigin(mobj, target->x, target->y, z);
|
||||
else
|
||||
P_TeleportMove(mobj,
|
||||
P_MoveOrigin(mobj,
|
||||
target->x + P_ReturnThrustX(mobj, mobj->angle + ANGLE_90, mobj->radius),
|
||||
target->y + P_ReturnThrustY(mobj, mobj->angle + ANGLE_90, mobj->radius),
|
||||
z);
|
||||
}
|
||||
}
|
||||
|
||||
static void P_RefreshItemCapsuleParts(mobj_t *mobj)
|
||||
{
|
||||
UINT8 numNumbers = 0;
|
||||
INT32 count = 0;
|
||||
INT32 itemType = mobj->threshold;
|
||||
mobj_t *part;
|
||||
skincolornum_t color;
|
||||
UINT32 newRenderFlags = 0;
|
||||
boolean colorized;
|
||||
|
||||
if (itemType < 1 || itemType >= NUMKARTITEMS)
|
||||
itemType = KITEM_SAD;
|
||||
|
||||
// update invincibility properties
|
||||
if (itemType == KITEM_INVINCIBILITY)
|
||||
{
|
||||
mobj->renderflags = (mobj->renderflags & ~RF_BRIGHTMASK) | RF_FULLBRIGHT;
|
||||
mobj->colorized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->renderflags = (mobj->renderflags & ~RF_BRIGHTMASK) | RF_SEMIBRIGHT;
|
||||
mobj->color = SKINCOLOR_NONE;
|
||||
mobj->colorized = false;
|
||||
}
|
||||
|
||||
// update cap colors
|
||||
if (itemType == KITEM_SUPERRING)
|
||||
{
|
||||
color = SKINCOLOR_GOLD;
|
||||
newRenderFlags |= RF_SEMIBRIGHT;
|
||||
}
|
||||
else if (mobj->spawnpoint && (mobj->spawnpoint->options & MTF_EXTRA))
|
||||
color = SKINCOLOR_SAPPHIRE;
|
||||
else if (itemType == KITEM_SPB)
|
||||
color = SKINCOLOR_JET;
|
||||
else
|
||||
color = SKINCOLOR_NONE;
|
||||
|
||||
colorized = (color != SKINCOLOR_NONE);
|
||||
part = mobj;
|
||||
while (!P_MobjWasRemoved(part->hnext))
|
||||
{
|
||||
part = part->hnext;
|
||||
part->color = color;
|
||||
part->colorized = colorized;
|
||||
part->renderflags = (part->renderflags & ~RF_BRIGHTMASK) | newRenderFlags;
|
||||
}
|
||||
|
||||
// update inside item frame
|
||||
part = mobj->tracer;
|
||||
if (P_MobjWasRemoved(part))
|
||||
return;
|
||||
|
||||
part->threshold = mobj->threshold;
|
||||
part->movecount = mobj->movecount;
|
||||
|
||||
switch (itemType)
|
||||
{
|
||||
case KITEM_ORBINAUT:
|
||||
part->sprite = SPR_ITMO;
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetOrbinautItemFrame(mobj->movecount);
|
||||
break;
|
||||
case KITEM_INVINCIBILITY:
|
||||
part->sprite = SPR_ITMI;
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetInvincibilityItemFrame();
|
||||
break;
|
||||
case KITEM_SAD:
|
||||
part->sprite = SPR_ITEM;
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE;
|
||||
break;
|
||||
default:
|
||||
part->sprite = SPR_ITEM;
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(itemType);
|
||||
break;
|
||||
}
|
||||
|
||||
// update number frame
|
||||
if (K_GetShieldFromItem(itemType) != KSHIELD_NONE) // shields don't stack, so don't show a number
|
||||
;
|
||||
else
|
||||
{
|
||||
switch (itemType)
|
||||
{
|
||||
case KITEM_ORBINAUT: // only display the number when the sprite no longer changes
|
||||
if (mobj->movecount - 1 > K_GetOrbinautItemFrame(mobj->movecount))
|
||||
count = mobj->movecount;
|
||||
break;
|
||||
case KITEM_SUPERRING: // always display the number, and multiply it by 5
|
||||
count = mobj->movecount * 5;
|
||||
break;
|
||||
case KITEM_SAD: // never display the number
|
||||
case KITEM_SPB:
|
||||
break;
|
||||
default:
|
||||
if (mobj->movecount > 1)
|
||||
count = mobj->movecount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
if (P_MobjWasRemoved(part->tracer))
|
||||
{
|
||||
P_SetTarget(&part->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY));
|
||||
P_SetTarget(&part->tracer->target, part);
|
||||
P_SetMobjState(part->tracer, S_INVISIBLE);
|
||||
part->tracer->spriteyoffset = 10*FRACUNIT;
|
||||
part->tracer->spritexoffset = 13*numNumbers*FRACUNIT;
|
||||
}
|
||||
part = part->tracer;
|
||||
part->sprite = SPR_ITMN;
|
||||
part->frame = FF_FULLBRIGHT|(count % 10);
|
||||
count /= 10;
|
||||
numNumbers++;
|
||||
}
|
||||
|
||||
// delete any extra overlays (I guess in case the number changes?)
|
||||
if (part->tracer)
|
||||
{
|
||||
P_RemoveMobj(part->tracer);
|
||||
P_SetTarget(&part->tracer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#define CAPSULESIDES 5
|
||||
#define ANG_CAPSULE (UINT32_MAX / CAPSULESIDES)
|
||||
#define ROTATIONSPEED (2*ANG2)
|
||||
static void P_SpawnItemCapsuleParts(mobj_t *mobj)
|
||||
{
|
||||
UINT8 i;
|
||||
mobj_t *part;
|
||||
fixed_t buttScale = 0;
|
||||
statenum_t buttState = S_ITEMCAPSULE_BOTTOM_SIDE_AIR;
|
||||
angle_t spin = ANGLE_MAX - ROTATIONSPEED;
|
||||
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
buttScale = 13*FRACUNIT/10;
|
||||
buttState = S_ITEMCAPSULE_BOTTOM_SIDE_GROUND;
|
||||
spin = 0;
|
||||
}
|
||||
|
||||
// inside item
|
||||
part = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_ITEMCAPSULE_PART);
|
||||
P_SetTarget(&part->target, mobj);
|
||||
P_SetMobjState(part, S_ITEMICON);
|
||||
part->movedir = ROTATIONSPEED; // rotation speed
|
||||
part->extravalue1 = 175*FRACUNIT/100; // relative scale
|
||||
part->flags2 |= MF2_CLASSICPUSH; // classicpush = centered horizontally
|
||||
part->flags2 &= ~MF2_OBJECTFLIP; // centered item should not be flipped
|
||||
part->eflags &= ~MFE_VERTICALFLIP;
|
||||
P_SetTarget(&mobj->tracer, part); // pointer to this item, so we can modify its sprite/frame
|
||||
|
||||
// capsule caps
|
||||
part = mobj;
|
||||
for (i = 0; i < CAPSULESIDES; i++)
|
||||
{
|
||||
// a bottom side
|
||||
P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_ITEMCAPSULE_PART));
|
||||
P_SetTarget(&part->hnext->hprev, part);
|
||||
part = part->hnext;
|
||||
P_SetTarget(&part->target, mobj);
|
||||
P_SetMobjState(part, buttState);
|
||||
part->angle = i * ANG_CAPSULE;
|
||||
part->movedir = spin; // rotation speed
|
||||
part->movefactor = 0; // z offset
|
||||
part->extravalue1 = buttScale; // relative scale
|
||||
|
||||
// a top side
|
||||
P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_ITEMCAPSULE_PART));
|
||||
P_SetTarget(&part->hnext->hprev, part);
|
||||
part = part->hnext;
|
||||
P_SetTarget(&part->target, mobj);
|
||||
P_SetMobjState(part, S_ITEMCAPSULE_TOP_SIDE);
|
||||
part->angle = i * ANG_CAPSULE;
|
||||
part->movedir = spin; // rotation speed
|
||||
part->movefactor = mobj->info->height - part->info->height; // z offset
|
||||
}
|
||||
|
||||
P_RefreshItemCapsuleParts(mobj);
|
||||
}
|
||||
#undef CAPSULESIDES
|
||||
#undef ANG_CAPSULE
|
||||
#undef ROTATIONSPEED
|
||||
|
||||
//
|
||||
// P_BossTargetPlayer
|
||||
// If closest is true, find the closest player.
|
||||
|
|
@ -4211,7 +4428,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y
|
|||
if (dist < source->movefactor)
|
||||
{
|
||||
source->momx = source->momy = source->momz = 0;
|
||||
P_TeleportMove(source, tx, ty, tz);
|
||||
P_MoveOrigin(source, tx, ty, tz);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -6153,6 +6370,14 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->z -= (mobj->height - oldHeight);
|
||||
}
|
||||
|
||||
// spawn parts if not done yet
|
||||
// (this SHOULD be done when the capsule is spawned, but gravflip isn't set up at that point)
|
||||
if (!(mobj->flags2 & MF2_JUSTATTACKED))
|
||||
{
|
||||
mobj->flags2 |= MF2_JUSTATTACKED;
|
||||
P_SpawnItemCapsuleParts(mobj);
|
||||
}
|
||||
|
||||
// update & animate capsule
|
||||
if (!P_MobjWasRemoved(mobj->tracer))
|
||||
{
|
||||
|
|
@ -6542,7 +6767,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->angle += ANGLE_90;
|
||||
}
|
||||
|
||||
P_TeleportMove(mobj,
|
||||
P_MoveOrigin(mobj,
|
||||
mobj->target->x + P_ReturnThrustX(mobj, angle + ANGLE_180, nudge),
|
||||
mobj->target->y + P_ReturnThrustY(mobj, angle + ANGLE_180, nudge),
|
||||
mobj->target->z);
|
||||
|
|
@ -6621,7 +6846,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
}
|
||||
|
||||
mobj->angle = mobj->target->angle;
|
||||
P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius),
|
||||
P_MoveOrigin(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius),
|
||||
mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z);
|
||||
P_SetScale(mobj, mobj->target->scale);
|
||||
|
||||
|
|
@ -6673,7 +6898,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
P_RemoveMobj(mobj);
|
||||
return false;
|
||||
}
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
break;
|
||||
case MT_BRAKEDRIFT:
|
||||
if ((!mobj->target || !mobj->target->health || !mobj->target->player || !P_IsObjectOnGround(mobj->target))
|
||||
|
|
@ -6694,7 +6919,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
|
||||
newx = mobj->target->x + P_ReturnThrustX(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale);
|
||||
newy = mobj->target->y + P_ReturnThrustY(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale);
|
||||
P_TeleportMove(mobj, newx, newy, mobj->target->z);
|
||||
P_MoveOrigin(mobj, newx, newy, mobj->target->z);
|
||||
|
||||
mobj->angle = travelangle - ((ANGLE_90/5)*mobj->target->player->drift);
|
||||
P_SetScale(mobj, (mobj->destscale = mobj->target->scale));
|
||||
|
|
@ -6723,7 +6948,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
{
|
||||
mobj->fuse = 9;
|
||||
}
|
||||
P_TeleportMove(mobj, mobj->target->x,
|
||||
P_MoveOrigin(mobj, mobj->target->x,
|
||||
mobj->target->y, mobj->target->z);
|
||||
mobj->angle = mobj->target->angle + mobj->cusval;
|
||||
break;
|
||||
|
|
@ -6733,7 +6958,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
P_RemoveMobj(mobj);
|
||||
return false;
|
||||
}
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
break;
|
||||
case MT_INSTASHIELDB:
|
||||
mobj->renderflags ^= RF_DONTDRAW;
|
||||
|
|
@ -6745,7 +6970,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
P_RemoveMobj(mobj);
|
||||
return false;
|
||||
}
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
break;
|
||||
case MT_BATTLEPOINT:
|
||||
|
|
@ -6768,7 +6993,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->movefactor = mobj->target->height;
|
||||
}
|
||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (mobj->target->height/2) + mobj->movefactor);
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (mobj->target->height/2) + mobj->movefactor);
|
||||
break;
|
||||
case MT_RINGSPARKS:
|
||||
if (!mobj->target || P_MobjWasRemoved(mobj->target))
|
||||
|
|
@ -6781,7 +7006,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
|
||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
|
||||
P_TeleportMove(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT),
|
||||
P_MoveOrigin(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT),
|
||||
mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT),
|
||||
mobj->z + (mobj->target->height * P_MobjFlip(mobj)));
|
||||
break;
|
||||
|
|
@ -6802,7 +7027,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
mobj->renderflags = (mobj->renderflags & ~RF_DONTDRAW)|K_GetPlayerDontDrawFlag(mobj->target->player);
|
||||
|
||||
P_TeleportMove(mobj, mobj->target->x + FixedMul(34 * mapobjectscale, FINECOSINE((mobj->angle + mobj->movedir) >> ANGLETOFINESHIFT)),
|
||||
P_MoveOrigin(mobj, mobj->target->x + FixedMul(34 * mapobjectscale, FINECOSINE((mobj->angle + mobj->movedir) >> ANGLETOFINESHIFT)),
|
||||
mobj->target->y + FixedMul(34 * mapobjectscale, FINESINE((mobj->angle + mobj->movedir) >> ANGLETOFINESHIFT)),
|
||||
mobj->z + (32 * mapobjectscale * P_MobjFlip(mobj)));
|
||||
|
||||
|
|
@ -6845,7 +7070,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
fixed_t newx = mobj->target->x + P_ReturnThrustX(NULL, mobj->target->angle + perpendicular, 8*mobj->target->scale);
|
||||
fixed_t newy = mobj->target->y + P_ReturnThrustY(NULL, mobj->target->angle + perpendicular, 8*mobj->target->scale);
|
||||
|
||||
P_TeleportMove(mobj, newx, newy, mobj->target->z);
|
||||
P_MoveOrigin(mobj, newx, newy, mobj->target->z);
|
||||
|
||||
if (mobj->extravalue1 & 1)
|
||||
mobj->angle = mobj->target->angle - ANGLE_45;
|
||||
|
|
@ -6883,7 +7108,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
else
|
||||
ang = (signed)(ang + off);
|
||||
|
||||
P_TeleportMove(mobj,
|
||||
P_MoveOrigin(mobj,
|
||||
mobj->target->x - FixedMul(mobj->target->radius, FINECOSINE(ang >> ANGLETOFINESHIFT)),
|
||||
mobj->target->y - FixedMul(mobj->target->radius, FINESINE(ang >> ANGLETOFINESHIFT)),
|
||||
z);
|
||||
|
|
@ -6938,7 +7163,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
desty = mobj->target->y;
|
||||
}
|
||||
|
||||
P_TeleportMove(mobj, destx, desty, mobj->target->z);
|
||||
P_MoveOrigin(mobj, destx, desty, mobj->target->z);
|
||||
break;
|
||||
}
|
||||
case MT_BUBBLESHIELD:
|
||||
|
|
@ -7066,7 +7291,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
desty = mobj->target->y;
|
||||
}
|
||||
|
||||
P_TeleportMove(mobj, destx, desty, mobj->target->z);
|
||||
P_MoveOrigin(mobj, destx, desty, mobj->target->z);
|
||||
break;
|
||||
}
|
||||
case MT_FLAMESHIELD:
|
||||
|
|
@ -7174,7 +7399,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
desty = mobj->target->y;
|
||||
}
|
||||
|
||||
P_TeleportMove(mobj, destx, desty, mobj->target->z);
|
||||
P_MoveOrigin(mobj, destx, desty, mobj->target->z);
|
||||
mobj->angle = K_MomentumAngle(mobj->target);
|
||||
|
||||
if (underlayst != S_NULL)
|
||||
|
|
@ -7218,7 +7443,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
return false;
|
||||
}
|
||||
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
mobj->angle = mobj->target->angle;
|
||||
mobj->scalespeed = mobj->target->scalespeed;
|
||||
mobj->destscale = mobj->target->destscale;
|
||||
|
|
@ -7268,7 +7493,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
if (cur->lastlook == 2 || cur->lastlook == 3)
|
||||
offy *= -1;
|
||||
|
||||
P_TeleportMove(cur, mobj->x + offx, mobj->y + offy, mobj->z);
|
||||
P_MoveOrigin(cur, mobj->x + offx, mobj->y + offy, mobj->z);
|
||||
cur->scalespeed = mobj->target->scalespeed;
|
||||
cur->destscale = mobj->target->destscale;
|
||||
P_SetScale(cur, mobj->target->scale);
|
||||
|
|
@ -7407,7 +7632,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
amt += 1;
|
||||
}
|
||||
|
||||
P_TeleportMove(
|
||||
P_MoveOrigin(
|
||||
cur,
|
||||
mobj->x + FixedMul(amt, FINECOSINE(dir >> ANGLETOFINESHIFT)),
|
||||
mobj->y + FixedMul(amt, FINESINE(dir >> ANGLETOFINESHIFT)),
|
||||
|
|
@ -7497,7 +7722,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
while (cur && !P_MobjWasRemoved(cur))
|
||||
{
|
||||
cur->angle += FixedAngle(mobj->info->speed);
|
||||
P_TeleportMove(cur, mobj->x + FINECOSINE((cur->angle*8)>>ANGLETOFINESHIFT),
|
||||
P_MoveOrigin(cur, mobj->x + FINECOSINE((cur->angle*8)>>ANGLETOFINESHIFT),
|
||||
mobj->y + FINESINE((cur->angle*8)>>ANGLETOFINESHIFT), mobj->z);
|
||||
//P_SpawnGhostMobj(cur)->tics = 2;
|
||||
|
||||
|
|
@ -7630,7 +7855,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
fixed_t wz = mobj->tracer->z + (joint * ((mobj->z + (mobj->height/2)) - mobj->tracer->z) / (numjoints+1));
|
||||
|
||||
if (cur && !P_MobjWasRemoved(cur))
|
||||
P_TeleportMove(cur, wx, wy, wz);
|
||||
P_MoveOrigin(cur, wx, wy, wz);
|
||||
else
|
||||
cur = P_SpawnMobj(wx, wy, wz, MT_FROGTONGUE_JOINT);
|
||||
|
||||
|
|
@ -7741,7 +7966,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
continue;
|
||||
}
|
||||
else // Move into place
|
||||
P_TeleportMove(cur, mobj->x, mobj->y, segz);
|
||||
P_MoveOrigin(cur, mobj->x, mobj->y, segz);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -7815,7 +8040,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->extravalue1 = 1;
|
||||
player->offroad += 2<<FRACBITS;
|
||||
|
||||
P_TeleportMove(mobj,
|
||||
P_MoveOrigin(mobj,
|
||||
player->mo->x + P_ReturnThrustX(NULL, player->mo->angle, player->mo->radius)
|
||||
+ P_ReturnThrustX(NULL, player->mo->angle+ANGLE_90, (mobj->threshold)<<FRACBITS),
|
||||
player->mo->y + P_ReturnThrustY(NULL, player->mo->angle, player->mo->radius)
|
||||
|
|
@ -7976,7 +8201,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->tracer->momx = mobj->tracer->momy = 0;
|
||||
}
|
||||
|
||||
P_TeleportMove(mobj,
|
||||
P_MoveOrigin(mobj,
|
||||
mobj->tracer->x + P_ReturnThrustX(NULL, mobj->tracer->angle+ANGLE_90, (mobj->cvmem)<<FRACBITS),
|
||||
mobj->tracer->y + P_ReturnThrustY(NULL, mobj->tracer->angle+ANGLE_90, (mobj->cvmem)<<FRACBITS),
|
||||
mobj->tracer->z - (4*mobj->tracer->scale) + (P_RandomRange(-abs(mobj->cvmem), abs(mobj->cvmem))<<FRACBITS));
|
||||
|
|
@ -8319,7 +8544,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
cur->angle = angle + ANGLE_90;
|
||||
}
|
||||
|
||||
P_TeleportMove(cur, newx, newy, newz);
|
||||
P_MoveOrigin(cur, newx, newy, newz);
|
||||
|
||||
cur = cur->hnext;
|
||||
}
|
||||
|
|
@ -8345,7 +8570,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->extravalue1++;
|
||||
dist = mobj->extravalue1 * mapobjectscale;
|
||||
|
||||
P_TeleportMove(mobj, battleovertime.x + P_ReturnThrustX(NULL, ang, dist),
|
||||
P_MoveOrigin(mobj, battleovertime.x + P_ReturnThrustX(NULL, ang, dist),
|
||||
battleovertime.y + P_ReturnThrustY(NULL, ang, dist), z);
|
||||
|
||||
ghost = P_SpawnGhostMobj(mobj);
|
||||
|
|
@ -8593,6 +8818,11 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
I_Assert(mobj != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mobj));
|
||||
|
||||
// Set old position (for interpolation)
|
||||
mobj->old_x = mobj->x;
|
||||
mobj->old_y = mobj->y;
|
||||
mobj->old_z = mobj->z;
|
||||
|
||||
// Remove dead target/tracer.
|
||||
if (mobj->target && P_MobjWasRemoved(mobj->target))
|
||||
P_SetTarget(&mobj->target, NULL);
|
||||
|
|
@ -8616,7 +8846,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
return;
|
||||
}
|
||||
|
||||
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL|MFE_DAMAGEHITLAG);
|
||||
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL|MFE_DAMAGEHITLAG|MFE_SLOPELAUNCHED);
|
||||
|
||||
tmfloorthing = tmhitthing = NULL;
|
||||
|
||||
|
|
@ -8805,6 +9035,8 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_ButteredSlope(mobj);
|
||||
}
|
||||
|
||||
P_SquishThink(mobj);
|
||||
|
||||
if (mobj->flags & (MF_ENEMY|MF_BOSS) && mobj->health
|
||||
&& P_CheckDeathPitCollide(mobj)) // extra pit check in case these didn't have momz
|
||||
{
|
||||
|
|
@ -9480,8 +9712,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
// SRB2Kart
|
||||
case MT_ITEMCAPSULE:
|
||||
{
|
||||
fixed_t oldHeight = mobj->height;
|
||||
|
||||
// set default item & count
|
||||
#if 0 // set to 1 to test capsules with random items, e.g. with objectplace
|
||||
if (P_RandomChance(FRACUNIT/3))
|
||||
|
|
@ -9498,17 +9728,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
mobj->movecount = 1;
|
||||
#endif
|
||||
|
||||
// grounded/aerial properties
|
||||
P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 0);
|
||||
if (!P_IsObjectOnGround(mobj))
|
||||
mobj->flags |= MF_NOGRAVITY;
|
||||
|
||||
// set starting scale
|
||||
mobj->extravalue1 = mobj->scale; // this acts as the capsule's destscale; we're avoiding P_MobjScaleThink because we want aerial capsules not to scale from their center
|
||||
mobj->scalespeed >>= 1;
|
||||
P_SetScale(mobj, mobj->destscale = mapobjectscale >> 4);
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
mobj->z += (oldHeight - mobj->height);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -9670,7 +9893,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
cur = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_SIDE);
|
||||
P_SetTarget(&cur->target, mobj);
|
||||
cur->threshold = i;
|
||||
P_TeleportMove(cur, cur->x + ((cur->radius>>FRACBITS) * FINECOSINE((FixedAngle((90*cur->threshold)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK)),
|
||||
P_MoveOrigin(cur, cur->x + ((cur->radius>>FRACBITS) * FINECOSINE((FixedAngle((90*cur->threshold)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK)),
|
||||
cur->y + ((cur->radius>>FRACBITS) * FINESINE((FixedAngle((90*cur->threshold)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK)), cur->z);
|
||||
cur->angle = ANGLE_90*(cur->threshold+1);
|
||||
|
||||
|
|
@ -9743,6 +9966,11 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
if (CheckForReverseGravity && !(mobj->flags & MF_NOBLOCKMAP))
|
||||
P_CheckGravity(mobj, false);
|
||||
|
||||
// set initial old positions (for interpolation)
|
||||
mobj->old_x = mobj->x;
|
||||
mobj->old_y = mobj->y;
|
||||
mobj->old_z = mobj->z;
|
||||
|
||||
return mobj;
|
||||
}
|
||||
|
||||
|
|
@ -9794,6 +10022,11 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|
|||
|| mobj->subsector->sector->floorpic == skyflatnum)
|
||||
mobj->precipflags |= PCF_PIT;
|
||||
|
||||
// set initial old positions (for interpolation)
|
||||
mobj->old_x = mobj->x;
|
||||
mobj->old_y = mobj->y;
|
||||
mobj->old_z = mobj->z;
|
||||
|
||||
return mobj;
|
||||
}
|
||||
|
||||
|
|
@ -11768,6 +12001,22 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
}
|
||||
case MT_ITEMCAPSULE:
|
||||
{
|
||||
// we have to adjust for reverse gravity early so that the below grounded checks work
|
||||
if (mthing->options & MTF_OBJECTFLIP)
|
||||
{
|
||||
mobj->eflags |= MFE_VERTICALFLIP;
|
||||
mobj->flags2 |= MF2_OBJECTFLIP;
|
||||
mobj->z += FixedMul(mobj->extravalue1, mobj->info->height) - mobj->height;
|
||||
}
|
||||
|
||||
// determine whether this capsule is grounded or aerial
|
||||
if (mobj->subsector->sector->ffloors)
|
||||
P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 0);
|
||||
if (mobj->subsector->polyList)
|
||||
P_AdjustMobjFloorZ_PolyObjs(mobj, mobj->subsector);
|
||||
if (!P_IsObjectOnGround(mobj))
|
||||
mobj->flags |= MF_NOGRAVITY;
|
||||
|
||||
// Angle = item type
|
||||
if (mthing->angle > 0 && mthing->angle < NUMKARTITEMS)
|
||||
mobj->threshold = mthing->angle;
|
||||
|
|
|
|||
|
|
@ -249,6 +249,8 @@ typedef enum
|
|||
MFE_JUSTBOUNCEDWALL = 1<<12,
|
||||
// SRB2Kart: In damage hitlag (displays different visual efx)
|
||||
MFE_DAMAGEHITLAG = 1<<13,
|
||||
// Slope physics sent you airborne
|
||||
MFE_SLOPELAUNCHED = 1<<14,
|
||||
// free: to and including 1<<15
|
||||
} mobjeflag_t;
|
||||
|
||||
|
|
@ -275,6 +277,7 @@ typedef struct mobj_s
|
|||
|
||||
// Info for drawing: position.
|
||||
fixed_t x, y, z;
|
||||
fixed_t old_x, old_y, old_z; // position interpolation
|
||||
|
||||
// More list: links in sector (if needed)
|
||||
struct mobj_s *snext;
|
||||
|
|
@ -360,6 +363,7 @@ typedef struct mobj_s
|
|||
|
||||
fixed_t friction;
|
||||
fixed_t movefactor;
|
||||
fixed_t lastmomz;
|
||||
|
||||
INT32 fuse; // Does something in P_MobjThinker on reaching 0.
|
||||
fixed_t watertop; // top of the water FOF the mobj is in
|
||||
|
|
@ -412,6 +416,7 @@ typedef struct precipmobj_s
|
|||
|
||||
// Info for drawing: position.
|
||||
fixed_t x, y, z;
|
||||
fixed_t old_x, old_y, old_z; // position interpolation
|
||||
|
||||
// More list: links in sector (if needed)
|
||||
struct precipmobj_s *snext;
|
||||
|
|
|
|||
|
|
@ -318,6 +318,7 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEINT16(save_p, players[i].spheres);
|
||||
|
||||
WRITESINT8(save_p, players[i].glanceDir);
|
||||
WRITEUINT8(save_p, players[i].tripWireState);
|
||||
|
||||
WRITEUINT8(save_p, players[i].typing_timer);
|
||||
WRITEUINT8(save_p, players[i].typing_duration);
|
||||
|
|
@ -573,6 +574,7 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].spheres = READINT16(save_p);
|
||||
|
||||
players[i].glanceDir = READSINT8(save_p);
|
||||
players[i].tripWireState = READUINT8(save_p);
|
||||
|
||||
players[i].typing_timer = READUINT8(save_p);
|
||||
players[i].typing_duration = READUINT8(save_p);
|
||||
|
|
@ -1532,7 +1534,8 @@ typedef enum
|
|||
MD2_HITLAG = 1<<24,
|
||||
MD2_WAYPOINTCAP = 1<<25,
|
||||
MD2_KITEMCAP = 1<<26,
|
||||
MD2_ITNEXT = 1<<27
|
||||
MD2_ITNEXT = 1<<27,
|
||||
MD2_LASTMOMZ = 1<<28,
|
||||
} mobj_diff2_t;
|
||||
|
||||
typedef enum
|
||||
|
|
@ -1773,6 +1776,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
diff2 |= MD2_KITEMCAP;
|
||||
if (mobj->itnext)
|
||||
diff2 |= MD2_ITNEXT;
|
||||
if (mobj->lastmomz)
|
||||
diff2 |= MD2_LASTMOMZ;
|
||||
|
||||
if (diff2 != 0)
|
||||
diff |= MD_MORE;
|
||||
|
|
@ -1966,6 +1971,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
{
|
||||
WRITEINT32(save_p, mobj->hitlag);
|
||||
}
|
||||
if (diff2 & MD2_LASTMOMZ)
|
||||
{
|
||||
WRITEINT32(save_p, mobj->lastmomz);
|
||||
}
|
||||
|
||||
WRITEUINT32(save_p, mobj->mobjnum);
|
||||
}
|
||||
|
|
@ -3060,6 +3069,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
{
|
||||
mobj->hitlag = READINT32(save_p);
|
||||
}
|
||||
if (diff2 & MD2_LASTMOMZ)
|
||||
{
|
||||
mobj->lastmomz = READINT32(save_p);
|
||||
}
|
||||
|
||||
if (diff & MD_REDFLAG)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1044,6 +1044,8 @@ static void P_InitializeLinedef(line_t *ld)
|
|||
ld->validcount = 0;
|
||||
ld->polyobj = NULL;
|
||||
|
||||
ld->tripwire = false;
|
||||
|
||||
ld->text = NULL;
|
||||
ld->callcount = 0;
|
||||
|
||||
|
|
@ -1936,11 +1938,23 @@ static void P_ProcessLinedefsAfterSidedefs(void)
|
|||
{
|
||||
size_t i = numlines;
|
||||
register line_t *ld = lines;
|
||||
|
||||
const INT32 TEX_TRIPWIRE = R_TextureNumForName("TRIPWIRE");
|
||||
const INT32 TEX_4RIPWIRE = R_TextureNumForName("4RIPWIRE");
|
||||
|
||||
for (; i--; ld++)
|
||||
{
|
||||
INT32 midtexture = sides[ld->sidenum[0]].midtexture;
|
||||
|
||||
ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here
|
||||
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0;
|
||||
|
||||
if (midtexture == TEX_TRIPWIRE ||
|
||||
midtexture == TEX_4RIPWIRE)
|
||||
{
|
||||
ld->tripwire = true;
|
||||
}
|
||||
|
||||
switch (ld->special)
|
||||
{
|
||||
// Compile linedef 'text' from both sidedefs 'text' for appropriate specials.
|
||||
|
|
|
|||
|
|
@ -844,6 +844,8 @@ void P_SlopeLaunch(mobj_t *mo)
|
|||
mo->momy = slopemom.y;
|
||||
mo->momz = slopemom.z;
|
||||
#endif
|
||||
|
||||
mo->eflags |= MFE_SLOPELAUNCHED;
|
||||
}
|
||||
|
||||
//CONS_Printf("Launched off of slope.\n");
|
||||
|
|
|
|||
|
|
@ -2018,6 +2018,12 @@ void P_CrossSpecialLine(line_t *line, INT32 side, mobj_t *thing)
|
|||
return;
|
||||
{
|
||||
player_t *player = thing->player;
|
||||
|
||||
if (P_IsLineTripWire(line))
|
||||
{
|
||||
K_ApplyTripWire(player, TRIP_PASSED);
|
||||
}
|
||||
|
||||
switch (line->special)
|
||||
{
|
||||
case 2001: // Finish Line
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
|
|||
{
|
||||
UINT8 i;
|
||||
|
||||
if (!P_TeleportMove(thing, x, y, z))
|
||||
if (!P_SetOrigin(thing, x, y, z))
|
||||
return false;
|
||||
|
||||
if (!dontstopmove)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "lua_hook.h"
|
||||
#include "m_perfstats.h"
|
||||
#include "i_system.h" // I_GetPreciseTime
|
||||
#include "r_fps.h"
|
||||
|
||||
// Object place
|
||||
#include "m_cheat.h"
|
||||
|
|
|
|||
33
src/p_user.c
33
src/p_user.c
|
|
@ -1058,6 +1058,9 @@ boolean P_IsLocalPlayer(player_t *player)
|
|||
{
|
||||
UINT8 i;
|
||||
|
||||
if (demo.playback)
|
||||
return P_IsDisplayPlayer(player);
|
||||
|
||||
for (i = 0; i <= r_splitscreen; i++) // DON'T skip P1
|
||||
{
|
||||
if (player == &players[g_localplayers[i]])
|
||||
|
|
@ -1138,6 +1141,11 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
|||
ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW);
|
||||
}
|
||||
|
||||
// Copy interpolation data :)
|
||||
ghost->old_x = mobj->old_x;
|
||||
ghost->old_y = mobj->old_y;
|
||||
ghost->old_z = mobj->old_z;
|
||||
|
||||
return ghost;
|
||||
}
|
||||
|
||||
|
|
@ -2115,6 +2123,9 @@ void P_MovePlayer(player_t *player)
|
|||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY);
|
||||
water->angle = forwardangle - ANGLE_180 - ANGLE_22h;
|
||||
water->destscale = trailScale;
|
||||
water->momx = player->mo->momx;
|
||||
water->momy = player->mo->momy;
|
||||
water->momz = player->mo->momz;
|
||||
P_SetScale(water, trailScale);
|
||||
P_SetMobjState(water, curUnderlayFrame);
|
||||
|
||||
|
|
@ -2123,6 +2134,9 @@ void P_MovePlayer(player_t *player)
|
|||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL);
|
||||
water->angle = forwardangle - ANGLE_180 - ANGLE_22h;
|
||||
water->destscale = trailScale;
|
||||
water->momx = player->mo->momx;
|
||||
water->momy = player->mo->momy;
|
||||
water->momz = player->mo->momz;
|
||||
P_SetScale(water, trailScale);
|
||||
P_SetMobjState(water, curOverlayFrame);
|
||||
|
||||
|
|
@ -2132,6 +2146,9 @@ void P_MovePlayer(player_t *player)
|
|||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY);
|
||||
water->angle = forwardangle - ANGLE_180 + ANGLE_22h;
|
||||
water->destscale = trailScale;
|
||||
water->momx = player->mo->momx;
|
||||
water->momy = player->mo->momy;
|
||||
water->momz = player->mo->momz;
|
||||
P_SetScale(water, trailScale);
|
||||
P_SetMobjState(water, curUnderlayFrame);
|
||||
|
||||
|
|
@ -2140,6 +2157,9 @@ void P_MovePlayer(player_t *player)
|
|||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL);
|
||||
water->angle = forwardangle - ANGLE_180 + ANGLE_22h;
|
||||
water->destscale = trailScale;
|
||||
water->momx = player->mo->momx;
|
||||
water->momy = player->mo->momy;
|
||||
water->momz = player->mo->momz;
|
||||
P_SetScale(water, trailScale);
|
||||
P_SetMobjState(water, curOverlayFrame);
|
||||
|
||||
|
|
@ -3847,13 +3867,12 @@ static void P_HandleFollower(player_t *player)
|
|||
}
|
||||
|
||||
// Set follower colour
|
||||
|
||||
switch (player->followercolor)
|
||||
{
|
||||
case MAXSKINCOLORS: // "Match"
|
||||
case 255: // "Match" (-1)
|
||||
color = player->skincolor;
|
||||
break;
|
||||
case MAXSKINCOLORS+1: // "Opposite"
|
||||
case 254: // "Opposite" (-2)
|
||||
color = skincolors[player->skincolor].invcolor;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -3914,9 +3933,10 @@ static void P_HandleFollower(player_t *player)
|
|||
P_SetFollowerState(player->follower, player->follower->state->nextstate);
|
||||
|
||||
// move the follower next to us (yes, this is really basic maths but it looks pretty damn clean in practice)!
|
||||
player->follower->momx = (sx - player->follower->x)/fl.horzlag;
|
||||
player->follower->momy = (sy - player->follower->y)/fl.horzlag;
|
||||
player->follower->momz = (sz - player->follower->z)/fl.vertlag;
|
||||
// 02/09/2021: cast lag to int32 otherwise funny things happen since it was changed to uint32 in the struct
|
||||
player->follower->momx = (sx - player->follower->x)/ (INT32)fl.horzlag;
|
||||
player->follower->momy = (sy - player->follower->y)/ (INT32)fl.horzlag;
|
||||
player->follower->momz = (sz - player->follower->z)/ (INT32)fl.vertlag;
|
||||
player->follower->angle = player->mo->angle;
|
||||
|
||||
if (player->mo->colorized)
|
||||
|
|
@ -4352,6 +4372,7 @@ void P_PlayerThink(player_t *player)
|
|||
player->flashing = TICRATE/2 + 1;
|
||||
/*if (P_SpectatorJoinGame(player))
|
||||
return; // player->mo was removed.*/
|
||||
//CONS_Printf("player %s wants to join on tic %d\n", player_names[player-players], leveltime);
|
||||
}
|
||||
|
||||
if (player->respawn.state != RESPAWNST_NONE)
|
||||
|
|
|
|||
|
|
@ -420,6 +420,8 @@ typedef struct line_s
|
|||
size_t validcount; // if == validcount, already checked
|
||||
polyobj_t *polyobj; // Belongs to a polyobject?
|
||||
|
||||
boolean tripwire;
|
||||
|
||||
char *text; // a concatenation of all front and back texture names, for linedef specials that require a string.
|
||||
INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
|
||||
} line_t;
|
||||
|
|
|
|||
163
src/r_fps.c
Normal file
163
src/r_fps.c
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze, Andrey Budko (prboom)
|
||||
// Copyright (C) 1999-2019 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file r_fps.h
|
||||
/// \brief Uncapped framerate stuff.
|
||||
|
||||
#include "r_fps.h"
|
||||
|
||||
#include "r_main.h"
|
||||
#include "g_game.h"
|
||||
#include "i_video.h"
|
||||
#include "r_plane.h"
|
||||
#include "p_spec.h"
|
||||
#include "r_state.h"
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h" // for cv_glshearing
|
||||
#endif
|
||||
|
||||
static viewvars_t pview_old[MAXSPLITSCREENPLAYERS];
|
||||
static viewvars_t pview_new[MAXSPLITSCREENPLAYERS];
|
||||
static viewvars_t skyview_old[MAXSPLITSCREENPLAYERS];
|
||||
static viewvars_t skyview_new[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
static viewvars_t *oldview = &pview_old[0];
|
||||
viewvars_t *newview = &pview_new[0];
|
||||
|
||||
|
||||
enum viewcontext_e viewcontext = VIEWCONTEXT_PLAYER1;
|
||||
|
||||
static fixed_t R_LerpFixed(fixed_t from, fixed_t to, fixed_t frac)
|
||||
{
|
||||
return FixedMul(frac, to - from);
|
||||
}
|
||||
|
||||
static angle_t R_LerpAngle(angle_t from, angle_t to, fixed_t frac)
|
||||
{
|
||||
return FixedMul(frac, to - from);
|
||||
}
|
||||
|
||||
// recalc necessary stuff for mouseaiming
|
||||
// slopes are already calculated for the full possible view (which is 4*viewheight).
|
||||
// 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out)
|
||||
static void R_SetupFreelook(player_t *player, boolean skybox)
|
||||
{
|
||||
#ifndef HWRENDER
|
||||
(void)player;
|
||||
(void)skybox;
|
||||
#endif
|
||||
|
||||
// clip it in the case we are looking a hardware 90 degrees full aiming
|
||||
// (lmps, network and use F12...)
|
||||
if (rendermode == render_soft
|
||||
#ifdef HWRENDER
|
||||
|| (rendermode == render_opengl
|
||||
&& (cv_glshearing.value == 1
|
||||
|| (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox))))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
|
||||
}
|
||||
|
||||
centeryfrac = (viewheight/2)<<FRACBITS;
|
||||
|
||||
if (rendermode == render_soft)
|
||||
centeryfrac += FixedMul(AIMINGTODY(aimingangle), FixedDiv(viewwidth<<FRACBITS, BASEVIDWIDTH<<FRACBITS));
|
||||
|
||||
centery = FixedInt(FixedRound(centeryfrac));
|
||||
|
||||
if (rendermode == render_soft)
|
||||
yslope = &yslopetab[viewssnum][viewheight*8 - centery];
|
||||
}
|
||||
|
||||
#undef AIMINGTODY
|
||||
|
||||
void R_InterpolateView(fixed_t frac)
|
||||
{
|
||||
boolean skybox = false;
|
||||
INT32 i;
|
||||
|
||||
if (FIXED_TO_FLOAT(frac) < 0)
|
||||
frac = 0;
|
||||
if (frac > FRACUNIT)
|
||||
frac = FRACUNIT;
|
||||
|
||||
viewx = oldview->x + R_LerpFixed(oldview->x, newview->x, frac);
|
||||
viewy = oldview->y + R_LerpFixed(oldview->y, newview->y, frac);
|
||||
viewz = oldview->z + R_LerpFixed(oldview->z, newview->z, frac);
|
||||
|
||||
viewangle = oldview->angle + R_LerpAngle(oldview->angle, newview->angle, frac);
|
||||
aimingangle = oldview->aim + R_LerpAngle(oldview->aim, newview->aim, frac);
|
||||
|
||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
|
||||
// this is gonna create some interesting visual errors for long distance teleports...
|
||||
// might want to recalculate the view sector every frame instead...
|
||||
viewplayer = newview->player;
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
|
||||
// well, this ain't pretty
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (newview == &skyview_new[i])
|
||||
{
|
||||
skybox = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
R_SetupFreelook(newview->player, skybox);
|
||||
}
|
||||
|
||||
void R_UpdateViewInterpolation(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
pview_old[i] = pview_new[i];
|
||||
skyview_old[i] = skyview_new[i];
|
||||
}
|
||||
}
|
||||
|
||||
void R_SetViewContext(enum viewcontext_e _viewcontext)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
I_Assert(_viewcontext >= VIEWCONTEXT_PLAYER1
|
||||
&& _viewcontext <= VIEWCONTEXT_SKY4);
|
||||
viewcontext = _viewcontext;
|
||||
|
||||
switch (viewcontext)
|
||||
{
|
||||
case VIEWCONTEXT_PLAYER1:
|
||||
case VIEWCONTEXT_PLAYER2:
|
||||
case VIEWCONTEXT_PLAYER3:
|
||||
case VIEWCONTEXT_PLAYER4:
|
||||
i = viewcontext - VIEWCONTEXT_PLAYER1;
|
||||
oldview = &pview_old[i];
|
||||
newview = &pview_new[i];
|
||||
break;
|
||||
case VIEWCONTEXT_SKY1:
|
||||
case VIEWCONTEXT_SKY2:
|
||||
case VIEWCONTEXT_SKY3:
|
||||
case VIEWCONTEXT_SKY4:
|
||||
i = viewcontext - VIEWCONTEXT_SKY1;
|
||||
oldview = &skyview_old[i];
|
||||
newview = &skyview_new[i];
|
||||
break;
|
||||
default:
|
||||
I_Error("viewcontext value is invalid: we should never get here without an assert!!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
58
src/r_fps.h
Normal file
58
src/r_fps.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze, Andrey Budko (prboom)
|
||||
// Copyright (C) 1999-2019 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file r_fps.h
|
||||
/// \brief Uncapped framerate stuff.
|
||||
|
||||
#ifndef __R_FPS_H__
|
||||
#define __R_FPS_H__
|
||||
|
||||
#include "m_fixed.h"
|
||||
#include "p_local.h"
|
||||
#include "r_state.h"
|
||||
|
||||
enum viewcontext_e
|
||||
{
|
||||
VIEWCONTEXT_PLAYER1 = 0,
|
||||
VIEWCONTEXT_PLAYER2,
|
||||
VIEWCONTEXT_PLAYER3,
|
||||
VIEWCONTEXT_PLAYER4,
|
||||
VIEWCONTEXT_SKY1,
|
||||
VIEWCONTEXT_SKY2,
|
||||
VIEWCONTEXT_SKY3,
|
||||
VIEWCONTEXT_SKY4
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
fixed_t z;
|
||||
boolean sky;
|
||||
sector_t *sector;
|
||||
player_t *player;
|
||||
|
||||
angle_t angle;
|
||||
angle_t aim;
|
||||
fixed_t cos;
|
||||
fixed_t sin;
|
||||
mobj_t *mobj;
|
||||
} viewvars_t;
|
||||
|
||||
extern viewvars_t *newview;
|
||||
|
||||
// Interpolates the current view variables (r_state.h) against the selected view context in R_SetViewContext
|
||||
void R_InterpolateView(fixed_t frac);
|
||||
// Buffer the current new views into the old views. Call once after each real tic.
|
||||
void R_UpdateViewInterpolation(void);
|
||||
// Set the current view context (the viewvars pointed to by newview)
|
||||
void R_SetViewContext(enum viewcontext_e _viewcontext);
|
||||
|
||||
#endif
|
||||
168
src/r_main.c
168
src/r_main.c
|
|
@ -36,6 +36,7 @@
|
|||
#include "r_main.h"
|
||||
#include "i_system.h" // I_GetPreciseTime
|
||||
#include "doomstat.h" // MAXSPLITSCREENPLAYERS
|
||||
#include "r_fps.h" // Frame interpolation/uncapped
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
|
|
@ -79,6 +80,9 @@ mobj_t *r_viewmobj;
|
|||
|
||||
int r_splitscreen;
|
||||
|
||||
fixed_t rendertimefrac;
|
||||
fixed_t renderdeltatics;
|
||||
|
||||
//
|
||||
// precalculated math tables
|
||||
//
|
||||
|
|
@ -100,6 +104,9 @@ lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
|
|||
lighttable_t *scalelightfixed[MAXLIGHTSCALE];
|
||||
lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
|
||||
|
||||
// Frame interpolation/uncapped
|
||||
tic_t prev_tics;
|
||||
|
||||
// Hack to support extra boom colormaps.
|
||||
extracolormap_t *extra_colormaps = NULL;
|
||||
|
||||
|
|
@ -172,6 +179,9 @@ consvar_t cv_fov[MAXSPLITSCREENPLAYERS] = {
|
|||
CVAR_INIT ("fov4", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange)
|
||||
};
|
||||
|
||||
// Frame interpolation/uncapped
|
||||
consvar_t cv_frameinterpolation = CVAR_INIT ("frameinterpolation", "On", CV_SAVE, CV_OnOff, NULL);
|
||||
|
||||
// Okay, whoever said homremoval causes a performance hit should be shot.
|
||||
consvar_t cv_homremoval = CVAR_INIT ("homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL);
|
||||
|
||||
|
|
@ -1193,40 +1203,6 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y)
|
|||
// R_SetupFrame
|
||||
//
|
||||
|
||||
// recalc necessary stuff for mouseaiming
|
||||
// slopes are already calculated for the full possible view (which is 4*viewheight).
|
||||
// 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out)
|
||||
static void R_SetupFreelook(player_t *player, boolean skybox)
|
||||
{
|
||||
#ifndef HWRENDER
|
||||
(void)player;
|
||||
(void)skybox;
|
||||
#endif
|
||||
|
||||
// clip it in the case we are looking a hardware 90 degrees full aiming
|
||||
// (lmps, network and use F12...)
|
||||
if (rendermode == render_soft
|
||||
#ifdef HWRENDER
|
||||
|| (rendermode == render_opengl
|
||||
&& (cv_glshearing.value == 1
|
||||
|| (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox))))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
|
||||
}
|
||||
|
||||
centeryfrac = (viewheight/2)<<FRACBITS;
|
||||
|
||||
if (rendermode == render_soft)
|
||||
centeryfrac += FixedMul(AIMINGTODY(aimingangle), FixedDiv(viewwidth<<FRACBITS, BASEVIDWIDTH<<FRACBITS));
|
||||
|
||||
centery = FixedInt(FixedRound(centeryfrac));
|
||||
|
||||
if (rendermode == render_soft)
|
||||
yslope = &yslopetab[viewssnum][viewheight*8 - centery];
|
||||
}
|
||||
|
||||
void R_SetupFrame(player_t *player)
|
||||
{
|
||||
camera_t *thiscam = &camera[0];
|
||||
|
|
@ -1239,6 +1215,7 @@ void R_SetupFrame(player_t *player)
|
|||
{
|
||||
thiscam = &camera[i];
|
||||
chasecam = (cv_chasecam[i].value != 0);
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER1 + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1257,73 +1234,75 @@ void R_SetupFrame(player_t *player)
|
|||
else if (!chasecam)
|
||||
thiscam->chase = false;
|
||||
|
||||
newview->sky = false;
|
||||
|
||||
if (player->awayviewtics)
|
||||
{
|
||||
// cut-away view stuff
|
||||
r_viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN
|
||||
I_Assert(r_viewmobj != NULL);
|
||||
viewz = r_viewmobj->z + 20*FRACUNIT;
|
||||
aimingangle = player->awayviewaiming;
|
||||
viewangle = r_viewmobj->angle;
|
||||
newview->z = r_viewmobj->z + 20*FRACUNIT;
|
||||
newview->aim = player->awayviewaiming;
|
||||
newview->angle = r_viewmobj->angle;
|
||||
}
|
||||
else if (!player->spectator && chasecam)
|
||||
// use outside cam view
|
||||
{
|
||||
r_viewmobj = NULL;
|
||||
viewz = thiscam->z + (thiscam->height>>1);
|
||||
aimingangle = thiscam->aiming;
|
||||
viewangle = thiscam->angle;
|
||||
newview->z = thiscam->z + (thiscam->height>>1);
|
||||
newview->aim = thiscam->aiming;
|
||||
newview->angle = thiscam->angle;
|
||||
}
|
||||
else
|
||||
// use the player's eyes view
|
||||
{
|
||||
viewz = player->viewz;
|
||||
newview->z = player->viewz;
|
||||
|
||||
r_viewmobj = player->mo;
|
||||
I_Assert(r_viewmobj != NULL);
|
||||
|
||||
aimingangle = player->aiming;
|
||||
viewangle = r_viewmobj->angle;
|
||||
newview->aim = player->aiming;
|
||||
newview->angle = r_viewmobj->angle;
|
||||
|
||||
if (!demo.playback && player->playerstate != PST_DEAD)
|
||||
{
|
||||
viewangle = localangle[i]; // WARNING: camera uses this
|
||||
aimingangle = localaiming[i];
|
||||
newview->angle = localangle[i]; // WARNING: camera uses this
|
||||
newview->aim = localaiming[i];
|
||||
}
|
||||
}
|
||||
viewz += quake.z;
|
||||
newview->z += quake.z;
|
||||
|
||||
viewplayer = player;
|
||||
newview->player = player;
|
||||
|
||||
if (chasecam && !player->awayviewtics && !player->spectator)
|
||||
{
|
||||
viewx = thiscam->x;
|
||||
viewy = thiscam->y;
|
||||
viewx += quake.x;
|
||||
viewy += quake.y;
|
||||
newview->x = thiscam->x;
|
||||
newview->y = thiscam->y;
|
||||
newview->x += quake.x;
|
||||
newview->y += quake.y;
|
||||
|
||||
if (thiscam->subsector)
|
||||
viewsector = thiscam->subsector->sector;
|
||||
newview->sector = thiscam->subsector->sector;
|
||||
else
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewx = r_viewmobj->x;
|
||||
viewy = r_viewmobj->y;
|
||||
viewx += quake.x;
|
||||
viewy += quake.y;
|
||||
newview->x = r_viewmobj->x;
|
||||
newview->y = r_viewmobj->y;
|
||||
newview->x += quake.x;
|
||||
newview->y += quake.y;
|
||||
|
||||
if (r_viewmobj->subsector)
|
||||
viewsector = r_viewmobj->subsector->sector;
|
||||
newview->sector = r_viewmobj->subsector->sector;
|
||||
else
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
|
||||
}
|
||||
|
||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
// newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
// newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
|
||||
R_SetupFreelook(player, false);
|
||||
R_InterpolateView(cv_frameinterpolation.value == 1 ? rendertimefrac : FRACUNIT);
|
||||
}
|
||||
|
||||
void R_SkyboxFrame(player_t *player)
|
||||
|
|
@ -1338,6 +1317,7 @@ void R_SkyboxFrame(player_t *player)
|
|||
if (player == &players[displayplayers[i]])
|
||||
{
|
||||
thiscam = &camera[i];
|
||||
R_SetViewContext(VIEWCONTEXT_SKY1 + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1349,6 +1329,7 @@ void R_SkyboxFrame(player_t *player)
|
|||
}
|
||||
|
||||
// cut-away view stuff
|
||||
newview->sky = true;
|
||||
r_viewmobj = skyboxmo[0];
|
||||
#ifdef PARANOIA
|
||||
if (!r_viewmobj)
|
||||
|
|
@ -1359,31 +1340,31 @@ void R_SkyboxFrame(player_t *player)
|
|||
#endif
|
||||
if (player->awayviewtics)
|
||||
{
|
||||
aimingangle = player->awayviewaiming;
|
||||
viewangle = player->awayviewmobj->angle;
|
||||
newview->aim = player->awayviewaiming;
|
||||
newview->angle = player->awayviewmobj->angle;
|
||||
}
|
||||
else if (thiscam->chase)
|
||||
{
|
||||
aimingangle = thiscam->aiming;
|
||||
viewangle = thiscam->angle;
|
||||
newview->aim = thiscam->aiming;
|
||||
newview->angle = thiscam->angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
aimingangle = player->aiming;
|
||||
viewangle = player->mo->angle;
|
||||
newview->aim = player->aiming;
|
||||
newview->angle = player->mo->angle;
|
||||
if (/*!demo.playback && */player->playerstate != PST_DEAD)
|
||||
{
|
||||
viewangle = localangle[i];
|
||||
aimingangle = localaiming[i];
|
||||
newview->angle = localangle[i];
|
||||
newview->aim = localaiming[i];
|
||||
}
|
||||
}
|
||||
viewangle += r_viewmobj->angle;
|
||||
newview->angle += r_viewmobj->angle;
|
||||
|
||||
viewplayer = player;
|
||||
newview->player = player;
|
||||
|
||||
viewx = r_viewmobj->x;
|
||||
viewy = r_viewmobj->y;
|
||||
viewz = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
|
||||
newview->x = r_viewmobj->x;
|
||||
newview->y = r_viewmobj->y;
|
||||
newview->z = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
|
||||
|
||||
if (mapheaderinfo[gamemap-1])
|
||||
{
|
||||
|
|
@ -1425,46 +1406,46 @@ void R_SkyboxFrame(player_t *player)
|
|||
|
||||
if (r_viewmobj->angle == 0)
|
||||
{
|
||||
viewx += x;
|
||||
viewy += y;
|
||||
newview->x += x;
|
||||
newview->y += y;
|
||||
}
|
||||
else if (r_viewmobj->angle == ANGLE_90)
|
||||
{
|
||||
viewx -= y;
|
||||
viewy += x;
|
||||
newview->x -= y;
|
||||
newview->y += x;
|
||||
}
|
||||
else if (r_viewmobj->angle == ANGLE_180)
|
||||
{
|
||||
viewx -= x;
|
||||
viewy -= y;
|
||||
newview->x -= x;
|
||||
newview->y -= y;
|
||||
}
|
||||
else if (r_viewmobj->angle == ANGLE_270)
|
||||
{
|
||||
viewx += y;
|
||||
viewy -= x;
|
||||
newview->x += y;
|
||||
newview->y -= x;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle_t ang = r_viewmobj->angle>>ANGLETOFINESHIFT;
|
||||
viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||
viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
||||
newview->x += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||
newview->y += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
||||
}
|
||||
}
|
||||
if (mh->skybox_scalez > 0)
|
||||
viewz += campos.z / mh->skybox_scalez;
|
||||
newview->z += campos.z / mh->skybox_scalez;
|
||||
else if (mh->skybox_scalez < 0)
|
||||
viewz += campos.z * -mh->skybox_scalez;
|
||||
newview->z += campos.z * -mh->skybox_scalez;
|
||||
}
|
||||
|
||||
if (r_viewmobj->subsector)
|
||||
viewsector = r_viewmobj->subsector->sector;
|
||||
newview->sector = r_viewmobj->subsector->sector;
|
||||
else
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
|
||||
|
||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
// newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
// newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
|
||||
R_SetupFreelook(player, true);
|
||||
R_InterpolateView(cv_frameinterpolation.value == 1 ? rendertimefrac : FRACUNIT);
|
||||
}
|
||||
|
||||
boolean R_ViewpointHasChasecam(player_t *player)
|
||||
|
|
@ -1737,4 +1718,7 @@ void R_RegisterEngineStuff(void)
|
|||
CV_RegisterVar(&cv_maxportals);
|
||||
|
||||
CV_RegisterVar(&cv_movebob);
|
||||
|
||||
// Frame interpolation/uncapped
|
||||
CV_RegisterVar(&cv_frameinterpolation);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@ extern fixed_t fovtan[MAXSPLITSCREENPLAYERS];
|
|||
|
||||
extern size_t validcount, linecount, loopcount, framecount;
|
||||
|
||||
// The fraction of a tic being drawn (for interpolation between two tics)
|
||||
extern fixed_t rendertimefrac;
|
||||
// Evaluated delta tics for this frame (how many tics since the last frame)
|
||||
extern fixed_t renderdeltatics;;
|
||||
|
||||
//
|
||||
// Lighting LUT.
|
||||
// Used for z-depth cuing per column/row,
|
||||
|
|
@ -111,6 +116,10 @@ extern consvar_t cv_fov[MAXSPLITSCREENPLAYERS];
|
|||
extern consvar_t cv_skybox;
|
||||
extern consvar_t cv_tailspickup;
|
||||
|
||||
// Frame interpolation (uncapped framerate)
|
||||
extern tic_t prev_tics;
|
||||
extern consvar_t cv_frameinterpolation;
|
||||
|
||||
// Called by startup code.
|
||||
void R_Init(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
return;
|
||||
|
||||
transtable = R_GetLinedefTransTable(ldef);
|
||||
if (ldef->special == 910)
|
||||
if (ldef->special == 910 || P_IsLineTripWire(ldef))
|
||||
{
|
||||
if (transtable == NUMTRANSMAPS)
|
||||
transtable = 0;
|
||||
|
|
|
|||
135
src/r_things.c
135
src/r_things.c
|
|
@ -1361,16 +1361,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
//
|
||||
static void R_ProjectSprite(mobj_t *thing)
|
||||
{
|
||||
fixed_t thingxpos = thing->x + thing->sprxoff;
|
||||
fixed_t thingypos = thing->y + thing->spryoff;
|
||||
fixed_t thingzpos = thing->z + thing->sprzoff;
|
||||
|
||||
mobj_t *oldthing = thing;
|
||||
|
||||
//const fixed_t oldthingxpos = oldthing->x + oldthing->sprxoff;
|
||||
//const fixed_t oldthingypos = oldthing->y + oldthing->spryoff;
|
||||
const fixed_t oldthingzpos = oldthing->z + oldthing->sprzoff;
|
||||
|
||||
fixed_t tr_x, tr_y;
|
||||
fixed_t tx, tz;
|
||||
fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!!
|
||||
|
|
@ -1435,7 +1427,32 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
angle_t spriterotangle = 0;
|
||||
#endif
|
||||
|
||||
// hitlag vibrating
|
||||
// uncapped/interpolation
|
||||
fixed_t interpx = thing->x;
|
||||
fixed_t interpy = thing->y;
|
||||
fixed_t interpz = thing->z;
|
||||
angle_t interpangle = thing->angle;
|
||||
|
||||
// use player drawangle if player
|
||||
if (thing->player) interpangle = thing->player->drawangle;
|
||||
|
||||
// do interpolation
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x);
|
||||
interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y);
|
||||
interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z);
|
||||
if (thing->player)
|
||||
{
|
||||
interpangle = thing->player->drawangle;
|
||||
}
|
||||
else
|
||||
{
|
||||
interpangle = thing->angle;
|
||||
}
|
||||
}
|
||||
|
||||
// hitlag vibrating (todo: interp somehow?)
|
||||
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
|
||||
{
|
||||
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
|
||||
|
|
@ -1445,14 +1462,19 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
mul = -mul;
|
||||
}
|
||||
|
||||
thingxpos += FixedMul(thing->momx, mul);
|
||||
thingypos += FixedMul(thing->momy, mul);
|
||||
thingzpos += FixedMul(thing->momz, mul);
|
||||
interpx += FixedMul(thing->momx, mul);
|
||||
interpy += FixedMul(thing->momy, mul);
|
||||
interpz += FixedMul(thing->momz, mul);
|
||||
}
|
||||
|
||||
// sprite offset
|
||||
interpx += thing->sprxoff;
|
||||
interpy += thing->spryoff;
|
||||
interpz += thing->sprzoff;
|
||||
|
||||
// transform the origin point
|
||||
tr_x = thingxpos - viewx;
|
||||
tr_y = thingypos - viewy;
|
||||
tr_x = interpx - viewx;
|
||||
tr_y = interpy - viewy;
|
||||
|
||||
basetz = tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
|
||||
|
||||
|
|
@ -1529,7 +1551,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (sprframe->rotate != SRF_SINGLE || papersprite)
|
||||
{
|
||||
ang = R_PointToAngle (thingxpos, thingypos) - (thing->player ? thing->player->drawangle : thing->angle);
|
||||
ang = R_PointToAngle (interpx, interpy) - interpangle;
|
||||
if (mirrored)
|
||||
ang = InvAngle(ang);
|
||||
}
|
||||
|
|
@ -1544,7 +1566,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
else
|
||||
{
|
||||
// choose a different rotation based on player view
|
||||
//ang = R_PointToAngle (thingxpos, thingypos) - thing->angle;
|
||||
//ang = R_PointToAngle (interpx, interpy) - interpangle;
|
||||
|
||||
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
||||
rot = 6; // F7 slot
|
||||
|
|
@ -1755,12 +1777,37 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
fixed_t linkscale;
|
||||
|
||||
thing = thing->tracer;
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
interpx = thing->old_x + FixedMul(thing->x - thing->old_x, rendertimefrac);
|
||||
interpy = thing->old_y + FixedMul(thing->y - thing->old_y, rendertimefrac);
|
||||
}
|
||||
|
||||
// hitlag vibrating (todo: interp somehow?)
|
||||
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
|
||||
{
|
||||
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
|
||||
|
||||
if (leveltime & 1)
|
||||
{
|
||||
mul = -mul;
|
||||
}
|
||||
|
||||
interpx += FixedMul(thing->momx, mul);
|
||||
interpy += FixedMul(thing->momy, mul);
|
||||
interpz += FixedMul(thing->momz, mul);
|
||||
}
|
||||
|
||||
// sprite offset
|
||||
interpx += thing->sprxoff;
|
||||
interpy += thing->spryoff;
|
||||
interpz += thing->sprzoff;
|
||||
|
||||
if (! R_ThingVisible(thing))
|
||||
return;
|
||||
|
||||
tr_x = (thingxpos + sort_x) - viewx;
|
||||
tr_y = (thingypos + sort_y) - viewy;
|
||||
tr_x = (interpx + sort_x) - viewx;
|
||||
tr_y = (interpy + sort_y) - viewy;
|
||||
tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
|
||||
linkscale = FixedDiv(projectiony[viewssnum], tz);
|
||||
|
||||
|
|
@ -1775,8 +1822,8 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
}
|
||||
else if (splat)
|
||||
{
|
||||
tr_x = (thingxpos + sort_x) - viewx;
|
||||
tr_y = (thingypos + sort_y) - viewy;
|
||||
tr_x = (interpx + sort_x) - viewx;
|
||||
tr_y = (interpy + sort_y) - viewy;
|
||||
sort_z = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
|
||||
sortscale = FixedDiv(projectiony[viewssnum], sort_z);
|
||||
}
|
||||
|
|
@ -1796,7 +1843,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (x2 < portalclipstart || x1 >= portalclipend)
|
||||
return;
|
||||
|
||||
if (P_PointOnLineSide(thingxpos, thingypos, portalclipline) != 0)
|
||||
if (P_PointOnLineSide(interpx, interpy, portalclipline) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1865,12 +1912,12 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
// When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned.
|
||||
// sprite height - sprite topoffset is the proper inverse of the vertical offset, of course.
|
||||
// remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes!
|
||||
gz = oldthingzpos + oldthing->height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
|
||||
gz = interpz + oldthing->height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
|
||||
gzt = gz + FixedMul(spr_height, FixedMul(spriteyscale, this_scale));
|
||||
}
|
||||
else
|
||||
{
|
||||
gzt = oldthingzpos + FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
|
||||
gzt = interpz + FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
|
||||
gz = gzt - FixedMul(spr_height, FixedMul(spriteyscale, this_scale));
|
||||
}
|
||||
}
|
||||
|
|
@ -1889,7 +1936,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
// R_GetPlaneLight won't work on sloped lights!
|
||||
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
|
||||
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], thingxpos, thingypos);
|
||||
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], interpx, interpy);
|
||||
if (h <= top) {
|
||||
light = lightnum - 1;
|
||||
break;
|
||||
|
|
@ -1907,7 +1954,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
}
|
||||
|
||||
heightsec = thing->subsector->sector->heightsec;
|
||||
if (viewplayer->mo && viewplayer->mo->subsector)
|
||||
if (viewplayer && viewplayer->mo && viewplayer->mo->subsector)
|
||||
phs = viewplayer->mo->subsector->sector->heightsec;
|
||||
else
|
||||
phs = -1;
|
||||
|
|
@ -1915,12 +1962,12 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
|
||||
{
|
||||
if (viewz < sectors[phs].floorheight ?
|
||||
thingzpos >= sectors[heightsec].floorheight :
|
||||
interpz >= sectors[heightsec].floorheight :
|
||||
gzt < sectors[heightsec].floorheight)
|
||||
return;
|
||||
if (viewz > sectors[phs].ceilingheight ?
|
||||
gzt < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight :
|
||||
thingzpos >= sectors[heightsec].ceilingheight)
|
||||
interpz >= sectors[heightsec].ceilingheight)
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1933,12 +1980,12 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->sortscale = sortscale;
|
||||
vis->sortsplat = sortsplat;
|
||||
vis->dispoffset = dispoffset; // Monster Iestyn: 23/11/15
|
||||
vis->gx = thingxpos;
|
||||
vis->gy = thingypos;
|
||||
vis->gx = interpx;
|
||||
vis->gy = interpy;
|
||||
vis->gz = gz;
|
||||
vis->gzt = gzt;
|
||||
vis->thingheight = thing->height;
|
||||
vis->pz = thingzpos;
|
||||
vis->pz = interpz;
|
||||
vis->pzt = vis->pz + vis->thingheight;
|
||||
vis->texturemid = FixedDiv(gzt - viewz, spriteyscale);
|
||||
vis->scalestep = scalestep;
|
||||
|
|
@ -2073,9 +2120,22 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
//SoM: 3/17/2000
|
||||
fixed_t gz, gzt;
|
||||
|
||||
// uncapped/interpolation
|
||||
fixed_t interpx = thing->x;
|
||||
fixed_t interpy = thing->y;
|
||||
fixed_t interpz = thing->z;
|
||||
|
||||
// do interpolation
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x);
|
||||
interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y);
|
||||
interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z);
|
||||
}
|
||||
|
||||
// transform the origin point
|
||||
tr_x = thing->x - viewx;
|
||||
tr_y = thing->y - viewy;
|
||||
tr_x = interpx - viewx;
|
||||
tr_y = interpy - viewy;
|
||||
|
||||
tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
|
||||
|
||||
|
|
@ -2139,12 +2199,12 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
if (x2 < portalclipstart || x1 >= portalclipend)
|
||||
return;
|
||||
|
||||
if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0)
|
||||
if (P_PointOnLineSide(interpx, interpy, portalclipline) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
//SoM: 3/17/2000: Disregard sprites that are out of view..
|
||||
gzt = thing->z + spritecachedinfo[lump].topoffset;
|
||||
gzt = interpz + spritecachedinfo[lump].topoffset;
|
||||
gz = gzt - spritecachedinfo[lump].height;
|
||||
|
||||
if (thing->subsector->sector->cullheight)
|
||||
|
|
@ -2157,10 +2217,13 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
vis = R_NewVisSprite();
|
||||
vis->scale = vis->sortscale = yscale; //<<detailshift;
|
||||
vis->dispoffset = 0; // Monster Iestyn: 23/11/15
|
||||
vis->gx = thing->x;
|
||||
vis->gy = thing->y;
|
||||
vis->gx = interpx;
|
||||
vis->gy = interpy;
|
||||
vis->gz = gz;
|
||||
vis->gzt = gzt;
|
||||
vis->thingheight = 4*FRACUNIT;
|
||||
vis->pz = interpz;
|
||||
vis->pzt = vis->pz + vis->thingheight;
|
||||
vis->texturemid = vis->gzt - viewz;
|
||||
vis->scalestep = 0;
|
||||
vis->paperdistance = 0;
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ static char returnWadPath[256];
|
|||
|
||||
#include "../m_argv.h"
|
||||
|
||||
#include "../m_menu.h"
|
||||
#include "../r_main.h" // Frame interpolation/uncapped
|
||||
|
||||
#ifdef MAC_ALERT
|
||||
#include "macosx/mac_alert.h"
|
||||
|
|
@ -1640,17 +1640,29 @@ static Uint64 timer_frequency;
|
|||
|
||||
static double tic_frequency;
|
||||
static Uint64 tic_epoch;
|
||||
static double elapsed_tics;
|
||||
|
||||
static void UpdateElapsedTics(void)
|
||||
{
|
||||
const Uint64 now = SDL_GetPerformanceCounter();
|
||||
|
||||
elapsed_tics += (now - tic_epoch) / tic_frequency;
|
||||
tic_epoch = now; // moving epoch
|
||||
}
|
||||
|
||||
tic_t I_GetTime(void)
|
||||
{
|
||||
static double elapsed;
|
||||
double f = 0.0;
|
||||
UpdateElapsedTics();
|
||||
f = floor(elapsed_tics);
|
||||
return (tic_t)f;
|
||||
}
|
||||
|
||||
const Uint64 now = SDL_GetPerformanceCounter();
|
||||
|
||||
elapsed += (now - tic_epoch) / tic_frequency;
|
||||
tic_epoch = now; // moving epoch
|
||||
|
||||
return (tic_t)elapsed;
|
||||
fixed_t I_GetTimeFrac(void)
|
||||
{
|
||||
UpdateElapsedTics();
|
||||
|
||||
return FLOAT_TO_FIXED((float) (elapsed_tics - floor(elapsed_tics)));
|
||||
}
|
||||
|
||||
precise_t I_GetPreciseTime(void)
|
||||
|
|
@ -1672,6 +1684,7 @@ void I_StartupTimer(void)
|
|||
tic_epoch = SDL_GetPerformanceCounter();
|
||||
|
||||
tic_frequency = timer_frequency / (double)NEWTICRATE;
|
||||
elapsed_tics = 0.0;
|
||||
}
|
||||
|
||||
void I_Sleep(void)
|
||||
|
|
|
|||
|
|
@ -1260,6 +1260,7 @@ void ST_Drawer(void)
|
|||
if (rendermode != render_none) ST_doPaletteStuff();
|
||||
|
||||
{
|
||||
#if 0
|
||||
const tic_t length = TICRATE/2;
|
||||
|
||||
if (lt_exitticker)
|
||||
|
|
@ -1270,6 +1271,9 @@ void ST_Drawer(void)
|
|||
}
|
||||
else
|
||||
st_translucency = 0;
|
||||
#else
|
||||
st_translucency = cv_translucenthud.value;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Check for a valid level title
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include "../d_main.h"
|
||||
|
||||
#include "../m_argv.h"
|
||||
#include "../m_fixed.h"
|
||||
|
||||
#include "../w_wad.h"
|
||||
#include "../z_zone.h"
|
||||
|
|
@ -261,6 +262,11 @@ tic_t I_GetTime(void)
|
|||
return newtics;
|
||||
}
|
||||
|
||||
fixed_t I_GetTimeFrac(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void I_Sleep(void)
|
||||
{
|
||||
if (cv_sleep.value > 0)
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ void Y_IntermissionDrawer(void)
|
|||
else
|
||||
hilicol = ((intertype == int_race) ? V_SKYMAP : V_REDMAP);
|
||||
|
||||
if (sorttic != -1 && intertic > sorttic && !demo.playback)
|
||||
if (sorttic != -1 && intertic > sorttic && multiplayer)
|
||||
{
|
||||
INT32 count = (intertic - sorttic);
|
||||
|
||||
|
|
@ -586,7 +586,7 @@ void Y_IntermissionDrawer(void)
|
|||
|
||||
y2 = y;
|
||||
|
||||
if (netgame && playerconsole[data.num[i]] == 0 && server_lagless && !players[data.num[i]].bot)
|
||||
if ((netgame || (demo.playback && demo.netgame)) && playerconsole[data.num[i]] == 0 && server_lagless && !players[data.num[i]].bot)
|
||||
{
|
||||
static int alagles_timer = 0;
|
||||
patch_t *alagles;
|
||||
|
|
@ -799,7 +799,7 @@ void Y_Ticker(void)
|
|||
|
||||
if (intertype == int_race || intertype == int_battle)
|
||||
{
|
||||
if (!(multiplayer && demo.playback)) // Don't advance to rankings in replays
|
||||
//if (!(multiplayer && demo.playback)) // Don't advance to rankings in replays
|
||||
{
|
||||
if (!data.rankingsmode && (intertic >= sorttic + 8))
|
||||
{
|
||||
|
|
@ -868,8 +868,6 @@ void Y_Ticker(void)
|
|||
endtic = intertic + 3*TICRATE; // 3 second pause after end of tally
|
||||
}
|
||||
}
|
||||
else if (!(intertic & 1))
|
||||
S_StartSound(NULL, sfx_ptally); // tally sound effect
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1013,7 +1011,7 @@ static void K_UpdatePowerLevels(void)
|
|||
data.increase[i] = increment[i];
|
||||
clientpowerlevels[i][powertype] += data.increase[i];
|
||||
|
||||
if (i == consoleplayer)
|
||||
if (!demo.playback && i == consoleplayer)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Player %d is you! Saving...\n", i);
|
||||
vspowerlevel[powertype] = clientpowerlevels[i][powertype];
|
||||
|
|
@ -1069,7 +1067,7 @@ void Y_StartIntermission(void)
|
|||
{
|
||||
if (cv_inttime.value == 0)
|
||||
timer = 0;
|
||||
else if (demo.playback) // Override inttime (which is pulled from the replay anyway
|
||||
else if (demo.playback && !multiplayer) // Override inttime (which is pulled from the replay anyway
|
||||
timer = 10*TICRATE;
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue