mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'master' of https://git.do.srb2.org/KartKrew/Kart.git into new-menus
# Conflicts: # src/Sourcefile # src/d_main.c # src/m_menu.c # src/v_video.c # src/v_video.h
This commit is contained in:
commit
87d797a45a
83 changed files with 4401 additions and 982 deletions
|
|
@ -6,7 +6,7 @@ passthru_opts+=\
|
|||
NONET NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\
|
||||
MOBJCONSISTANCY PACKETDROP ZDEBUG\
|
||||
HAVE_MINIUPNPC\
|
||||
HAVE_DISCORDRPC TESTERS DEVELOP
|
||||
HAVE_DISCORDRPC TESTERS HOSTTESTERS DEVELOP
|
||||
|
||||
# build with debugging information
|
||||
ifdef DEBUGMODE
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@ else
|
|||
EXENAME?=srb2kart64.exe
|
||||
endif
|
||||
|
||||
# disable dynamicbase if under msys2
|
||||
ifdef MSYSTEM
|
||||
libs+=-Wl,--disable-dynamicbase
|
||||
endif
|
||||
|
||||
sources+=win32/Srb2win.rc
|
||||
opts+=-DSTDC_HEADERS
|
||||
libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32
|
||||
|
|
|
|||
|
|
@ -113,4 +113,6 @@ k_hud.c
|
|||
k_menudef.c
|
||||
k_menufunc.c
|
||||
k_menudraw.c
|
||||
k_terrain.c
|
||||
k_brightmap.c
|
||||
k_director.c
|
||||
|
|
@ -5256,8 +5256,10 @@ static void SV_Maketic(void)
|
|||
maketic++;
|
||||
}
|
||||
|
||||
void TryRunTics(tic_t realtics)
|
||||
boolean TryRunTics(tic_t realtics)
|
||||
{
|
||||
boolean ticking;
|
||||
|
||||
// the machine has lagged but it is not so bad
|
||||
if (realtics > TICRATE/7) // FIXME: consistency failure!!
|
||||
{
|
||||
|
|
@ -5301,7 +5303,9 @@ void TryRunTics(tic_t realtics)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (neededtic > gametic)
|
||||
ticking = neededtic > gametic;
|
||||
|
||||
if (ticking)
|
||||
{
|
||||
if (realtics)
|
||||
hu_stopped = false;
|
||||
|
|
@ -5311,10 +5315,10 @@ void TryRunTics(tic_t realtics)
|
|||
{
|
||||
if (realtics)
|
||||
hu_stopped = true;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (neededtic > gametic)
|
||||
if (ticking)
|
||||
{
|
||||
if (advancedemo)
|
||||
{
|
||||
|
|
@ -5351,6 +5355,8 @@ void TryRunTics(tic_t realtics)
|
|||
if (realtics)
|
||||
hu_stopped = true;
|
||||
}
|
||||
|
||||
return ticking;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -488,7 +488,7 @@ boolean Playing(void);
|
|||
void D_QuitNetGame(void);
|
||||
|
||||
//? How many ticks to run?
|
||||
void TryRunTics(tic_t realtic);
|
||||
boolean TryRunTics(tic_t realtic);
|
||||
|
||||
// extra data for lmps
|
||||
// these functions scare me. they contain magic.
|
||||
|
|
|
|||
62
src/d_main.c
62
src/d_main.c
|
|
@ -295,6 +295,8 @@ static void D_Display(void)
|
|||
{
|
||||
for (i = 0; i <= r_splitscreen; ++i)
|
||||
{
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER1 + i);
|
||||
R_InterpolateViewRollAngle(rendertimefrac);
|
||||
R_CheckViewMorph(i);
|
||||
}
|
||||
}
|
||||
|
|
@ -686,6 +688,7 @@ tic_t rendergametic;
|
|||
void D_SRB2Loop(void)
|
||||
{
|
||||
tic_t oldentertics = 0, entertic = 0, realtics = 0, rendertimeout = INFTICS;
|
||||
boolean ticked;
|
||||
|
||||
if (dedicated)
|
||||
server = true;
|
||||
|
|
@ -773,11 +776,23 @@ void D_SRB2Loop(void)
|
|||
realtics = 1;
|
||||
|
||||
// process tics (but maybe not if realtic == 0)
|
||||
TryRunTics(realtics);
|
||||
ticked = TryRunTics(realtics);
|
||||
|
||||
if (cv_frameinterpolation.value == 1 && !(paused || P_AutoPause() || hu_stopped))
|
||||
if (cv_frameinterpolation.value == 1 && !(paused || P_AutoPause()))
|
||||
{
|
||||
fixed_t entertimefrac = I_GetTimeFrac();
|
||||
static float tictime;
|
||||
float entertime = I_GetTimeFrac();
|
||||
|
||||
fixed_t entertimefrac;
|
||||
|
||||
if (ticked)
|
||||
tictime = entertime;
|
||||
|
||||
if (aproxfps < 35.0)
|
||||
entertimefrac = FRACUNIT;
|
||||
else
|
||||
entertimefrac = FLOAT_TO_FIXED(entertime - tictime);
|
||||
|
||||
// renderdeltatics is a bit awkard to evaluate, since the system time interface is whole tic-based
|
||||
renderdeltatics = realtics * FRACUNIT;
|
||||
if (entertimefrac > rendertimefrac)
|
||||
|
|
@ -1065,17 +1080,39 @@ static void IdentifyVersion(void)
|
|||
// if you change the ordering of this or add/remove a file, be sure to update the md5
|
||||
// checking in D_SRB2Main
|
||||
|
||||
#if defined (TESTERS) || defined (HOSTTESTERS)
|
||||
////
|
||||
#define TEXTURESNAME "MISC_TEXTURES.pk3"
|
||||
#define MAPSNAME "MISC_MAPS.pk3"
|
||||
#define PATCHNAME "MISC_PATCH.pk3"
|
||||
#define MUSICNAME "MISC_MUSIC.PK3"
|
||||
////
|
||||
#else
|
||||
////
|
||||
#define TEXTURESNAME "textures.pk3"
|
||||
#define MAPSNAME "maps.pk3"
|
||||
#define PATCHNAME "patch.pk3"
|
||||
#define MUSICNAME "music.pk3"
|
||||
////
|
||||
#endif
|
||||
////
|
||||
#if !defined (TESTERS) && !defined (HOSTTESTERS)
|
||||
D_AddFile(startupiwads, va(pandf,srb2waddir,"gfx.pk3"));
|
||||
D_AddFile(startupiwads, va(pandf,srb2waddir,"textures.pk3"));
|
||||
#endif
|
||||
D_AddFile(startupiwads, va(pandf,srb2waddir,TEXTURESNAME));
|
||||
D_AddFile(startupiwads, va(pandf,srb2waddir,"chars.pk3"));
|
||||
D_AddFile(startupiwads, va(pandf,srb2waddir,"maps.pk3"));
|
||||
|
||||
D_AddFile(startupiwads, va(pandf,srb2waddir,MAPSNAME));
|
||||
D_AddFile(startupiwads, va(pandf,srb2waddir,"followers.pk3"));
|
||||
#ifdef USE_PATCH_FILE
|
||||
D_AddFile(startupiwads, va(pandf,srb2waddir,"patch.pk3"));
|
||||
|
||||
D_AddFile(startupiwads, va(pandf,srb2waddir,PATCHNAME));
|
||||
// SPECIFIC HACK TO NEW-MENUS SO THAT MY DUMBASS STOPS FORGETTING TO ADD THE FILE (rip :youfuckedup:)
|
||||
D_AddFile(startupiwads, va(pandf,srb2waddir,"newmenus.pk3"));
|
||||
#endif
|
||||
////
|
||||
#undef TEXTURESNAME
|
||||
#undef MAPSNAME
|
||||
#undef PATCHNAME
|
||||
|
||||
#if !defined (HAVE_SDL) || defined (HAVE_MIXER)
|
||||
|
||||
|
|
@ -1090,8 +1127,9 @@ static void IdentifyVersion(void)
|
|||
}
|
||||
|
||||
MUSICTEST("sounds.pk3")
|
||||
MUSICTEST("music.pk3")
|
||||
MUSICTEST(MUSICNAME)
|
||||
|
||||
#undef MUSICNAME
|
||||
#undef MUSICTEST
|
||||
|
||||
#endif
|
||||
|
|
@ -1264,6 +1302,7 @@ void D_SRB2Main(void)
|
|||
// Do this up here so that WADs loaded through the command line can use ExecCfg
|
||||
COM_Init();
|
||||
|
||||
#ifndef TESTERS
|
||||
// add any files specified on the command line with -file wadfile
|
||||
// to the wad list
|
||||
if (!((M_GetUrlProtocolArg() || M_CheckParm("-connect")) && !M_CheckParm("-server")))
|
||||
|
|
@ -1281,6 +1320,7 @@ void D_SRB2Main(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// get map from parms
|
||||
|
||||
|
|
@ -1315,14 +1355,18 @@ void D_SRB2Main(void)
|
|||
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_TEXTURES_PK3); // textures.pk3
|
||||
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_PK3); // chars.pk3
|
||||
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_PK3); // maps.pk3 -- 4 - If you touch this, make sure to touch up the majormods stuff below.
|
||||
mainwads++; W_VerifyFileMd5(mainwads, ASSET_HASH_FOLLOWERS_PK3); // followers.pk3
|
||||
#ifdef USE_PATCH_FILE
|
||||
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_PK3); // patch.pk3
|
||||
#endif
|
||||
#else
|
||||
#if !defined (TESTERS) && !defined (HOSTTESTERS)
|
||||
mainwads++; // gfx.pk3
|
||||
#endif
|
||||
mainwads++; // textures.pk3
|
||||
mainwads++; // chars.pk3
|
||||
mainwads++; // maps.pk3
|
||||
mainwads++; // followers.pk3
|
||||
|
||||
#ifdef USE_PATCH_FILE
|
||||
mainwads++; // patch.pk3
|
||||
|
|
@ -1335,7 +1379,7 @@ void D_SRB2Main(void)
|
|||
//
|
||||
// search for maps
|
||||
//
|
||||
for (wadnum = 4; wadnum < 6; wadnum++) // fucking arbitrary numbers
|
||||
for (wadnum = 0; wadnum <= mainwads; wadnum++)
|
||||
{
|
||||
lumpinfo = wadfiles[wadnum]->lumpinfo;
|
||||
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lumpinfo++)
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ consvar_t cv_kartencore = CVAR_INIT ("kartencore", "Auto", CV_NETVAR|CV_CALL|CV_
|
|||
static CV_PossibleValue_t kartvoterulechanges_cons_t[] = {{0, "Never"}, {1, "Sometimes"}, {2, "Frequent"}, {3, "Always"}, {0, NULL}};
|
||||
consvar_t cv_kartvoterulechanges = CVAR_INIT ("kartvoterulechanges", "Frequent", CV_NETVAR, kartvoterulechanges_cons_t, NULL);
|
||||
static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Percentage"}, {2, "Kilometers"}, {3, "Miles"}, {4, "Fracunits"}, {0, NULL}};
|
||||
consvar_t cv_kartspeedometer = CVAR_INIT ("kartdisplayspeed", "Off", CV_SAVE, kartspeedometer_cons_t, NULL); // use tics in display
|
||||
consvar_t cv_kartspeedometer = CVAR_INIT ("kartdisplayspeed", "Percentage", CV_SAVE, kartspeedometer_cons_t, NULL); // use tics in display
|
||||
static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}};
|
||||
consvar_t cv_kartvoices = CVAR_INIT ("kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL);
|
||||
|
||||
|
|
@ -423,7 +423,7 @@ consvar_t cv_kartallowgiveitem = CVAR_INIT ("kartallowgiveitem",
|
|||
#endif
|
||||
CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_YesNo, NULL
|
||||
);
|
||||
consvar_t cv_kartdebugshrink = CVAR_INIT ("kartdebugshrink", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
|
||||
consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}};
|
||||
|
|
@ -433,6 +433,7 @@ consvar_t cv_kartdebugbotpredict = CVAR_INIT ("kartdebugbotpredict", "Off", CV_N
|
|||
consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
consvar_t cv_kartdebugcolorize = CVAR_INIT ("kartdebugcolorize", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
consvar_t cv_kartdebugdirector = CVAR_INIT ("kartdebugdirector", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
|
||||
static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_votetime = CVAR_INIT ("votetime", "20", CV_NETVAR, votetime_cons_t, NULL);
|
||||
|
|
@ -509,6 +510,8 @@ static CV_PossibleValue_t perfstats_cons_t[] = {
|
|||
{0, "Off"}, {1, "Rendering"}, {2, "Logic"}, {3, "ThinkFrame"}, {0, NULL}};
|
||||
consvar_t cv_perfstats = CVAR_INIT ("perfstats", "Off", 0, perfstats_cons_t, NULL);
|
||||
|
||||
consvar_t cv_director = CVAR_INIT ("director", "Off", 0, CV_OnOff, NULL);
|
||||
|
||||
char timedemo_name[256];
|
||||
boolean timedemo_csv;
|
||||
char timedemo_csv_id[256];
|
||||
|
|
@ -735,6 +738,8 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_showping);
|
||||
CV_RegisterVar(&cv_showviewpointtext);
|
||||
|
||||
CV_RegisterVar(&cv_director);
|
||||
|
||||
CV_RegisterVar(&cv_dummyconsvar);
|
||||
|
||||
#ifdef USE_STUN
|
||||
|
|
@ -929,6 +934,7 @@ void D_RegisterClientCommands(void)
|
|||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
CV_RegisterVar(&cv_kickstartaccel[i]);
|
||||
CV_RegisterVar(&cv_shrinkme[i]);
|
||||
CV_RegisterVar(&cv_turnaxis[i]);
|
||||
CV_RegisterVar(&cv_moveaxis[i]);
|
||||
CV_RegisterVar(&cv_brakeaxis[i]);
|
||||
|
|
@ -1630,10 +1636,13 @@ void SendWeaponPref(UINT8 n)
|
|||
UINT8 buf[1];
|
||||
|
||||
buf[0] = 0;
|
||||
// Player option cvars that need to be synched go HERE
|
||||
|
||||
if (cv_kickstartaccel[n].value)
|
||||
buf[0] |= 1;
|
||||
|
||||
if (cv_shrinkme[n].value)
|
||||
buf[0] |= 2;
|
||||
|
||||
SendNetXCmdForPlayer(n, XD_WEAPONPREF, buf, 1);
|
||||
}
|
||||
|
||||
|
|
@ -1641,11 +1650,22 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum)
|
|||
{
|
||||
UINT8 prefs = READUINT8(*cp);
|
||||
|
||||
// Player option cvars that need to be synched go HERE
|
||||
players[playernum].pflags &= ~(PF_KICKSTARTACCEL);
|
||||
players[playernum].pflags &= ~(PF_KICKSTARTACCEL|PF_SHRINKME);
|
||||
|
||||
if (prefs & 1)
|
||||
players[playernum].pflags |= PF_KICKSTARTACCEL;
|
||||
|
||||
if (prefs & 2)
|
||||
players[playernum].pflags |= PF_SHRINKME;
|
||||
|
||||
if (leveltime < 2)
|
||||
{
|
||||
// BAD HACK: No other place I tried to slot this in
|
||||
// made it work for the host when they initally host,
|
||||
// so this will have to do.
|
||||
K_UpdateShrinkCheat(&players[playernum]);
|
||||
}
|
||||
|
||||
// SEE ALSO g_demo.c
|
||||
demo_extradata[playernum] |= DXD_WEAPONPREF;
|
||||
}
|
||||
|
|
@ -3558,7 +3578,10 @@ static void Command_Login_f(void)
|
|||
|
||||
boolean IsPlayerAdmin(INT32 playernum)
|
||||
{
|
||||
#ifdef DEVELOP
|
||||
#if defined (TESTERS) || defined (HOSTTESTERS)
|
||||
(void)playernum;
|
||||
return false;
|
||||
#elif defined (DEVELOP)
|
||||
return playernum != serverplayer;
|
||||
#else
|
||||
INT32 i;
|
||||
|
|
@ -3862,6 +3885,7 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum)
|
|||
*/
|
||||
static void Command_Addfile(void)
|
||||
{
|
||||
#ifndef TESTERS
|
||||
size_t argc = COM_Argc(); // amount of arguments total
|
||||
size_t curarg; // current argument index
|
||||
|
||||
|
|
@ -3991,6 +4015,7 @@ static void Command_Addfile(void)
|
|||
else
|
||||
SendNetXCmd(XD_ADDFILE, buf, buf_p - buf);
|
||||
}
|
||||
#endif/*TESTERS*/
|
||||
}
|
||||
|
||||
static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ extern consvar_t cv_kartusepwrlv;
|
|||
|
||||
extern consvar_t cv_votetime;
|
||||
|
||||
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
||||
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize;
|
||||
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
||||
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector;
|
||||
extern consvar_t cv_kartdebugwaypoints, cv_kartdebugbotpredict;
|
||||
|
||||
extern consvar_t cv_itemfinder;
|
||||
|
|
@ -113,6 +113,8 @@ extern consvar_t cv_sleep;
|
|||
|
||||
extern consvar_t cv_perfstats;
|
||||
|
||||
extern consvar_t cv_director;
|
||||
|
||||
extern char timedemo_name[256];
|
||||
extern boolean timedemo_csv;
|
||||
extern char timedemo_csv_id[256];
|
||||
|
|
|
|||
|
|
@ -459,7 +459,12 @@ INT32 CL_CheckFiles(void)
|
|||
if (modifiedgame)
|
||||
{
|
||||
CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n");
|
||||
for (i = 0, j = mainwads+1; i < fileneedednum || j < numwadfiles;)
|
||||
#ifdef DEVELOP
|
||||
j = 0;
|
||||
#else
|
||||
j = mainwads + 1;
|
||||
#endif
|
||||
for (i = 0; i < fileneedednum || j < numwadfiles;)
|
||||
{
|
||||
if (j < numwadfiles && !wadfiles[j]->important)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -59,10 +59,10 @@ typedef enum
|
|||
typedef enum
|
||||
{
|
||||
// True if button down last tic.
|
||||
PF_ATTACKDOWN = 1,
|
||||
PF_ACCELDOWN = 1<<1,
|
||||
PF_BRAKEDOWN = 1<<2,
|
||||
PF_LOOKDOWN = 1<<3,
|
||||
PF_ATTACKDOWN = 1,
|
||||
PF_ACCELDOWN = 1<<1,
|
||||
PF_BRAKEDOWN = 1<<2,
|
||||
PF_LOOKDOWN = 1<<3,
|
||||
|
||||
// Accessibility and cheats
|
||||
PF_KICKSTARTACCEL = 1<<4, // Is accelerate in kickstart mode?
|
||||
|
|
@ -99,6 +99,9 @@ typedef enum
|
|||
PF_HITFINISHLINE = 1<<26, // Already hit the finish line this tic
|
||||
PF_WRONGWAY = 1<<27, // Moving the wrong way with respect to waypoints?
|
||||
|
||||
PF_SHRINKME = 1<<28, // "Shrink me" cheat preference
|
||||
PF_SHRINKACTIVE = 1<<29, // "Shrink me" cheat is in effect. (Can't be disabled mid-race)
|
||||
|
||||
// up to 1<<31 is free
|
||||
} pflags_t;
|
||||
|
||||
|
|
@ -260,6 +263,10 @@ typedef enum
|
|||
// for kickstartaccel
|
||||
#define ACCEL_KICKSTART 35
|
||||
|
||||
#define ITEMSCALE_NORMAL 0
|
||||
#define ITEMSCALE_GROW 1
|
||||
#define ITEMSCALE_SHRINK 2
|
||||
|
||||
// player_t struct for all respawn variables
|
||||
typedef struct respawnvars_s
|
||||
{
|
||||
|
|
@ -290,6 +297,12 @@ typedef struct botvars_s
|
|||
tic_t spindashconfirm; // When high enough, they will try spindashing
|
||||
} botvars_t;
|
||||
|
||||
// player_t struct for all skybox variables
|
||||
typedef struct {
|
||||
mobj_t * viewpoint;
|
||||
mobj_t * centerpoint;
|
||||
} skybox_t;
|
||||
|
||||
// ========================================================================
|
||||
// PLAYER STRUCTURE
|
||||
// ========================================================================
|
||||
|
|
@ -311,6 +324,8 @@ typedef struct player_s
|
|||
// bounded/scaled total momentum.
|
||||
fixed_t bob;
|
||||
|
||||
skybox_t skybox;
|
||||
|
||||
angle_t viewrollangle;
|
||||
angle_t old_viewrollangle;
|
||||
// camera tilt
|
||||
|
|
@ -428,6 +443,7 @@ typedef struct player_s
|
|||
SINT8 itemtype; // KITEM_ constant for item number
|
||||
UINT8 itemamount; // Amount of said item
|
||||
SINT8 throwdir; // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir")
|
||||
UINT8 itemscale; // Item scale value, from when an item was taken out. (0 for normal, 1 for grow, 2 for shrink.)
|
||||
|
||||
UINT8 sadtimer; // How long you've been sad
|
||||
|
||||
|
|
|
|||
|
|
@ -5466,6 +5466,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
|||
|
||||
// SRB2kart
|
||||
"MT_RANDOMITEM",
|
||||
"MT_SPHEREBOX",
|
||||
"MT_RANDOMITEMPOP",
|
||||
"MT_FLOATINGITEM",
|
||||
"MT_ITEMCAPSULE",
|
||||
|
|
@ -5806,6 +5807,9 @@ const char *const MOBJFLAG_LIST[] = {
|
|||
"GRENADEBOUNCE",
|
||||
"RUNSPAWNFUNC",
|
||||
"DONTENCOREMAP",
|
||||
"PICKUPFROMBELOW",
|
||||
"NOSQUISH",
|
||||
"NOHITLAGFORME",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -5909,6 +5913,10 @@ const char *const PLAYERFLAG_LIST[] = {
|
|||
|
||||
"HITFINISHLINE", // Already hit the finish line this tic
|
||||
"WRONGWAY", // Moving the wrong way with respect to waypoints?
|
||||
|
||||
"SHRINKME",
|
||||
"SHRINKACTIVE",
|
||||
|
||||
NULL // stop loop here.
|
||||
};
|
||||
|
||||
|
|
@ -6457,6 +6465,7 @@ struct int_const_s const INT_CONST[] = {
|
|||
//// Masks
|
||||
{"DMG_STEAL",DMG_CANTHURTSELF},
|
||||
{"DMG_CANTHURTSELF",DMG_CANTHURTSELF},
|
||||
{"DMG_WOMBO", DMG_WOMBO},
|
||||
{"DMG_DEATHMASK",DMG_DEATHMASK},
|
||||
{"DMG_TYPEMASK",DMG_TYPEMASK},
|
||||
|
||||
|
|
|
|||
|
|
@ -550,6 +550,22 @@ extern boolean capslock;
|
|||
// i_system.c, replace getchar() once the keyboard has been appropriated
|
||||
INT32 I_GetKey(void);
|
||||
|
||||
/* http://www.cse.yorku.ca/~oz/hash.html */
|
||||
static inline
|
||||
UINT32 quickncasehash (const char *p, size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
UINT32 x = 5381;
|
||||
|
||||
while (i < n && p[i])
|
||||
{
|
||||
x = (x * 33) ^ tolower(p[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
#ifndef min // Double-Check with WATTCP-32's cdefs.h
|
||||
#define min(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -346,16 +346,6 @@ static void F_IntroDrawScene(void)
|
|||
// DRAW A FULL PIC INSTEAD OF FLAT!
|
||||
if (intro_scenenum == 0)
|
||||
{
|
||||
if (finalecount == 8)
|
||||
S_StartSound(NULL, sfx_vroom);
|
||||
else if (finalecount == 47)
|
||||
{
|
||||
// Need to use M_Random otherwise it always uses the same sound
|
||||
INT32 rskin = M_RandomKey(numskins);
|
||||
UINT8 rtaunt = M_RandomKey(2);
|
||||
sfxenum_t rsound = skins[rskin].soundsid[SKSKBST1+rtaunt];
|
||||
S_StartSound(NULL, rsound);
|
||||
}
|
||||
background = W_CachePatchName("KARTKREW", PU_CACHE);
|
||||
highres = true;
|
||||
}
|
||||
|
|
@ -454,6 +444,20 @@ void F_IntroTicker(void)
|
|||
|
||||
timetonext--;
|
||||
|
||||
if (intro_scenenum == 0)
|
||||
{
|
||||
if (finalecount == 8)
|
||||
S_StartSound(NULL, sfx_vroom);
|
||||
else if (finalecount == 47)
|
||||
{
|
||||
// Need to use M_Random otherwise it always uses the same sound
|
||||
INT32 rskin = M_RandomKey(numskins);
|
||||
UINT8 rtaunt = M_RandomKey(2);
|
||||
sfxenum_t rsound = skins[rskin].soundsid[SKSKBST1+rtaunt];
|
||||
S_StartSound(NULL, rsound);
|
||||
}
|
||||
}
|
||||
|
||||
F_WriteText();
|
||||
|
||||
// check for skipping
|
||||
|
|
|
|||
66
src/g_demo.c
66
src/g_demo.c
|
|
@ -60,7 +60,7 @@ boolean nodrawers; // for comparative timing purposes
|
|||
boolean noblit; // for comparative timing purposes
|
||||
tic_t demostarttime; // for comparative timing purposes
|
||||
|
||||
static char demoname[128];
|
||||
static char demoname[MAX_WADPATH];
|
||||
static UINT8 *demobuffer = NULL;
|
||||
static UINT8 *demotime_p, *demoinfo_p;
|
||||
UINT8 *demo_p;
|
||||
|
|
@ -122,8 +122,9 @@ demoghost *ghosts = NULL;
|
|||
#define DF_ENCORE 0x40
|
||||
#define DF_MULTIPLAYER 0x80 // This demo was recorded in multiplayer mode!
|
||||
|
||||
#define DEMO_SPECTATOR 0x40
|
||||
#define DEMO_KICKSTART 0x20
|
||||
#define DEMO_SPECTATOR 0x01
|
||||
#define DEMO_KICKSTART 0x02
|
||||
#define DEMO_SHRINKME 0x04
|
||||
|
||||
// For demos
|
||||
#define ZT_FWD 0x01
|
||||
|
|
@ -351,9 +352,20 @@ void G_ReadDemoExtraData(void)
|
|||
if (extradata & DXD_WEAPONPREF)
|
||||
{
|
||||
i = READUINT8(demo_p);
|
||||
players[p].pflags &= ~(PF_KICKSTARTACCEL);
|
||||
players[p].pflags &= ~(PF_KICKSTARTACCEL|PF_SHRINKME);
|
||||
if (i & 1)
|
||||
players[p].pflags |= PF_KICKSTARTACCEL;
|
||||
if (i & 2)
|
||||
players[p].pflags |= PF_SHRINKME;
|
||||
|
||||
if (leveltime < 2)
|
||||
{
|
||||
// BAD HACK: No other place I tried to slot this in
|
||||
// made it work for the host when they initally host,
|
||||
// so this will have to do.
|
||||
K_UpdateShrinkCheat(&players[p]);
|
||||
}
|
||||
|
||||
//CONS_Printf("weaponpref is %d for player %d\n", i, p);
|
||||
}
|
||||
|
||||
|
|
@ -466,6 +478,8 @@ void G_WriteDemoExtraData(void)
|
|||
UINT8 prefs = 0;
|
||||
if (players[i].pflags & PF_KICKSTARTACCEL)
|
||||
prefs |= 1;
|
||||
if (players[i].pflags & PF_SHRINKME)
|
||||
prefs |= 2;
|
||||
WRITEUINT8(demo_p, prefs);
|
||||
}
|
||||
}
|
||||
|
|
@ -2015,12 +2029,15 @@ void G_BeginRecording(void)
|
|||
for (p = 0; p < MAXPLAYERS; p++) {
|
||||
if (playeringame[p]) {
|
||||
player = &players[p];
|
||||
WRITEUINT8(demo_p, p);
|
||||
|
||||
i = p;
|
||||
if (player->pflags & PF_KICKSTARTACCEL)
|
||||
i |= DEMO_KICKSTART;
|
||||
i = 0;
|
||||
if (player->spectator)
|
||||
i |= DEMO_SPECTATOR;
|
||||
if (player->pflags & PF_KICKSTARTACCEL)
|
||||
i |= DEMO_KICKSTART;
|
||||
if (player->pflags & PF_SHRINKME)
|
||||
i |= DEMO_SHRINKME;
|
||||
WRITEUINT8(demo_p, i);
|
||||
|
||||
// Name
|
||||
|
|
@ -2672,7 +2689,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
UINT32 randseed;
|
||||
char msg[1024];
|
||||
|
||||
boolean spectator, kickstart;
|
||||
boolean spectator;
|
||||
UINT8 slots[MAXPLAYERS], kartspeed[MAXPLAYERS], kartweight[MAXPLAYERS], numslots = 0;
|
||||
|
||||
#if defined(SKIPERRORS) && !defined(DEVELOP)
|
||||
|
|
@ -2943,10 +2960,12 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
|
||||
while (p != 0xFF)
|
||||
{
|
||||
if ((spectator = !!(p & DEMO_SPECTATOR)))
|
||||
{
|
||||
p &= ~DEMO_SPECTATOR;
|
||||
UINT8 flags = READUINT8(demo_p);
|
||||
|
||||
spectator = !!(flags & DEMO_SPECTATOR);
|
||||
|
||||
if (spectator == true)
|
||||
{
|
||||
if (modeattacking)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with spectators, and is thus invalid.\n"), pdemoname);
|
||||
|
|
@ -2960,10 +2979,8 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
}
|
||||
}
|
||||
|
||||
if ((kickstart = (p & DEMO_KICKSTART)))
|
||||
p &= ~DEMO_KICKSTART;
|
||||
|
||||
slots[numslots] = p; numslots++;
|
||||
slots[numslots] = p;
|
||||
numslots++;
|
||||
|
||||
if (modeattacking && numslots > 1)
|
||||
{
|
||||
|
|
@ -2982,11 +2999,19 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
|
||||
playeringame[p] = true;
|
||||
players[p].spectator = spectator;
|
||||
if (kickstart)
|
||||
|
||||
if (flags & DEMO_KICKSTART)
|
||||
players[p].pflags |= PF_KICKSTARTACCEL;
|
||||
else
|
||||
players[p].pflags &= ~PF_KICKSTARTACCEL;
|
||||
|
||||
if (flags & DEMO_SHRINKME)
|
||||
players[p].pflags |= PF_SHRINKME;
|
||||
else
|
||||
players[p].pflags &= ~PF_SHRINKME;
|
||||
|
||||
K_UpdateShrinkCheat(&players[p]);
|
||||
|
||||
// Name
|
||||
M_Memcpy(player_names[p],demo_p,16);
|
||||
demo_p += 16;
|
||||
|
|
@ -3245,7 +3270,10 @@ void G_AddGhost(char *defdemoname)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((READUINT8(p) & ~DEMO_KICKSTART) != 0)
|
||||
p++; // player number - doesn't really need to be checked, TODO maybe support adding multiple players' ghosts at once
|
||||
|
||||
// any invalidating flags?
|
||||
if ((READUINT8(p) & (DEMO_SPECTATOR)) != 0)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname);
|
||||
Z_Free(pdemoname);
|
||||
|
|
@ -3791,7 +3819,7 @@ void G_SaveDemo(void)
|
|||
demo_slug[strindex] = 0;
|
||||
if (dash) demo_slug[strindex-1] = 0;
|
||||
|
||||
writepoint = strstr(demoname, "-") + 1;
|
||||
writepoint = strstr(strrchr(demoname, *PATHSEP), "-") + 1;
|
||||
demo_slug[128 - (writepoint - demoname) - 4] = 0;
|
||||
sprintf(writepoint, "%s.lmp", demo_slug);
|
||||
}
|
||||
|
|
@ -3808,7 +3836,7 @@ void G_SaveDemo(void)
|
|||
md5_buffer((char *)p+16, (demobuffer + length) - (p+16), p);
|
||||
#endif
|
||||
|
||||
if (FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer)) // finally output the file.
|
||||
if (FIL_WriteFile(demoname, demobuffer, demo_p - demobuffer)) // finally output the file.
|
||||
demo.savemode = DSM_SAVED;
|
||||
free(demobuffer);
|
||||
demo.recording = false;
|
||||
|
|
|
|||
36
src/g_game.c
36
src/g_game.c
|
|
@ -261,7 +261,7 @@ INT32 stealtime = TICRATE/2;
|
|||
INT32 sneakertime = TICRATE + (TICRATE/3);
|
||||
INT32 itemtime = 8*TICRATE;
|
||||
INT32 bubbletime = TICRATE/2;
|
||||
INT32 comebacktime = 10*TICRATE;
|
||||
INT32 comebacktime = 3*TICRATE;
|
||||
INT32 bumptime = 6;
|
||||
INT32 greasetics = 3*TICRATE;
|
||||
INT32 wipeoutslowtime = 20;
|
||||
|
|
@ -342,10 +342,10 @@ INT16 prevmap, nextmap;
|
|||
|
||||
static UINT8 *savebuffer;
|
||||
|
||||
static void kickstartaccel_OnChange(void);
|
||||
static void kickstartaccel2_OnChange(void);
|
||||
static void kickstartaccel3_OnChange(void);
|
||||
static void kickstartaccel4_OnChange(void);
|
||||
static void weaponPrefChange(void);
|
||||
static void weaponPrefChange2(void);
|
||||
static void weaponPrefChange3(void);
|
||||
static void weaponPrefChange4(void);
|
||||
|
||||
static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"},
|
||||
{1, "X-Axis"}, {2, "Y-Axis"}, {-1, "X-Axis-"}, {-2, "Y-Axis-"},
|
||||
|
|
@ -406,10 +406,17 @@ consvar_t cv_resetspecialmusic = CVAR_INIT ("resetspecialmusic", "Yes", CV_SAVE,
|
|||
consvar_t cv_resume = CVAR_INIT ("resume", "Yes", CV_SAVE, CV_YesNo, NULL);
|
||||
|
||||
consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("kickstartaccel", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel_OnChange),
|
||||
CVAR_INIT ("kickstartaccel2", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel2_OnChange),
|
||||
CVAR_INIT ("kickstartaccel3", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel3_OnChange),
|
||||
CVAR_INIT ("kickstartaccel4", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel4_OnChange)
|
||||
CVAR_INIT ("kickstartaccel", "Off", CV_SAVE|CV_CALL, CV_OnOff, weaponPrefChange),
|
||||
CVAR_INIT ("kickstartaccel2", "Off", CV_SAVE|CV_CALL, CV_OnOff, weaponPrefChange2),
|
||||
CVAR_INIT ("kickstartaccel3", "Off", CV_SAVE|CV_CALL, CV_OnOff, weaponPrefChange3),
|
||||
CVAR_INIT ("kickstartaccel4", "Off", CV_SAVE|CV_CALL, CV_OnOff, weaponPrefChange4)
|
||||
};
|
||||
|
||||
consvar_t cv_shrinkme[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("shrinkme", "Off", CV_CALL, CV_OnOff, weaponPrefChange),
|
||||
CVAR_INIT ("shrinkme2", "Off", CV_CALL, CV_OnOff, weaponPrefChange2),
|
||||
CVAR_INIT ("shrinkme3", "Off", CV_CALL, CV_OnOff, weaponPrefChange3),
|
||||
CVAR_INIT ("shrinkme4", "Off", CV_CALL, CV_OnOff, weaponPrefChange4)
|
||||
};
|
||||
|
||||
consvar_t cv_turnaxis[MAXSPLITSCREENPLAYERS] = {
|
||||
|
|
@ -1185,22 +1192,22 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n)
|
|||
return dest;
|
||||
}
|
||||
|
||||
static void kickstartaccel_OnChange(void)
|
||||
static void weaponPrefChange(void)
|
||||
{
|
||||
SendWeaponPref(0);
|
||||
}
|
||||
|
||||
static void kickstartaccel2_OnChange(void)
|
||||
static void weaponPrefChange2(void)
|
||||
{
|
||||
SendWeaponPref(1);
|
||||
}
|
||||
|
||||
static void kickstartaccel3_OnChange(void)
|
||||
static void weaponPrefChange3(void)
|
||||
{
|
||||
SendWeaponPref(2);
|
||||
}
|
||||
|
||||
static void kickstartaccel4_OnChange(void)
|
||||
static void weaponPrefChange4(void)
|
||||
{
|
||||
SendWeaponPref(3);
|
||||
}
|
||||
|
|
@ -2165,7 +2172,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
botdiffincrease = players[player].botvars.diffincrease;
|
||||
botrival = players[player].botvars.rival;
|
||||
|
||||
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL));
|
||||
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE));
|
||||
|
||||
// SRB2kart
|
||||
if (betweenmaps || leveltime < introtime)
|
||||
|
|
@ -2236,7 +2243,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
if (!(netgame || multiplayer))
|
||||
pflags |= (players[player].pflags & (PF_GODMODE|PF_NOCLIP));
|
||||
|
||||
|
||||
// Obliterate follower from existence
|
||||
P_SetTarget(&players[player].follower, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ extern consvar_t cv_pauseifunfocused;
|
|||
extern consvar_t cv_invertmouse;
|
||||
|
||||
extern consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_shrinkme[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
extern consvar_t cv_turnaxis[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_moveaxis[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_brakeaxis[MAXSPLITSCREENPLAYERS];
|
||||
|
|
|
|||
|
|
@ -40,9 +40,12 @@
|
|||
#include "../r_things.h" // R_GetShadowZ
|
||||
#include "../d_main.h"
|
||||
#include "../p_slopes.h"
|
||||
#include "../k_kart.h" // HITLAGJITTERS
|
||||
#include "hw_md2.h"
|
||||
|
||||
// SRB2Kart
|
||||
#include "../k_kart.h" // HITLAGJITTERS
|
||||
#include "../r_fps.h"
|
||||
|
||||
#ifdef NEWCLIP
|
||||
#include "hw_clip.h"
|
||||
#endif
|
||||
|
|
@ -178,6 +181,18 @@ boolean gl_shadersavailable = true;
|
|||
// Lighting
|
||||
// ==========================================================================
|
||||
|
||||
boolean HWR_OverrideObjectLightLevel(mobj_t *thing, INT32 *lightlevel)
|
||||
{
|
||||
if (R_ThingIsFullBright(thing))
|
||||
*lightlevel = 255;
|
||||
else if (R_ThingIsFullDark(thing))
|
||||
*lightlevel = 0;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap)
|
||||
{
|
||||
RGBA_t poly_color, tint_color, fade_color;
|
||||
|
|
@ -3641,17 +3656,9 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
fixed_t slopez;
|
||||
pslope_t *groundslope;
|
||||
|
||||
fixed_t interpx = thing->x;
|
||||
fixed_t interpy = thing->y;
|
||||
fixed_t interpz = thing->z;
|
||||
|
||||
// do interpolation
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
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);
|
||||
}
|
||||
fixed_t interpx = R_InterpolateFixed(thing->old_x, thing->x);
|
||||
fixed_t interpy = R_InterpolateFixed(thing->old_y, thing->y);
|
||||
fixed_t interpz = R_InterpolateFixed(thing->old_z, thing->z);
|
||||
|
||||
// hitlag vibrating (todo: interp somehow?)
|
||||
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
|
||||
|
|
@ -3673,7 +3680,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
interpy += thing->spryoff;
|
||||
interpz += thing->sprzoff;
|
||||
|
||||
groundz = R_GetShadowZ(thing, &groundslope);
|
||||
groundz = R_GetShadowZ(thing, &groundslope, interpx, interpy, interpz);
|
||||
|
||||
gpatch = (patch_t *)W_CachePatchName("DSHADOW", PU_SPRITE);
|
||||
if (!(gpatch && ((GLPatch_t *)gpatch->hardware)->mipmap->format)) return;
|
||||
|
|
@ -3800,7 +3807,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
patch_t *gpatch;
|
||||
FSurfaceInfo Surf;
|
||||
extracolormap_t *colormap = NULL;
|
||||
FUINT lightlevel;
|
||||
INT32 lightlevel;
|
||||
boolean lightset = true;
|
||||
FBITFIELD blend = 0;
|
||||
FBITFIELD occlusion;
|
||||
|
|
@ -3930,18 +3937,13 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
|
||||
// Start with the lightlevel and colormap from the top of the sprite
|
||||
lightlevel = *list[sector->numlights - 1].lightlevel;
|
||||
if (!(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||
if (!R_ThingIsFullBright(spr->mobj) && !(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||
colormap = *list[sector->numlights - 1].extra_colormap;
|
||||
|
||||
i = 0;
|
||||
temp = FLOAT_TO_FIXED(realtop);
|
||||
|
||||
if (R_ThingIsFullBright(spr->mobj))
|
||||
lightlevel = 255;
|
||||
else if (R_ThingIsFullDark(spr->mobj))
|
||||
lightlevel = 0;
|
||||
else
|
||||
lightset = false;
|
||||
lightset = HWR_OverrideObjectLightLevel(spr->mobj, &lightlevel);
|
||||
|
||||
for (i = 1; i < sector->numlights; i++)
|
||||
{
|
||||
|
|
@ -3950,7 +3952,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
{
|
||||
if (!lightset)
|
||||
lightlevel = *list[i-1].lightlevel > 255 ? 255 : *list[i-1].lightlevel;
|
||||
if (!(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||
if (!R_ThingIsFullBright(spr->mobj) && !(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||
colormap = *list[i-1].extra_colormap;
|
||||
break;
|
||||
}
|
||||
|
|
@ -3968,8 +3970,14 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES))
|
||||
{
|
||||
if (!lightset)
|
||||
{
|
||||
lightlevel = *list[i].lightlevel > 255 ? 255 : *list[i].lightlevel;
|
||||
if (!(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||
|
||||
if (R_ThingIsSemiBright(spr->mobj))
|
||||
lightlevel = 128 + (lightlevel>>1);
|
||||
}
|
||||
|
||||
if (!R_ThingIsFullBright(spr->mobj) && !(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||
colormap = *list[i].extra_colormap;
|
||||
}
|
||||
|
||||
|
|
@ -4284,18 +4292,11 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
// colormap test
|
||||
{
|
||||
sector_t *sector = spr->mobj->subsector->sector;
|
||||
UINT8 lightlevel = 0;
|
||||
boolean lightset = true;
|
||||
INT32 lightlevel = 0;
|
||||
boolean lightset = HWR_OverrideObjectLightLevel(spr->mobj, &lightlevel);
|
||||
extracolormap_t *colormap = NULL;
|
||||
|
||||
if (R_ThingIsFullBright(spr->mobj))
|
||||
lightlevel = 255;
|
||||
else if (R_ThingIsFullDark(spr->mobj))
|
||||
lightlevel = 0;
|
||||
else
|
||||
lightset = false;
|
||||
|
||||
if (!(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||
if (!R_ThingIsFullBright(spr->mobj) && !(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||
colormap = sector->extra_colormap;
|
||||
|
||||
if (splat && sector->numlights)
|
||||
|
|
@ -4305,7 +4306,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
if (!lightset)
|
||||
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
|
||||
|
||||
if (*sector->lightlist[light].extra_colormap && !(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||
if (!R_ThingIsFullBright(spr->mobj) && *sector->lightlist[light].extra_colormap && !(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||
colormap = *sector->lightlist[light].extra_colormap;
|
||||
}
|
||||
else if (!lightset)
|
||||
|
|
@ -5084,25 +5085,18 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
dispoffset = thing->info->dispoffset;
|
||||
|
||||
interpx = thing->x;
|
||||
interpy = thing->y;
|
||||
interpz = thing->z;
|
||||
interpangle = (thing->player ? thing->player->drawangle : thing->angle);
|
||||
interpx = R_InterpolateFixed(thing->old_x, thing->x);
|
||||
interpy = R_InterpolateFixed(thing->old_y, thing->y);
|
||||
interpz = R_InterpolateFixed(thing->old_z, thing->z);
|
||||
interpangle = ANGLE_MAX;
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
if (thing->player)
|
||||
{
|
||||
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->old_drawangle + FixedMul(rendertimefrac, thing->player->drawangle - thing->player->old_drawangle);
|
||||
}
|
||||
else
|
||||
{
|
||||
interpangle = thing->old_angle + FixedMul(rendertimefrac, thing->angle - thing->old_angle);
|
||||
}
|
||||
interpangle = R_InterpolateAngle(thing->player->old_drawangle, thing->player->drawangle);
|
||||
}
|
||||
else
|
||||
{
|
||||
interpangle = R_InterpolateAngle(thing->old_angle, thing->angle);
|
||||
}
|
||||
|
||||
// hitlag vibrating (todo: interp somehow?)
|
||||
|
|
@ -5307,7 +5301,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (caster && !P_MobjWasRemoved(caster))
|
||||
{
|
||||
fixed_t groundz = R_GetShadowZ(thing, NULL);
|
||||
fixed_t groundz = R_GetShadowZ(thing, NULL, interpx, interpy, interpz);
|
||||
fixed_t floordiff = abs(((thing->eflags & MFE_VERTICALFLIP) ? caster->height : 0) + caster->z - groundz);
|
||||
|
||||
shadowheight = FIXED_TO_FLOAT(floordiff);
|
||||
|
|
@ -5526,17 +5520,9 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
if (!thing)
|
||||
return;
|
||||
|
||||
interpx = thing->x;
|
||||
interpy = thing->y;
|
||||
interpz = thing->z;
|
||||
|
||||
// do interpolation
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
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);
|
||||
}
|
||||
interpx = R_InterpolateFixed(thing->old_x, thing->x);
|
||||
interpy = R_InterpolateFixed(thing->old_y, thing->y);
|
||||
interpz = R_InterpolateFixed(thing->old_z, thing->z);
|
||||
|
||||
// transform the origin point
|
||||
tr_x = FIXED_TO_FLOAT(interpx) - gl_viewx;
|
||||
|
|
@ -6241,7 +6227,7 @@ void HWR_RenderPlayerView(void)
|
|||
const float fpov = FIXED_TO_FLOAT(cv_fov[viewssnum].value+player->fovadd);
|
||||
postimg_t *type = &postimgtype[viewssnum];
|
||||
|
||||
const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on
|
||||
const boolean skybox = (player->skybox.viewpoint && cv_skybox.value); // True if there's a skybox object and skyboxes are on
|
||||
|
||||
FRGBAFloat ClearColor;
|
||||
|
||||
|
|
@ -6772,7 +6758,6 @@ 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;
|
||||
|
|
@ -6782,15 +6767,15 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
// Modifies the wave.
|
||||
if (*type == postimg_water)
|
||||
{
|
||||
WAVELENGTH = 20; // Lower is longer
|
||||
AMPLITUDE = 20; // Lower is bigger
|
||||
FREQUENCY = 16; // Lower is faster
|
||||
WAVELENGTH = 5;
|
||||
AMPLITUDE = 20;
|
||||
FREQUENCY = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
WAVELENGTH = 10; // Lower is longer
|
||||
AMPLITUDE = 30; // Lower is bigger
|
||||
FREQUENCY = 4; // Lower is faster
|
||||
WAVELENGTH = 10;
|
||||
AMPLITUDE = 60;
|
||||
FREQUENCY = 4;
|
||||
}
|
||||
|
||||
for (x = 0; x < SCREENVERTS; x++)
|
||||
|
|
@ -6804,16 +6789,7 @@ 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;
|
||||
disStart += FIXED_TO_FLOAT(renderdeltatics);
|
||||
|
||||
// Capture the screen again for screen waving on the intermission
|
||||
if(gamestate != GS_INTERMISSION)
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ void HWR_MakeScreenFinalTexture(void);
|
|||
void HWR_DrawScreenFinalTexture(int width, int height);
|
||||
|
||||
// This stuff is put here so models can use them
|
||||
boolean HWR_OverrideObjectLightLevel(mobj_t *thing, INT32 *lightlevel);
|
||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
|
||||
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
// SRB2Kart
|
||||
#include "../k_color.h"
|
||||
#include "../k_kart.h" // HITLAGJITTERS
|
||||
#include "../r_fps.h"
|
||||
|
||||
#ifdef HAVE_PNG
|
||||
|
||||
|
|
@ -1323,7 +1324,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
if (spr->mobj->subsector)
|
||||
{
|
||||
sector_t *sector = spr->mobj->subsector->sector;
|
||||
UINT8 lightlevel = 255;
|
||||
INT32 lightlevel = 255;
|
||||
boolean lightset = HWR_OverrideObjectLightLevel(spr->mobj, &lightlevel);
|
||||
extracolormap_t *colormap = NULL;
|
||||
|
||||
if (sector->numlights)
|
||||
|
|
@ -1332,22 +1334,22 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
|
||||
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
|
||||
|
||||
if (!R_ThingIsFullBright(spr->mobj))
|
||||
if (!lightset)
|
||||
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
|
||||
|
||||
if (*sector->lightlist[light].extra_colormap)
|
||||
if (!R_ThingIsFullBright(spr->mobj) && *sector->lightlist[light].extra_colormap)
|
||||
colormap = *sector->lightlist[light].extra_colormap;
|
||||
}
|
||||
else
|
||||
else if (!lightset)
|
||||
{
|
||||
if (!R_ThingIsFullBright(spr->mobj))
|
||||
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
|
||||
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
|
||||
|
||||
if (sector->extra_colormap)
|
||||
colormap = sector->extra_colormap;
|
||||
}
|
||||
|
||||
//lightlevel = 128 + (lightlevel>>1);
|
||||
if (R_ThingIsSemiBright(spr->mobj))
|
||||
lightlevel = 128 + (lightlevel>>1);
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
}
|
||||
|
|
@ -1368,17 +1370,9 @@ 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
fixed_t interpx = R_InterpolateFixed(spr->mobj->old_x, spr->mobj->x);
|
||||
fixed_t interpy = R_InterpolateFixed(spr->mobj->old_y, spr->mobj->y);
|
||||
fixed_t interpz = R_InterpolateFixed(spr->mobj->old_z, spr->mobj->z);
|
||||
|
||||
// hitlag vibrating
|
||||
if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG))
|
||||
|
|
@ -1636,10 +1630,16 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
|
||||
if (sprframe->rotate || papersprite)
|
||||
{
|
||||
fixed_t anglef = AngleFixed(spr->mobj->angle);
|
||||
fixed_t anglef = INT32_MAX;
|
||||
|
||||
if (spr->mobj->player)
|
||||
anglef = AngleFixed(spr->mobj->player->drawangle);
|
||||
{
|
||||
anglef = AngleFixed(R_InterpolateAngle(spr->mobj->player->old_drawangle, spr->mobj->player->drawangle));
|
||||
}
|
||||
else
|
||||
{
|
||||
anglef = AngleFixed(R_InterpolateAngle(spr->mobj->old_angle, spr->mobj->angle));
|
||||
}
|
||||
|
||||
p.angley = FIXED_TO_FLOAT(anglef);
|
||||
}
|
||||
|
|
@ -1671,8 +1671,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
}
|
||||
}
|
||||
|
||||
p.anglez = FIXED_TO_FLOAT(AngleFixed(spr->mobj->pitch));
|
||||
p.anglex = FIXED_TO_FLOAT(AngleFixed(spr->mobj->roll));
|
||||
p.anglez = FIXED_TO_FLOAT(AngleFixed(R_InterpolateAngle(spr->mobj->old_pitch, spr->mobj->pitch)));
|
||||
p.anglex = FIXED_TO_FLOAT(AngleFixed(R_InterpolateAngle(spr->mobj->old_roll, spr->mobj->roll)));
|
||||
|
||||
// SRB2CBTODO: MD2 scaling support
|
||||
finalscale *= FIXED_TO_FLOAT(spr->mobj->scale);
|
||||
|
|
|
|||
169
src/hu_stuff.c
169
src/hu_stuff.c
|
|
@ -56,6 +56,7 @@
|
|||
#include "k_kart.h"
|
||||
#include "k_color.h"
|
||||
#include "k_hud.h"
|
||||
#include "r_fps.h"
|
||||
|
||||
// coords are scaled
|
||||
#define HU_INPUTX 0
|
||||
|
|
@ -165,6 +166,8 @@ static tic_t cechotimer = 0;
|
|||
static tic_t cechoduration = 5*TICRATE;
|
||||
static INT32 cechoflags = 0;
|
||||
|
||||
static tic_t resynch_ticker = 0;
|
||||
|
||||
//======================================================================
|
||||
// HEADS UP INIT
|
||||
//======================================================================
|
||||
|
|
@ -908,6 +911,60 @@ static inline boolean HU_keyInChatString(char *s, char ch)
|
|||
|
||||
//
|
||||
//
|
||||
static void HU_TickSongCredits(void)
|
||||
{
|
||||
if (cursongcredit.def == NULL) // No def
|
||||
{
|
||||
cursongcredit.x = cursongcredit.old_x = 0;
|
||||
cursongcredit.anim = 0;
|
||||
cursongcredit.trans = NUMTRANSMAPS;
|
||||
return;
|
||||
}
|
||||
|
||||
cursongcredit.old_x = cursongcredit.x;
|
||||
|
||||
if (cursongcredit.anim > 0)
|
||||
{
|
||||
char *str = va("\x1F"" %s", cursongcredit.def->source);
|
||||
INT32 len = V_ThinStringWidth(str, V_ALLOWLOWERCASE|V_6WIDTHSPACE);
|
||||
fixed_t destx = (len+7) * FRACUNIT;
|
||||
|
||||
if (cursongcredit.trans > 0)
|
||||
{
|
||||
cursongcredit.trans--;
|
||||
}
|
||||
|
||||
if (cursongcredit.x < destx)
|
||||
{
|
||||
cursongcredit.x += (destx - cursongcredit.x) / 2;
|
||||
}
|
||||
|
||||
if (cursongcredit.x > destx)
|
||||
{
|
||||
cursongcredit.x = destx;
|
||||
}
|
||||
|
||||
cursongcredit.anim--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cursongcredit.trans < NUMTRANSMAPS)
|
||||
{
|
||||
cursongcredit.trans++;
|
||||
}
|
||||
|
||||
if (cursongcredit.x > 0)
|
||||
{
|
||||
cursongcredit.x /= 2;
|
||||
}
|
||||
|
||||
if (cursongcredit.x < 0)
|
||||
{
|
||||
cursongcredit.x = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HU_Ticker(void)
|
||||
{
|
||||
if (dedicated)
|
||||
|
|
@ -922,6 +979,49 @@ void HU_Ticker(void)
|
|||
hu_showscores = false;
|
||||
|
||||
hu_keystrokes = false;
|
||||
|
||||
if (chat_on)
|
||||
{
|
||||
// count down the scroll timer.
|
||||
if (chat_scrolltime > 0)
|
||||
chat_scrolltime--;
|
||||
}
|
||||
else
|
||||
{
|
||||
chat_scrolltime = 0;
|
||||
}
|
||||
|
||||
if (netgame) // would handle that in hu_drawminichat, but it's actually kinda awkward when you're typing a lot of messages. (only handle that in netgames duh)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
// handle spam while we're at it:
|
||||
for(; (i<MAXPLAYERS); i++)
|
||||
{
|
||||
if (stop_spamming[i] > 0)
|
||||
stop_spamming[i]--;
|
||||
}
|
||||
|
||||
// handle chat timers
|
||||
for (i=0; (i<chat_nummsg_min); i++)
|
||||
{
|
||||
if (chat_timers[i] > 0)
|
||||
chat_timers[i]--;
|
||||
else
|
||||
HU_removeChatText_Mini();
|
||||
}
|
||||
}
|
||||
|
||||
cechotimer--;
|
||||
|
||||
if (gamestate != GS_LEVEL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
resynch_ticker++;
|
||||
|
||||
HU_TickSongCredits();
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
|
|
@ -1903,8 +2003,6 @@ static void HU_DrawCEcho(void)
|
|||
echoptr = line;
|
||||
echoptr++;
|
||||
}
|
||||
|
||||
--cechotimer;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -1954,42 +2052,28 @@ static void HU_DrawDemoInfo(void)
|
|||
void HU_DrawSongCredits(void)
|
||||
{
|
||||
char *str;
|
||||
INT32 len, destx;
|
||||
INT32 y = (r_splitscreen ? (BASEVIDHEIGHT/2)-4 : 32);
|
||||
fixed_t x;
|
||||
fixed_t y = (r_splitscreen ? (BASEVIDHEIGHT/2)-4 : 32) * FRACUNIT;
|
||||
INT32 bgt;
|
||||
|
||||
if (!cursongcredit.def) // No def
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
str = va("\x1F"" %s", cursongcredit.def->source);
|
||||
len = V_ThinStringWidth(str, V_ALLOWLOWERCASE|V_6WIDTHSPACE);
|
||||
destx = (len+7);
|
||||
bgt = (NUMTRANSMAPS/2) + (cursongcredit.trans / 2);
|
||||
x = R_InterpolateFixed(cursongcredit.old_x, cursongcredit.x);
|
||||
|
||||
if (cursongcredit.anim)
|
||||
{
|
||||
if (cursongcredit.trans > 0)
|
||||
cursongcredit.trans--;
|
||||
if (cursongcredit.x < destx)
|
||||
cursongcredit.x += (destx - cursongcredit.x) / 2;
|
||||
if (cursongcredit.x > destx)
|
||||
cursongcredit.x = destx;
|
||||
cursongcredit.anim--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cursongcredit.trans < NUMTRANSMAPS)
|
||||
cursongcredit.trans++;
|
||||
if (cursongcredit.x > 0)
|
||||
cursongcredit.x /= 2;
|
||||
if (cursongcredit.x < 0)
|
||||
cursongcredit.x = 0;
|
||||
}
|
||||
|
||||
bgt = (NUMTRANSMAPS/2)+(cursongcredit.trans/2);
|
||||
if (bgt < NUMTRANSMAPS)
|
||||
V_DrawScaledPatch(cursongcredit.x, y-2, V_SNAPTOLEFT|(bgt<<V_ALPHASHIFT), songcreditbg);
|
||||
{
|
||||
V_DrawFixedPatch(x, y - (2 * FRACUNIT), FRACUNIT, V_SNAPTOLEFT|(bgt<<V_ALPHASHIFT), songcreditbg, NULL);
|
||||
}
|
||||
|
||||
if (cursongcredit.trans < NUMTRANSMAPS)
|
||||
V_DrawRightAlignedThinString(cursongcredit.x, y, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_SNAPTOLEFT|(cursongcredit.trans<<V_ALPHASHIFT), str);
|
||||
{
|
||||
V_DrawRightAlignedThinStringAtFixed(x, y, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_SNAPTOLEFT|(cursongcredit.trans<<V_ALPHASHIFT), str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2004,9 +2088,6 @@ void HU_Drawer(void)
|
|||
// draw chat string plus cursor
|
||||
if (chat_on)
|
||||
{
|
||||
// count down the scroll timer.
|
||||
if (chat_scrolltime > 0)
|
||||
chat_scrolltime--;
|
||||
if (!OLDCHAT)
|
||||
HU_DrawChat();
|
||||
else
|
||||
|
|
@ -2015,31 +2096,9 @@ void HU_Drawer(void)
|
|||
else
|
||||
{
|
||||
typelines = 1;
|
||||
chat_scrolltime = 0;
|
||||
if (!OLDCHAT && cv_consolechat.value < 2 && netgame) // Don't display minimized chat if you set the mode to Window (Hidden)
|
||||
HU_drawMiniChat(); // draw messages in a cool fashion.
|
||||
}
|
||||
|
||||
if (netgame) // would handle that in hu_drawminichat, but it's actually kinda awkward when you're typing a lot of messages. (only handle that in netgames duh)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
// handle spam while we're at it:
|
||||
for(; (i<MAXPLAYERS); i++)
|
||||
{
|
||||
if (stop_spamming[i] > 0)
|
||||
stop_spamming[i]--;
|
||||
}
|
||||
|
||||
// handle chat timers
|
||||
for (i=0; (i<chat_nummsg_min); i++)
|
||||
{
|
||||
if (chat_timers[i] > 0)
|
||||
chat_timers[i]--;
|
||||
else
|
||||
HU_removeChatText_Mini();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cechotimer)
|
||||
|
|
@ -2078,12 +2137,10 @@ void HU_Drawer(void)
|
|||
// draw desynch text
|
||||
if (hu_redownloadinggamestate)
|
||||
{
|
||||
static UINT32 resynch_ticker = 0;
|
||||
char resynch_text[14];
|
||||
UINT32 i;
|
||||
|
||||
// Animate the dots
|
||||
resynch_ticker++;
|
||||
strcpy(resynch_text, "Resynching");
|
||||
for (i = 0; i < (resynch_ticker / 16) % 4; i++)
|
||||
strcat(resynch_text, ".");
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@ 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.
|
||||
/** \brief Get the current time in tics including fractions.
|
||||
*/
|
||||
fixed_t I_GetTimeFrac(void);
|
||||
float I_GetTimeFrac(void);
|
||||
|
||||
/** \brief Returns precise time value for performance measurement.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -9295,7 +9295,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
4, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
MF_NOBLOCKMAP|MF_SCENERY|MF_NOCLIPHEIGHT|MF_NOHITLAGFORME, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -9322,7 +9322,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
4, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY|MF_NOCLIPHEIGHT|MF_PAPERCOLLISION, // flags
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY|MF_NOCLIPHEIGHT|MF_PAPERCOLLISION|MF_NOHITLAGFORME, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
@ -9349,7 +9349,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
4, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPTHING, // flags
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPTHING|MF_NOHITLAGFORME, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ mobj_t *K_SpawnSphereBox(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 f
|
|||
|
||||
(void)amount;
|
||||
|
||||
drop->angle = angle;
|
||||
P_InitAngle(drop, angle);
|
||||
P_Thrust(drop,
|
||||
FixedAngle(P_RandomFixed() * 180) + angle,
|
||||
P_RandomRange(4, 12) * mapobjectscale);
|
||||
|
|
@ -469,16 +469,15 @@ void K_RunPaperItemSpawners(void)
|
|||
firstUnspawnedEmerald
|
||||
);
|
||||
}
|
||||
else if (P_RandomChance(FRACUNIT/3))
|
||||
else
|
||||
{
|
||||
drop = K_SpawnSphereBox(
|
||||
spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip),
|
||||
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
|
||||
10
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
K_FlipFromObject(drop, spotList[r]);
|
||||
|
||||
drop = K_CreatePaperItem(
|
||||
spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip),
|
||||
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
|
||||
|
|
@ -529,7 +528,7 @@ static void K_SpawnOvertimeLaser(fixed_t x, fixed_t y, fixed_t scale)
|
|||
mo->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
|
||||
mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90;
|
||||
P_InitAngle(mo, R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90);
|
||||
mo->renderflags |= (RF_DONTDRAW & ~(K_GetPlayerDontDrawFlag(player)));
|
||||
|
||||
P_SetScale(mo, scale);
|
||||
|
|
|
|||
|
|
@ -662,7 +662,10 @@ fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t
|
|||
--------------------------------------------------*/
|
||||
static botprediction_t *K_CreateBotPrediction(player_t *player)
|
||||
{
|
||||
const INT16 handling = K_GetKartTurnValue(player, KART_FULLTURN); // Reduce prediction based on how fast you can turn
|
||||
// Stair janking makes it harder to steer, so attempt to steer harder.
|
||||
const UINT8 jankDiv = (player->stairjank > 0 ? 2 : 1);
|
||||
|
||||
const INT16 handling = K_GetKartTurnValue(player, KART_FULLTURN) / jankDiv; // Reduce prediction based on how fast you can turn
|
||||
const INT16 normal = KART_FULLTURN; // "Standard" handling to compare to
|
||||
|
||||
const tic_t futuresight = (TICRATE * normal) / max(1, handling); // How far ahead into the future to try and predict
|
||||
|
|
|
|||
|
|
@ -382,6 +382,8 @@ static void K_BotItemGenericTap(player_t *player, ticcmd_t *cmd)
|
|||
--------------------------------------------------*/
|
||||
static boolean K_BotRevealsGenericTrap(player_t *player, INT16 turnamt, boolean mine)
|
||||
{
|
||||
const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
|
||||
|
||||
if (abs(turnamt) >= KART_FULLTURN/2)
|
||||
{
|
||||
// DON'T reveal on turns, we can place bananas on turns whenever we have multiple to spare,
|
||||
|
|
@ -404,7 +406,7 @@ static boolean K_BotRevealsGenericTrap(player_t *player, INT16 turnamt, boolean
|
|||
}
|
||||
|
||||
// Check your behind.
|
||||
if (K_PlayerInCone(player, player->mo->radius * 16, 10, true) != NULL)
|
||||
if (K_PlayerInCone(player, coneDist, 15, true) != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -536,16 +538,19 @@ static void K_BotItemRocketSneaker(player_t *player, ticcmd_t *cmd)
|
|||
--------------------------------------------------*/
|
||||
static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||
{
|
||||
const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
|
||||
SINT8 throwdir = -1;
|
||||
boolean tryLookback = false;
|
||||
player_t *target = NULL;
|
||||
|
||||
player->botvars.itemconfirm++;
|
||||
|
||||
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
|
||||
target = K_PlayerInCone(player, coneDist, 15, true);
|
||||
if (target != NULL)
|
||||
{
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
|
||||
throwdir = -1;
|
||||
tryLookback = true;
|
||||
}
|
||||
|
||||
if (abs(turnamt) >= KART_FULLTURN/2)
|
||||
|
|
@ -564,7 +569,12 @@ static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
|||
}
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE)
|
||||
if (tryLookback == true && throwdir == -1)
|
||||
{
|
||||
cmd->buttons |= BT_LOOKBACK;
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 10*TICRATE || player->bananadrag >= TICRATE)
|
||||
{
|
||||
K_BotGenericPressItem(player, cmd, throwdir);
|
||||
}
|
||||
|
|
@ -585,12 +595,14 @@ static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
|||
--------------------------------------------------*/
|
||||
static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||
{
|
||||
const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
|
||||
SINT8 throwdir = 0;
|
||||
boolean tryLookback = false;
|
||||
player_t *target = NULL;
|
||||
|
||||
player->botvars.itemconfirm++;
|
||||
|
||||
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
|
||||
target = K_PlayerInCone(player, coneDist, 15, true);
|
||||
if (target != NULL)
|
||||
{
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
|
||||
|
|
@ -601,6 +613,7 @@ static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
|||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty / 2;
|
||||
throwdir = -1;
|
||||
tryLookback = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -619,7 +632,12 @@ static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
|||
}
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE)
|
||||
if (tryLookback == true && throwdir == -1)
|
||||
{
|
||||
cmd->buttons |= BT_LOOKBACK;
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 10*TICRATE || player->bananadrag >= TICRATE)
|
||||
{
|
||||
K_BotGenericPressItem(player, cmd, throwdir);
|
||||
}
|
||||
|
|
@ -640,6 +658,7 @@ static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
|||
--------------------------------------------------*/
|
||||
static void K_BotItemLandmine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||
{
|
||||
const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
|
||||
player_t *target = NULL;
|
||||
|
||||
player->botvars.itemconfirm++;
|
||||
|
|
@ -649,13 +668,14 @@ static void K_BotItemLandmine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
|||
player->botvars.itemconfirm += player->botvars.difficulty / 2;
|
||||
}
|
||||
|
||||
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
|
||||
target = K_PlayerInCone(player, coneDist, 15, true);
|
||||
if (target != NULL)
|
||||
{
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
|
||||
cmd->buttons |= BT_LOOKBACK;
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 2*TICRATE)
|
||||
if (player->botvars.itemconfirm > 10*TICRATE)
|
||||
{
|
||||
K_BotGenericPressItem(player, cmd, -1);
|
||||
}
|
||||
|
|
@ -675,8 +695,10 @@ static void K_BotItemLandmine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
|||
--------------------------------------------------*/
|
||||
static void K_BotItemEggman(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
|
||||
const UINT8 stealth = K_EggboxStealth(player->mo->x, player->mo->y);
|
||||
SINT8 throwdir = -1;
|
||||
boolean tryLookback = false;
|
||||
player_t *target = NULL;
|
||||
|
||||
player->botvars.itemconfirm++;
|
||||
|
|
@ -688,11 +710,12 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd)
|
|||
throwdir = 1;
|
||||
}
|
||||
|
||||
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
|
||||
target = K_PlayerInCone(player, coneDist, 15, true);
|
||||
if (target != NULL)
|
||||
{
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
|
||||
throwdir = -1;
|
||||
tryLookback = true;
|
||||
}
|
||||
|
||||
if (stealth > 1 || player->itemroulette > 0)
|
||||
|
|
@ -701,7 +724,12 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd)
|
|||
throwdir = -1;
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE)
|
||||
if (tryLookback == true && throwdir == -1)
|
||||
{
|
||||
cmd->buttons |= BT_LOOKBACK;
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 10*TICRATE || player->bananadrag >= TICRATE)
|
||||
{
|
||||
K_BotGenericPressItem(player, cmd, throwdir);
|
||||
}
|
||||
|
|
@ -720,6 +748,7 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd)
|
|||
--------------------------------------------------*/
|
||||
static boolean K_BotRevealsEggbox(player_t *player)
|
||||
{
|
||||
const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
|
||||
const UINT8 stealth = K_EggboxStealth(player->mo->x, player->mo->y);
|
||||
player_t *target = NULL;
|
||||
|
||||
|
|
@ -737,7 +766,7 @@ static boolean K_BotRevealsEggbox(player_t *player)
|
|||
}
|
||||
|
||||
// Check your behind.
|
||||
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
|
||||
target = K_PlayerInCone(player, coneDist, 15, true);
|
||||
if (target != NULL)
|
||||
{
|
||||
return true;
|
||||
|
|
@ -810,8 +839,9 @@ static void K_BotItemEggmanExplosion(player_t *player, ticcmd_t *cmd)
|
|||
static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
const fixed_t topspeed = K_GetKartSpeed(player, false);
|
||||
fixed_t radius = (player->mo->radius * 32);
|
||||
fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
|
||||
SINT8 throwdir = -1;
|
||||
boolean tryLookback = false;
|
||||
UINT8 snipeMul = 2;
|
||||
player_t *target = NULL;
|
||||
|
||||
|
|
@ -823,24 +853,30 @@ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
player->botvars.itemconfirm++;
|
||||
|
||||
target = K_PlayerInCone(player, radius, 10, false);
|
||||
target = K_PlayerInCone(player, radius, 15, false);
|
||||
if (target != NULL)
|
||||
{
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty * snipeMul);
|
||||
throwdir = 1;
|
||||
}
|
||||
else if (K_PlayerInCone(player, radius, 10, true))
|
||||
else
|
||||
{
|
||||
target = K_PlayerInCone(player, radius, 10, true);
|
||||
target = K_PlayerInCone(player, radius, 15, true);
|
||||
|
||||
if (target != NULL)
|
||||
{
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
|
||||
throwdir = -1;
|
||||
tryLookback = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 5*TICRATE)
|
||||
if (tryLookback == true && throwdir == -1)
|
||||
{
|
||||
cmd->buttons |= BT_LOOKBACK;
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 25*TICRATE)
|
||||
{
|
||||
K_BotGenericPressItem(player, cmd, throwdir);
|
||||
}
|
||||
|
|
@ -861,8 +897,9 @@ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd)
|
|||
static void K_BotItemJawz(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
const fixed_t topspeed = K_GetKartSpeed(player, false);
|
||||
fixed_t radius = (player->mo->radius * 32);
|
||||
fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
|
||||
SINT8 throwdir = 1;
|
||||
boolean tryLookback = false;
|
||||
UINT8 snipeMul = 2;
|
||||
INT32 lastTarg = player->lastjawztarget;
|
||||
player_t *target = NULL;
|
||||
|
|
@ -875,11 +912,12 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
player->botvars.itemconfirm++;
|
||||
|
||||
target = K_PlayerInCone(player, radius, 10, true);
|
||||
target = K_PlayerInCone(player, radius, 15, true);
|
||||
if (target != NULL)
|
||||
{
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
|
||||
throwdir = -1;
|
||||
tryLookback = true;
|
||||
}
|
||||
|
||||
if (lastTarg != -1
|
||||
|
|
@ -913,7 +951,12 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd)
|
|||
}
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 5*TICRATE)
|
||||
if (tryLookback == true && throwdir == -1)
|
||||
{
|
||||
cmd->buttons |= BT_LOOKBACK;
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 25*TICRATE)
|
||||
{
|
||||
K_BotGenericPressItem(player, cmd, throwdir);
|
||||
}
|
||||
|
|
@ -1007,7 +1050,7 @@ static void K_BotItemBubble(player_t *player, ticcmd_t *cmd)
|
|||
}
|
||||
else if (player->bubbleblowup >= bubbletime)
|
||||
{
|
||||
if (player->botvars.itemconfirm >= 10*TICRATE)
|
||||
if (player->botvars.itemconfirm > 10*TICRATE)
|
||||
{
|
||||
hold = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -619,7 +619,7 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
fixed_t avgX = 0, avgY = 0;
|
||||
fixed_t avgDist = 0;
|
||||
|
||||
const fixed_t baseNudge = 128 * mapobjectscale;
|
||||
const fixed_t baseNudge = predict->radius;
|
||||
fixed_t maxNudge = distToPredict;
|
||||
fixed_t nudgeDist = 0;
|
||||
angle_t nudgeDir = 0;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
|||
boolean damageitem = false;
|
||||
boolean sprung = false;
|
||||
|
||||
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
|
||||
return true;
|
||||
|
||||
if (((t1->target == t2) || (t1->target == t2->target)) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||
return true;
|
||||
|
||||
|
|
@ -45,7 +48,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
|||
else
|
||||
{
|
||||
// Player Damage
|
||||
P_DamageMobj(t2, t1, t1->target, 1, DMG_WIPEOUT);
|
||||
P_DamageMobj(t2, t1, t1->target, 1, DMG_WIPEOUT|DMG_WOMBO);
|
||||
K_KartBouncing(t2, t1);
|
||||
S_StartSound(t2, sfx_s3k7b);
|
||||
}
|
||||
|
|
@ -108,6 +111,9 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|
|||
{
|
||||
boolean damageitem = false;
|
||||
|
||||
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
|
||||
return true;
|
||||
|
||||
if (((t1->target == t2) || (t1->target == t2->target)) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||
return true;
|
||||
|
||||
|
|
@ -137,7 +143,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|
|||
}
|
||||
else
|
||||
{
|
||||
P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL);
|
||||
P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL|DMG_WOMBO);
|
||||
}
|
||||
|
||||
damageitem = true;
|
||||
|
|
@ -186,6 +192,9 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
|
||||
{
|
||||
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
|
||||
return true;
|
||||
|
||||
// Push fakes out of other item boxes
|
||||
if (t2->type == MT_RANDOMITEM || t2->type == MT_EGGMANITEM)
|
||||
{
|
||||
|
|
@ -258,6 +267,9 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
boolean K_MineCollide(mobj_t *t1, mobj_t *t2)
|
||||
{
|
||||
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
|
||||
return true;
|
||||
|
||||
if (((t1->target == t2) || (t1->target == t2->target)) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||
return true;
|
||||
|
||||
|
|
@ -331,6 +343,9 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
|
||||
{
|
||||
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
|
||||
return true;
|
||||
|
||||
if (((t1->target == t2) || (t1->target == t2->target)) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||
return true;
|
||||
|
||||
|
|
@ -398,6 +413,9 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2)
|
||||
{
|
||||
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
|
||||
return true;
|
||||
|
||||
if (((t1->target == t2) || (t1->target == t2->target)) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||
return true;
|
||||
|
||||
|
|
@ -465,7 +483,8 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
|||
{
|
||||
boolean t1Condition = false;
|
||||
boolean t2Condition = false;
|
||||
boolean stung = false;
|
||||
boolean stungT1 = false;
|
||||
boolean stungT2 = false;
|
||||
|
||||
// Grow damage
|
||||
t1Condition = (t1->scale > t2->scale + (mapobjectscale/8));
|
||||
|
|
@ -473,12 +492,12 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
if (t1Condition == true && t2Condition == false)
|
||||
{
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE);
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE|DMG_WOMBO);
|
||||
return true;
|
||||
}
|
||||
else if (t1Condition == false && t2Condition == true)
|
||||
{
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE);
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE|DMG_WOMBO);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -488,12 +507,12 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
if (t1Condition == true && t2Condition == false)
|
||||
{
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE);
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE|DMG_WOMBO);
|
||||
return true;
|
||||
}
|
||||
else if (t1Condition == false && t2Condition == true)
|
||||
{
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE);
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE|DMG_WOMBO);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -503,12 +522,12 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
if (t1Condition == true && t2Condition == false)
|
||||
{
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_WIPEOUT);
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_WIPEOUT|DMG_WOMBO);
|
||||
return true;
|
||||
}
|
||||
else if (t1Condition == false && t2Condition == true)
|
||||
{
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT);
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT|DMG_WOMBO);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -521,12 +540,12 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
if (t1Condition == true && t2Condition == false)
|
||||
{
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_WIPEOUT|DMG_STEAL);
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_WIPEOUT|DMG_STEAL|DMG_WOMBO);
|
||||
return true;
|
||||
}
|
||||
else if (t1Condition == false && t2Condition == true)
|
||||
{
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT|DMG_STEAL);
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT|DMG_STEAL|DMG_WOMBO);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -537,25 +556,35 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
if (t1Condition == true)
|
||||
{
|
||||
P_PlayerRingBurst(t2->player, 1);
|
||||
|
||||
if (t2->player->rings <= 0)
|
||||
{
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_STING);
|
||||
stung = true;
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_STING|DMG_WOMBO);
|
||||
stungT2 = true;
|
||||
}
|
||||
|
||||
P_PlayerRingBurst(t2->player, 1);
|
||||
}
|
||||
|
||||
if (t2Condition == true)
|
||||
{
|
||||
P_PlayerRingBurst(t1->player, 1);
|
||||
|
||||
if (t1->player->rings <= 0)
|
||||
{
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_STING);
|
||||
stung = true;
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_STING|DMG_WOMBO);
|
||||
stungT1 = true;
|
||||
}
|
||||
|
||||
P_PlayerRingBurst(t1->player, 1);
|
||||
}
|
||||
|
||||
return stung;
|
||||
// No damage hitlag for stinging.
|
||||
if (stungT1 == true && stungT2 == false)
|
||||
{
|
||||
t2->eflags &= ~MFE_DAMAGEHITLAG;
|
||||
}
|
||||
else if (stungT2 == true && stungT1 == false)
|
||||
{
|
||||
t1->eflags &= ~MFE_DAMAGEHITLAG;
|
||||
}
|
||||
|
||||
return (stungT1 || stungT2);
|
||||
}
|
||||
|
|
|
|||
294
src/k_director.c
Normal file
294
src/k_director.c
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_director.c
|
||||
/// \brief SRB2kart automatic spectator camera.
|
||||
|
||||
#include "k_kart.h"
|
||||
#include "k_respawn.h"
|
||||
#include "doomdef.h"
|
||||
#include "g_game.h"
|
||||
#include "v_video.h"
|
||||
#include "k_director.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "p_local.h"
|
||||
|
||||
#define SWITCHTIME TICRATE * 5 // cooldown between unforced switches
|
||||
#define BOREDOMTIME 3 * TICRATE / 2 // how long until players considered far apart?
|
||||
#define TRANSFERTIME TICRATE // how long to delay reaction shots?
|
||||
#define BREAKAWAYDIST 4000 // how *far* until players considered far apart?
|
||||
#define WALKBACKDIST 600 // how close should a trailing player be before we switch?
|
||||
#define PINCHDIST 30000 // how close should the leader be to be considered "end of race"?
|
||||
|
||||
struct directorinfo directorinfo;
|
||||
|
||||
void K_InitDirector(void)
|
||||
{
|
||||
INT32 playernum;
|
||||
|
||||
directorinfo.cooldown = SWITCHTIME;
|
||||
directorinfo.freeze = 0;
|
||||
directorinfo.attacker = 0;
|
||||
directorinfo.maxdist = 0;
|
||||
|
||||
for (playernum = 0; playernum < MAXPLAYERS; playernum++)
|
||||
{
|
||||
directorinfo.sortedplayers[playernum] = -1;
|
||||
directorinfo.gap[playernum] = INT32_MAX;
|
||||
directorinfo.boredom[playernum] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static fixed_t K_GetFinishGap(INT32 leader, INT32 follower)
|
||||
{
|
||||
fixed_t dista = players[follower].distancetofinish;
|
||||
fixed_t distb = players[leader].distancetofinish;
|
||||
|
||||
if (players[follower].position < players[leader].position)
|
||||
{
|
||||
return distb - dista;
|
||||
}
|
||||
else
|
||||
{
|
||||
return dista - distb;
|
||||
}
|
||||
}
|
||||
|
||||
static void K_UpdateDirectorPositions(void)
|
||||
{
|
||||
INT32 playernum;
|
||||
INT32 position;
|
||||
player_t* target;
|
||||
|
||||
memset(directorinfo.sortedplayers, -1, sizeof(directorinfo.sortedplayers));
|
||||
|
||||
for (playernum = 0; playernum < MAXPLAYERS; playernum++)
|
||||
{
|
||||
target = &players[playernum];
|
||||
|
||||
if (playeringame[playernum] && !target->spectator && target->position > 0)
|
||||
{
|
||||
directorinfo.sortedplayers[target->position - 1] = playernum;
|
||||
}
|
||||
}
|
||||
|
||||
for (position = 0; position < MAXPLAYERS - 1; position++)
|
||||
{
|
||||
directorinfo.gap[position] = INT32_MAX;
|
||||
|
||||
if (directorinfo.sortedplayers[position] == -1 || directorinfo.sortedplayers[position + 1] == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
directorinfo.gap[position] = P_ScaleFromMap(K_GetFinishGap(directorinfo.sortedplayers[position], directorinfo.sortedplayers[position + 1]), FRACUNIT);
|
||||
|
||||
if (directorinfo.gap[position] >= BREAKAWAYDIST)
|
||||
{
|
||||
directorinfo.boredom[position] = min(BOREDOMTIME * 2, directorinfo.boredom[position] + 1);
|
||||
}
|
||||
else if (directorinfo.boredom[position] > 0)
|
||||
{
|
||||
directorinfo.boredom[position]--;
|
||||
}
|
||||
}
|
||||
|
||||
directorinfo.maxdist = P_ScaleFromMap(players[directorinfo.sortedplayers[0]].distancetofinish, FRACUNIT);
|
||||
}
|
||||
|
||||
static boolean K_CanSwitchDirector(void)
|
||||
{
|
||||
INT32 *displayplayerp = &displayplayers[0];
|
||||
|
||||
if (players[*displayplayerp].trickpanel > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (directorinfo.cooldown > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void K_DirectorSwitch(INT32 player, boolean force)
|
||||
{
|
||||
if (P_IsDisplayPlayer(&players[player]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (players[player].exiting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!force && !K_CanSwitchDirector())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
G_ResetView(1, player, true);
|
||||
directorinfo.cooldown = SWITCHTIME;
|
||||
}
|
||||
|
||||
static void K_DirectorForceSwitch(INT32 player, INT32 time)
|
||||
{
|
||||
if (players[player].exiting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
directorinfo.attacker = player;
|
||||
directorinfo.freeze = time;
|
||||
}
|
||||
|
||||
void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source)
|
||||
{
|
||||
if (!P_IsDisplayPlayer(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (inflictor && inflictor->player)
|
||||
{
|
||||
K_DirectorForceSwitch(inflictor->player - players, TRANSFERTIME);
|
||||
}
|
||||
else if (source && source->player)
|
||||
{
|
||||
K_DirectorForceSwitch(source->player - players, TRANSFERTIME);
|
||||
}
|
||||
}
|
||||
|
||||
void K_DrawDirectorDebugger(void)
|
||||
{
|
||||
INT32 position;
|
||||
INT32 leader;
|
||||
INT32 follower;
|
||||
INT32 ytxt;
|
||||
|
||||
if (!cv_kartdebugdirector.value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
V_DrawThinString(10, 0, V_70TRANS, va("PLACE"));
|
||||
V_DrawThinString(40, 0, V_70TRANS, va("CONF?"));
|
||||
V_DrawThinString(80, 0, V_70TRANS, va("GAP"));
|
||||
V_DrawThinString(120, 0, V_70TRANS, va("BORED"));
|
||||
V_DrawThinString(150, 0, V_70TRANS, va("COOLDOWN: %d", directorinfo.cooldown));
|
||||
V_DrawThinString(230, 0, V_70TRANS, va("MAXDIST: %d", directorinfo.maxdist));
|
||||
|
||||
for (position = 0; position < MAXPLAYERS - 1; position++)
|
||||
{
|
||||
ytxt = 10 * (position + 1);
|
||||
leader = directorinfo.sortedplayers[position];
|
||||
follower = directorinfo.sortedplayers[position + 1];
|
||||
|
||||
if (leader == -1 || follower == -1)
|
||||
break;
|
||||
|
||||
V_DrawThinString(10, ytxt, V_70TRANS, va("%d", position));
|
||||
V_DrawThinString(20, ytxt, V_70TRANS, va("%d", position + 1));
|
||||
|
||||
if (players[leader].positiondelay)
|
||||
{
|
||||
V_DrawThinString(40, ytxt, V_70TRANS, va("NG"));
|
||||
}
|
||||
|
||||
V_DrawThinString(80, ytxt, V_70TRANS, va("%d", directorinfo.gap[position]));
|
||||
|
||||
if (directorinfo.boredom[position] >= BOREDOMTIME)
|
||||
{
|
||||
V_DrawThinString(120, ytxt, V_70TRANS, va("BORED"));
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawThinString(120, ytxt, V_70TRANS, va("%d", directorinfo.boredom[position]));
|
||||
}
|
||||
|
||||
V_DrawThinString(150, ytxt, V_70TRANS, va("%s", player_names[leader]));
|
||||
V_DrawThinString(230, ytxt, V_70TRANS, va("%s", player_names[follower]));
|
||||
}
|
||||
}
|
||||
|
||||
void K_UpdateDirector(void)
|
||||
{
|
||||
INT32 *displayplayerp = &displayplayers[0];
|
||||
INT32 targetposition;
|
||||
|
||||
if (!cv_director.value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
K_UpdateDirectorPositions();
|
||||
|
||||
if (directorinfo.cooldown > 0) {
|
||||
directorinfo.cooldown--;
|
||||
}
|
||||
|
||||
// handle pending forced switches
|
||||
if (directorinfo.freeze > 0)
|
||||
{
|
||||
if (!(--directorinfo.freeze))
|
||||
K_DirectorSwitch(directorinfo.attacker, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// aaight, time to walk through the standings to find the first interesting pair
|
||||
// NB: targetposition/sortedplayers is 0-indexed, aiming at the "back half" of a given pair by default.
|
||||
// we adjust for this when comparing to player->position or when looking at the leading player, Don't Freak Out
|
||||
for (targetposition = 1; targetposition < MAXPLAYERS; targetposition++)
|
||||
{
|
||||
INT32 target;
|
||||
|
||||
// you are out of players, try again
|
||||
if (directorinfo.sortedplayers[targetposition] == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// pair too far apart? try the next one
|
||||
if (directorinfo.boredom[targetposition - 1] >= BOREDOMTIME)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// pair finished? try the next one
|
||||
if (players[directorinfo.sortedplayers[targetposition]].exiting)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't risk switching away from forward pairs at race end, might miss something!
|
||||
if (directorinfo.maxdist > PINCHDIST)
|
||||
{
|
||||
// if the "next" player is close enough, they should be able to see everyone fine!
|
||||
// walk back through the standings to find a vantage that gets everyone in frame.
|
||||
// (also creates a pretty cool effect w/ overtakes at speed)
|
||||
while (targetposition < MAXPLAYERS && directorinfo.gap[targetposition] < WALKBACKDIST)
|
||||
{
|
||||
targetposition++;
|
||||
}
|
||||
}
|
||||
|
||||
target = directorinfo.sortedplayers[targetposition];
|
||||
|
||||
// if we're certain the back half of the pair is actually in this position, try to switch
|
||||
if (*displayplayerp != target && !players[target].positiondelay)
|
||||
{
|
||||
K_DirectorSwitch(target, false);
|
||||
}
|
||||
|
||||
// even if we're not certain, if we're certain we're watching the WRONG player, try to switch
|
||||
if (players[*displayplayerp].position != targetposition+1 && !players[target].positiondelay)
|
||||
{
|
||||
K_DirectorSwitch(target, false);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
21
src/k_director.h
Normal file
21
src/k_director.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_director.h
|
||||
/// \brief SRB2kart automatic spectator camera.
|
||||
|
||||
extern struct directorinfo
|
||||
{
|
||||
tic_t cooldown; // how long has it been since we last switched?
|
||||
tic_t freeze; // when nonzero, fixed switch pending, freeze logic!
|
||||
INT32 attacker; // who to switch to when freeze delay elapses
|
||||
INT32 maxdist; // how far is the closest player from finishing?
|
||||
|
||||
INT32 sortedplayers[MAXPLAYERS]; // position-1 goes in, player index comes out.
|
||||
INT32 gap[MAXPLAYERS]; // gap between a given position and their closest pursuer
|
||||
INT32 boredom[MAXPLAYERS]; // how long has a given position had no credible attackers?
|
||||
} directorinfo;
|
||||
|
||||
void K_InitDirector(void);
|
||||
void K_UpdateDirector(void);
|
||||
void K_DrawDirectorDebugger(void);
|
||||
void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||
184
src/k_hud.c
184
src/k_hud.c
|
|
@ -13,6 +13,7 @@
|
|||
#include "k_kart.h"
|
||||
#include "k_battle.h"
|
||||
#include "k_color.h"
|
||||
#include "k_director.h"
|
||||
#include "screen.h"
|
||||
#include "doomtype.h"
|
||||
#include "doomdef.h"
|
||||
|
|
@ -31,6 +32,7 @@
|
|||
#include "r_main.h"
|
||||
#include "s_sound.h"
|
||||
#include "r_things.h"
|
||||
#include "r_fps.h"
|
||||
|
||||
#define NUMPOSNUMS 10
|
||||
#define NUMPOSFRAMES 7 // White, three blues, three reds
|
||||
|
|
@ -835,48 +837,26 @@ void K_ObjectTracking(trackingResult_t *result, vector3_t *point, UINT8 cameraNu
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO: needs da interp
|
||||
// TODO: parts need interp
|
||||
if (cam->chase == true && !player->spectator)
|
||||
{
|
||||
// Use the camera's properties.
|
||||
viewpointX = cam->x;
|
||||
viewpointY = cam->y;
|
||||
viewpointZ = cam->z - point->z;
|
||||
viewpointAngle = (INT32)cam->angle;
|
||||
viewpointAiming = (INT32)cam->aiming;
|
||||
viewpointRoll = (INT32)player->viewrollangle;
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
viewpointX = cam->old_x + FixedMul(rendertimefrac, cam->x - cam->old_x);
|
||||
viewpointY = cam->old_y + FixedMul(rendertimefrac, cam->y - cam->old_y);
|
||||
viewpointZ = (cam->old_z + FixedMul(rendertimefrac, cam->z - cam->old_z)) - point->z;
|
||||
|
||||
viewpointAngle = (INT32)(cam->old_angle + FixedMul(rendertimefrac, cam->angle - cam->old_angle));
|
||||
viewpointAiming = (INT32)(cam->old_aiming + FixedMul(rendertimefrac, cam->aiming - cam->old_aiming));
|
||||
viewpointRoll = (INT32)(player->old_viewrollangle + FixedMul(rendertimefrac, player->viewrollangle - player->old_viewrollangle));
|
||||
}
|
||||
viewpointX = R_InterpolateFixed(cam->old_x, cam->x);
|
||||
viewpointY = R_InterpolateFixed(cam->old_y, cam->y);
|
||||
viewpointZ = R_InterpolateFixed(cam->old_z, cam->z) - point->z;
|
||||
viewpointAngle = (INT32)R_InterpolateAngle(cam->old_angle, cam->angle);
|
||||
viewpointAiming = (INT32)R_InterpolateAngle(cam->old_aiming, cam->aiming);
|
||||
viewpointRoll = (INT32)R_InterpolateAngle(player->old_viewrollangle, player->viewrollangle);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use player properties.
|
||||
viewpointX = player->mo->x;
|
||||
viewpointY = player->mo->y;
|
||||
viewpointZ = player->viewz - point->z;
|
||||
viewpointAngle = (INT32)player->mo->angle;
|
||||
viewpointX = R_InterpolateFixed(player->mo->old_x, player->mo->x);
|
||||
viewpointY = R_InterpolateFixed(player->mo->old_y, player->mo->y);
|
||||
viewpointZ = R_InterpolateFixed(player->mo->old_z, player->mo->z) - point->z; //player->old_viewz
|
||||
viewpointAngle = (INT32)R_InterpolateAngle(player->mo->old_angle, player->mo->angle);
|
||||
viewpointAiming = (INT32)player->aiming;
|
||||
viewpointRoll = (INT32)player->viewrollangle;
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
viewpointX = player->mo->old_x + FixedMul(rendertimefrac, player->mo->x - player->mo->old_x);
|
||||
viewpointY = player->mo->old_y + FixedMul(rendertimefrac, player->mo->y - player->mo->old_y);
|
||||
viewpointZ = (player->mo->old_z + FixedMul(rendertimefrac, player->viewz - player->mo->old_z)) - point->z; //player->old_viewz
|
||||
|
||||
viewpointAngle = (INT32)(player->mo->old_angle + FixedMul(rendertimefrac, player->mo->angle - player->mo->old_angle));
|
||||
//viewpointAiming = (INT32)(player->mo->old_aiming + FixedMul(rendertimefrac, player->mo->aiming - player->mo->old_aiming));
|
||||
viewpointRoll = (INT32)(player->old_viewrollangle + FixedMul(rendertimefrac, player->viewrollangle - player->old_viewrollangle));
|
||||
}
|
||||
viewpointRoll = (INT32)R_InterpolateAngle(player->old_viewrollangle, player->viewrollangle);
|
||||
}
|
||||
|
||||
viewpointAngle += (INT32)angleOffset;
|
||||
|
|
@ -2631,24 +2611,13 @@ static void K_drawKartPlayerCheck(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
v.x = checkplayer->mo->x;
|
||||
v.y = checkplayer->mo->y;
|
||||
v.z = checkplayer->mo->z;
|
||||
v.x = R_InterpolateFixed(checkplayer->mo->old_x, checkplayer->mo->x);
|
||||
v.y = R_InterpolateFixed(checkplayer->mo->old_y, checkplayer->mo->y);
|
||||
v.z = R_InterpolateFixed(checkplayer->mo->old_z, checkplayer->mo->z);
|
||||
|
||||
pPos.x = stplyr->mo->x;
|
||||
pPos.y = stplyr->mo->y;
|
||||
pPos.z = stplyr->mo->z;
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
v.x = checkplayer->mo->old_x + FixedMul(rendertimefrac, checkplayer->mo->x - checkplayer->mo->old_x);
|
||||
v.y = checkplayer->mo->old_y + FixedMul(rendertimefrac, checkplayer->mo->y - checkplayer->mo->old_y);
|
||||
v.z = checkplayer->mo->old_z + FixedMul(rendertimefrac, checkplayer->mo->z - checkplayer->mo->old_z);
|
||||
|
||||
pPos.x = stplyr->mo->old_x + FixedMul(rendertimefrac, stplyr->mo->x - stplyr->mo->old_x);
|
||||
pPos.y = stplyr->mo->old_y + FixedMul(rendertimefrac, stplyr->mo->y - stplyr->mo->old_y);
|
||||
pPos.z = stplyr->mo->old_z + FixedMul(rendertimefrac, stplyr->mo->z - stplyr->mo->old_z);
|
||||
}
|
||||
pPos.x = R_InterpolateFixed(stplyr->mo->old_x, stplyr->mo->x);
|
||||
pPos.y = R_InterpolateFixed(stplyr->mo->old_y, stplyr->mo->y);
|
||||
pPos.z = R_InterpolateFixed(stplyr->mo->old_z, stplyr->mo->z);
|
||||
|
||||
distance = R_PointToDist2(pPos.x, pPos.y, v.x, v.y);
|
||||
|
||||
|
|
@ -2834,29 +2803,15 @@ static void K_drawKartNameTags(void)
|
|||
|
||||
if (thiscam->chase == true)
|
||||
{
|
||||
c.x = thiscam->x;
|
||||
c.y = thiscam->y;
|
||||
c.z = thiscam->z;
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
c.x = thiscam->old_x + FixedMul(rendertimefrac, thiscam->x - thiscam->old_x);
|
||||
c.y = thiscam->old_y + FixedMul(rendertimefrac, thiscam->y - thiscam->old_y);
|
||||
c.z = thiscam->old_z + FixedMul(rendertimefrac, thiscam->z - thiscam->old_z);
|
||||
}
|
||||
c.x = R_InterpolateFixed(thiscam->old_x, thiscam->x);
|
||||
c.y = R_InterpolateFixed(thiscam->old_y, thiscam->y);
|
||||
c.z = R_InterpolateFixed(thiscam->old_z, thiscam->z);
|
||||
}
|
||||
else
|
||||
{
|
||||
c.x = stplyr->mo->x;
|
||||
c.y = stplyr->mo->y;
|
||||
c.z = stplyr->mo->z;
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
c.x = stplyr->mo->old_x + FixedMul(rendertimefrac, stplyr->mo->x - stplyr->mo->old_x);
|
||||
c.y = stplyr->mo->old_y + FixedMul(rendertimefrac, stplyr->mo->y - stplyr->mo->old_y);
|
||||
c.z = stplyr->mo->old_z + FixedMul(rendertimefrac, stplyr->mo->z - stplyr->mo->old_z);
|
||||
}
|
||||
c.x = R_InterpolateFixed(stplyr->mo->old_x, stplyr->mo->x);
|
||||
c.y = R_InterpolateFixed(stplyr->mo->old_y, stplyr->mo->y);
|
||||
c.z = R_InterpolateFixed(stplyr->mo->old_z, stplyr->mo->z);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
@ -2895,16 +2850,9 @@ static void K_drawKartNameTags(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
v.x = ntplayer->mo->x;
|
||||
v.y = ntplayer->mo->y;
|
||||
v.z = ntplayer->mo->z;
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
v.x = ntplayer->mo->old_x + FixedMul(rendertimefrac, ntplayer->mo->x - ntplayer->mo->old_x);
|
||||
v.y = ntplayer->mo->old_y + FixedMul(rendertimefrac, ntplayer->mo->y - ntplayer->mo->old_y);
|
||||
v.z = ntplayer->mo->old_z + FixedMul(rendertimefrac, ntplayer->mo->z - ntplayer->mo->old_z);
|
||||
}
|
||||
v.x = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->x);
|
||||
v.y = R_InterpolateFixed(ntplayer->mo->old_y, ntplayer->mo->y);
|
||||
v.z = R_InterpolateFixed(ntplayer->mo->old_z, ntplayer->mo->z);
|
||||
|
||||
if (!(ntplayer->mo->eflags & MFE_VERTICALFLIP))
|
||||
{
|
||||
|
|
@ -2959,16 +2907,9 @@ static void K_drawKartNameTags(void)
|
|||
SINT8 localindicator = -1;
|
||||
vector3_t v;
|
||||
|
||||
v.x = ntplayer->mo->x;
|
||||
v.y = ntplayer->mo->y;
|
||||
v.z = ntplayer->mo->z;
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
v.x = ntplayer->mo->old_x + FixedMul(rendertimefrac, ntplayer->mo->x - ntplayer->mo->old_x);
|
||||
v.y = ntplayer->mo->old_y + FixedMul(rendertimefrac, ntplayer->mo->y - ntplayer->mo->old_y);
|
||||
v.z = ntplayer->mo->old_z + FixedMul(rendertimefrac, ntplayer->mo->z - ntplayer->mo->old_z);
|
||||
}
|
||||
v.x = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->x);
|
||||
v.y = R_InterpolateFixed(ntplayer->mo->old_y, ntplayer->mo->y);
|
||||
v.z = R_InterpolateFixed(ntplayer->mo->old_z, ntplayer->mo->z);
|
||||
|
||||
v.z += (ntplayer->mo->height / 2);
|
||||
|
||||
|
|
@ -3208,14 +3149,8 @@ static void K_drawKartMinimap(void)
|
|||
else
|
||||
colormap = NULL;
|
||||
|
||||
interpx = g->mo->x;
|
||||
interpy = g->mo->y;
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
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);
|
||||
}
|
||||
interpx = R_InterpolateFixed(g->mo->old_x, g->mo->x);
|
||||
interpy = R_InterpolateFixed(g->mo->old_y, g->mo->y);
|
||||
|
||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
|
||||
g = g->next;
|
||||
|
|
@ -3273,14 +3208,8 @@ static void K_drawKartMinimap(void)
|
|||
else
|
||||
colormap = NULL;
|
||||
|
||||
interpx = players[i].mo->x;
|
||||
interpy = players[i].mo->y;
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
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);
|
||||
}
|
||||
interpx = R_InterpolateFixed(players[i].mo->old_x, players[i].mo->x);
|
||||
interpy = R_InterpolateFixed(players[i].mo->old_y, players[i].mo->y);
|
||||
|
||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
|
||||
// Target reticule
|
||||
|
|
@ -3308,14 +3237,8 @@ static void K_drawKartMinimap(void)
|
|||
colormap = R_GetTranslationColormap(TC_RAINBOW, mobj->color, GTC_CACHE);
|
||||
}
|
||||
|
||||
interpx = mobj->x;
|
||||
interpy = mobj->y;
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
interpx = mobj->old_x + FixedMul(rendertimefrac, mobj->x - mobj->old_x);
|
||||
interpy = mobj->old_y + FixedMul(rendertimefrac, mobj->y - mobj->old_y);
|
||||
}
|
||||
interpx = R_InterpolateFixed(mobj->old_x, mobj->x);
|
||||
interpy = R_InterpolateFixed(mobj->old_y, mobj->y);
|
||||
|
||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_spbminimap, colormap, AutomapPic);
|
||||
}
|
||||
|
|
@ -3345,14 +3268,8 @@ static void K_drawKartMinimap(void)
|
|||
else
|
||||
colormap = NULL;
|
||||
|
||||
interpx = players[localplayers[i]].mo->x;
|
||||
interpy = players[localplayers[i]].mo->y;
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
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);
|
||||
}
|
||||
interpx = R_InterpolateFixed(players[localplayers[i]].mo->old_x, players[localplayers[i]].mo->x);
|
||||
interpy = R_InterpolateFixed(players[localplayers[i]].mo->old_y, players[localplayers[i]].mo->y);
|
||||
|
||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
|
||||
|
||||
|
|
@ -3631,7 +3548,7 @@ static void K_drawKartFinish(void)
|
|||
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);
|
||||
interpx = R_InterpolateFixed(ox, x);
|
||||
|
||||
if (r_splitscreen && stplyr == &players[displayplayers[1]])
|
||||
interpx = -interpx;
|
||||
|
|
@ -4028,7 +3945,7 @@ static void K_drawLapStartAnim(void)
|
|||
const UINT8 t = stplyr->karthud[khud_lapanimation];
|
||||
const UINT8 progress = 80 - t;
|
||||
|
||||
const UINT8 tOld = t - 1;
|
||||
const UINT8 tOld = t + 1;
|
||||
const UINT8 progressOld = 80 - tOld;
|
||||
|
||||
const tic_t leveltimeOld = leveltime - 1;
|
||||
|
|
@ -4039,11 +3956,11 @@ static void K_drawLapStartAnim(void)
|
|||
|
||||
newval = (BASEVIDWIDTH/2 + (32 * max(0, t - 76))) * FRACUNIT;
|
||||
oldval = (BASEVIDWIDTH/2 + (32 * max(0, tOld - 76))) * FRACUNIT;
|
||||
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
interpx = R_InterpolateFixed(oldval, newval);
|
||||
|
||||
newval = (48 - (32 * max(0, progress - 76))) * FRACUNIT;
|
||||
oldval = (48 - (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||
interpy = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
interpy = R_InterpolateFixed(oldval, newval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, interpy,
|
||||
|
|
@ -4054,7 +3971,7 @@ static void K_drawLapStartAnim(void)
|
|||
{
|
||||
newval = (4 - abs((signed)((leveltime % 8) - 4))) * FRACUNIT;
|
||||
oldval = (4 - abs((signed)((leveltimeOld % 8) - 4))) * FRACUNIT;
|
||||
interpy += oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
interpy += R_InterpolateFixed(oldval, newval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, interpy,
|
||||
|
|
@ -4066,7 +3983,7 @@ static void K_drawLapStartAnim(void)
|
|||
{
|
||||
newval = (62 - (32 * max(0, progress - 76))) * FRACUNIT;
|
||||
oldval = (62 - (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
interpx = R_InterpolateFixed(oldval, newval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, // 27
|
||||
|
|
@ -4078,7 +3995,7 @@ static void K_drawLapStartAnim(void)
|
|||
{
|
||||
newval = (188 + (32 * max(0, progress - 76))) * FRACUNIT;
|
||||
oldval = (188 + (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
interpx = R_InterpolateFixed(oldval, newval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, // 194
|
||||
|
|
@ -4091,7 +4008,7 @@ static void K_drawLapStartAnim(void)
|
|||
{
|
||||
newval = (82 - (32 * max(0, progress - 76))) * FRACUNIT;
|
||||
oldval = (82 - (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
interpx = R_InterpolateFixed(oldval, newval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, // 61
|
||||
|
|
@ -4103,7 +4020,7 @@ static void K_drawLapStartAnim(void)
|
|||
{
|
||||
newval = (188 + (32 * max(0, progress - 76))) * FRACUNIT;
|
||||
oldval = (188 + (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
interpx = R_InterpolateFixed(oldval, newval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, // 194
|
||||
|
|
@ -4115,7 +4032,7 @@ static void K_drawLapStartAnim(void)
|
|||
{
|
||||
newval = (208 + (32 * max(0, progress - 76))) * FRACUNIT;
|
||||
oldval = (208 + (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
|
||||
interpx = R_InterpolateFixed(oldval, newval);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
interpx, // 221
|
||||
|
|
@ -4588,6 +4505,7 @@ void K_drawKartHUD(void)
|
|||
}
|
||||
|
||||
K_DrawWaypointDebugger();
|
||||
K_DrawDirectorDebugger();
|
||||
|
||||
if (gametype == GT_BATTLE)
|
||||
{
|
||||
|
|
|
|||
495
src/k_kart.c
495
src/k_kart.c
File diff suppressed because it is too large
Load diff
15
src/k_kart.h
15
src/k_kart.h
|
|
@ -22,6 +22,12 @@ Make sure this matches the actual number of states
|
|||
#define MAXHITLAGTICS 18 //12
|
||||
#define HITLAGJITTERS (FRACUNIT / 20)
|
||||
|
||||
#define GROW_SCALE (2*FRACUNIT)
|
||||
#define SHRINK_SCALE (FRACUNIT/2)
|
||||
|
||||
#define GROW_PHYSICS_SCALE (3*FRACUNIT/2)
|
||||
#define SHRINK_PHYSICS_SCALE (3*FRACUNIT/4)
|
||||
|
||||
player_t *K_GetItemBoxPlayer(mobj_t *mobj);
|
||||
angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed);
|
||||
|
||||
|
|
@ -76,7 +82,7 @@ void K_RunFinishLineBeam(void);
|
|||
UINT16 K_DriftSparkColor(player_t *player, INT32 charge);
|
||||
void K_SpawnBoostTrail(player_t *player);
|
||||
void K_SpawnSparkleTrail(mobj_t *mo);
|
||||
void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad);
|
||||
void K_SpawnWipeoutTrail(mobj_t *mo);
|
||||
void K_SpawnDraftDust(mobj_t *mo);
|
||||
void K_DriftDustHandling(mobj_t *spawner);
|
||||
void K_Squish(mobj_t *mo);
|
||||
|
|
@ -115,10 +121,13 @@ boolean K_WaterRun(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_GrowShrinkSpeedMul(player_t *player);
|
||||
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed);
|
||||
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower);
|
||||
fixed_t K_GetKartAccel(player_t *player);
|
||||
UINT16 K_GetKartFlashing(player_t *player);
|
||||
boolean K_PlayerShrinkCheat(player_t *player);
|
||||
void K_UpdateShrinkCheat(player_t *player);
|
||||
boolean K_KartKickstart(player_t *player);
|
||||
UINT16 K_GetKartButtons(player_t *player);
|
||||
SINT8 K_GetForwardMove(player_t *player);
|
||||
|
|
@ -141,5 +150,9 @@ void K_PlayPainSound(mobj_t *source);
|
|||
void K_PlayHitEmSound(mobj_t *source);
|
||||
void K_PlayPowerGloatSound(mobj_t *source);
|
||||
|
||||
fixed_t K_ItemScaleForPlayer(player_t *player);
|
||||
void K_SetItemOut(player_t *player);
|
||||
void K_UnsetItemOut(player_t *player);
|
||||
|
||||
// =========================================================================
|
||||
#endif // __K_KART__
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ static void K_DrawFinishLineBeamForLine(fixed_t offset, angle_t aiming, line_t *
|
|||
|
||||
P_SetMobjState(end1, S_FINISHBEAMEND1);
|
||||
end1->renderflags = RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(&players[displayplayers[i]]);
|
||||
end1->angle = lineangle;
|
||||
P_InitAngle(end1, lineangle);
|
||||
|
||||
end2 = P_SpawnMobj(
|
||||
v->x + (8*sx),
|
||||
|
|
@ -381,7 +381,7 @@ static void K_DrawFinishLineBeamForLine(fixed_t offset, angle_t aiming, line_t *
|
|||
|
||||
P_SetMobjState(end2, S_FINISHBEAMEND2);
|
||||
end2->renderflags = RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(&players[displayplayers[i]]);
|
||||
end2->angle = lineangle;
|
||||
P_InitAngle(end2, lineangle);
|
||||
|
||||
P_SetTarget(&end2->tracer, end1);
|
||||
end2->flags2 |= MF2_LINKDRAW;
|
||||
|
|
|
|||
|
|
@ -582,7 +582,7 @@ static void K_MovePlayerToRespawnPoint(player_t *player)
|
|||
|
||||
P_SetTarget(&lasermo->target, player->mo);
|
||||
|
||||
lasermo->angle = stepha + ANGLE_90;
|
||||
P_InitAngle(lasermo, stepha + ANGLE_90);
|
||||
P_SetScale(lasermo, (lasermo->destscale = player->mo->scale));
|
||||
}
|
||||
}
|
||||
|
|
@ -645,7 +645,7 @@ static void K_DropDashWait(player_t *player)
|
|||
|
||||
P_SetTarget(&laser->target, player->mo);
|
||||
|
||||
laser->angle = newangle + ANGLE_90;
|
||||
P_InitAngle(laser, newangle + ANGLE_90);
|
||||
laser->momz = (8 * player->mo->scale) * P_MobjFlip(player->mo);
|
||||
P_SetScale(laser, (laser->destscale = player->mo->scale));
|
||||
}
|
||||
|
|
@ -672,11 +672,11 @@ static void K_HandleDropDash(player_t *player)
|
|||
if (player->growshrinktimer < 0)
|
||||
{
|
||||
player->mo->scalespeed = mapobjectscale/TICRATE;
|
||||
player->mo->destscale = (6*mapobjectscale)/8;
|
||||
player->mo->destscale = FixedMul(mapobjectscale, SHRINK_SCALE);
|
||||
|
||||
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
|
||||
if (K_PlayerShrinkCheat(player) == true)
|
||||
{
|
||||
player->mo->destscale = (6*player->mo->destscale)/8;
|
||||
player->mo->destscale = FixedMul(player->mo->destscale, SHRINK_SCALE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
1532
src/k_terrain.c
Normal file
1532
src/k_terrain.c
Normal file
File diff suppressed because it is too large
Load diff
459
src/k_terrain.h
Normal file
459
src/k_terrain.h
Normal file
|
|
@ -0,0 +1,459 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2021 by ZDoom + GZDoom teams, and contributors
|
||||
// Copyright (C) 2021 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2021 by Kart Krew
|
||||
//
|
||||
// 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 k_terrain.h
|
||||
/// \brief Implementation of a TERRAIN-style lump for DRRR, ala GZDoom's codebase.
|
||||
|
||||
#ifndef __K_TERRAIN_H__
|
||||
#define __K_TERRAIN_H__
|
||||
|
||||
#include "doomdata.h"
|
||||
#include "doomdef.h"
|
||||
#include "doomtype.h"
|
||||
#include "m_fixed.h"
|
||||
#include "p_mobj.h"
|
||||
|
||||
#define TERRAIN_NAME_LEN 32
|
||||
|
||||
typedef struct t_splash_s
|
||||
{
|
||||
// Splash definition.
|
||||
// These are particles spawned when hitting the floor.
|
||||
|
||||
char name[TERRAIN_NAME_LEN]; // Lookup name.
|
||||
|
||||
UINT16 mobjType; // Thing type. MT_NULL to not spawn anything.
|
||||
UINT16 sfx; // Sound to play.
|
||||
fixed_t scale; // Thing scale multiplier.
|
||||
UINT16 color; // Colorize effect. SKINCOLOR_NONE has no colorize.
|
||||
|
||||
fixed_t pushH; // Push-out horizontal multiplier.
|
||||
fixed_t pushV; // Push-out vertical multiplier.
|
||||
fixed_t spread; // Randomized spread distance.
|
||||
angle_t cone; // Randomized angle of the push-out.
|
||||
|
||||
UINT8 numParticles; // Number of particles to spawn.
|
||||
} t_splash_t;
|
||||
|
||||
typedef struct t_footstep_s
|
||||
{
|
||||
// Footstep definition.
|
||||
// These are particles spawned when moving fast enough on a floor.
|
||||
|
||||
char name[TERRAIN_NAME_LEN]; // Lookup name.
|
||||
|
||||
UINT16 mobjType; // Thing type. MT_NULL to not spawn anything.
|
||||
UINT16 sfx; // Sound to play.
|
||||
fixed_t scale; // Thing scale multiplier.
|
||||
UINT16 color; // Colorize effect. SKINCOLOR_NONE has no colorize.
|
||||
|
||||
fixed_t pushH; // Push-out horizontal multiplier.
|
||||
fixed_t pushV; // Push-out vertical multiplier.
|
||||
fixed_t spread; // Randomized spread distance.
|
||||
angle_t cone; // Randomized angle of the push-out.
|
||||
|
||||
tic_t sfxFreq; // How frequently to play the sound.
|
||||
tic_t frequency; // How frequently to spawn the particles.
|
||||
fixed_t requiredSpeed; // Speed percentage you need to be at to trigger the particles.
|
||||
} t_footstep_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
// Terrain flag values.
|
||||
TRF_LIQUID = 1, // Texture water properties (wavy, slippery, etc)
|
||||
TRF_SNEAKERPANEL = 1<<1, // Texture is a booster
|
||||
TRF_STAIRJANK = 1<<2, // Texture is bumpy road
|
||||
TRF_TRIPWIRE = 1<<3 // Texture is a tripwire when used as a midtexture
|
||||
} terrain_flags_t;
|
||||
|
||||
typedef struct terrain_s
|
||||
{
|
||||
// Terrain definition.
|
||||
// These are all of the properties that the floor gets.
|
||||
|
||||
char name[TERRAIN_NAME_LEN]; // Lookup name.
|
||||
|
||||
size_t splashID; // Splash defintion ID.
|
||||
size_t footstepID; // Footstep defintion ID.
|
||||
|
||||
fixed_t friction; // The default friction of this texture.
|
||||
UINT8 offroad; // The default offroad level of this texture.
|
||||
INT16 damageType; // The default damage type of this texture. (Negative means no damage).
|
||||
UINT8 trickPanel; // Trick panel strength
|
||||
UINT32 flags; // Flag values (see: terrain_flags_t)
|
||||
} terrain_t;
|
||||
|
||||
typedef struct t_floor_s
|
||||
{
|
||||
// Terrain floor definition.
|
||||
// Ties texture names to a .
|
||||
|
||||
// (Could be optimized by using texture IDs instead of names,
|
||||
// but was concerned because I recall sooomething about those not being netsafe?
|
||||
// Someone confirm if I just hallucinated that. :V)
|
||||
|
||||
char textureName[9]; // Floor texture name.
|
||||
size_t terrainID; // Terrain definition ID.
|
||||
} t_floor_t;
|
||||
|
||||
/*--------------------------------------------------
|
||||
size_t K_GetSplashHeapIndex(t_splash_t *splash);
|
||||
|
||||
Returns a splash defintion's index in the
|
||||
splash definition heap.
|
||||
|
||||
Input Arguments:-
|
||||
splash - The splash definition to return the index of.
|
||||
|
||||
Return:-
|
||||
The splash heap index, SIZE_MAX if the splash was invalid.
|
||||
--------------------------------------------------*/
|
||||
|
||||
size_t K_GetSplashHeapIndex(t_splash_t *splash);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
size_t K_GetNumSplashDefs(void);
|
||||
|
||||
Returns the number of splash definitions.
|
||||
|
||||
Input Arguments:-
|
||||
None
|
||||
|
||||
Return:-
|
||||
Length of splashDefs.
|
||||
--------------------------------------------------*/
|
||||
|
||||
size_t K_GetNumSplashDefs(void);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
t_splash_t *K_GetSplashByIndex(size_t checkIndex);
|
||||
|
||||
Retrieves a splash definition by its heap index.
|
||||
|
||||
Input Arguments:-
|
||||
checkIndex - The heap index to retrieve.
|
||||
|
||||
Return:-
|
||||
The splash definition, NULL if it didn't exist.
|
||||
--------------------------------------------------*/
|
||||
|
||||
t_splash_t *K_GetSplashByIndex(size_t checkIndex);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
t_splash_t *K_GetSplashByName(const char *checkName);
|
||||
|
||||
Retrieves a splash definition by its lookup name.
|
||||
|
||||
Input Arguments:-
|
||||
checkName - The lookup name to retrieve.
|
||||
|
||||
Return:-
|
||||
The splash definition, NULL if it didn't exist.
|
||||
--------------------------------------------------*/
|
||||
|
||||
t_splash_t *K_GetSplashByName(const char *checkName);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
size_t K_GetFootstepHeapIndex(t_footstep_t *footstep);
|
||||
|
||||
Returns a footstep defintion's index in the
|
||||
footstep definition heap.
|
||||
|
||||
Input Arguments:-
|
||||
footstep - The footstep definition to return the index of.
|
||||
|
||||
Return:-
|
||||
The footstep heap index, SIZE_MAX if the footstep was invalid.
|
||||
--------------------------------------------------*/
|
||||
|
||||
size_t K_GetFootstepHeapIndex(t_footstep_t *footstep);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
size_t K_GetNumFootstepDefs(void);
|
||||
|
||||
Returns the number of footstep definitions.
|
||||
|
||||
Input Arguments:-
|
||||
None
|
||||
|
||||
Return:-
|
||||
Length of footstepDefs.
|
||||
--------------------------------------------------*/
|
||||
|
||||
size_t K_GetNumFootstepDefs(void);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
t_footstep_t *K_GetFootstepByIndex(size_t checkIndex);
|
||||
|
||||
Retrieves a footstep definition by its heap index.
|
||||
|
||||
Input Arguments:-
|
||||
checkIndex - The heap index to retrieve.
|
||||
|
||||
Return:-
|
||||
The footstep definition, NULL if it didn't exist.
|
||||
--------------------------------------------------*/
|
||||
|
||||
t_footstep_t *K_GetFootstepByIndex(size_t checkIndex);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
t_footstep_t *K_GetFootstepByName(const char *checkName);
|
||||
|
||||
Retrieves a footstep definition by its lookup name.
|
||||
|
||||
Input Arguments:-
|
||||
checkName - The lookup name to retrieve.
|
||||
|
||||
Return:-
|
||||
The footstep definition, NULL if it didn't exist.
|
||||
--------------------------------------------------*/
|
||||
|
||||
t_footstep_t *K_GetFootstepByName(const char *checkName);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
size_t K_GetTerrainHeapIndex(terrain_t *terrain);
|
||||
|
||||
Returns a terrain defintion's index in the
|
||||
terrain definition heap.
|
||||
|
||||
Input Arguments:-
|
||||
terrain - The terrain definition to return the index of.
|
||||
|
||||
Return:-
|
||||
The terrain heap index, SIZE_MAX if the terrain was invalid.
|
||||
--------------------------------------------------*/
|
||||
|
||||
size_t K_GetTerrainHeapIndex(terrain_t *terrain);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
size_t K_GetNumTerrainDefs(void);
|
||||
|
||||
Returns the number of terrain definitions.
|
||||
|
||||
Input Arguments:-
|
||||
None
|
||||
|
||||
Return:-
|
||||
Length of terrainDefs.
|
||||
--------------------------------------------------*/
|
||||
|
||||
size_t K_GetNumTerrainDefs(void);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
terrain_t *K_GetTerrainByIndex(size_t checkIndex);
|
||||
|
||||
Retrieves a terrain definition by its heap index.
|
||||
|
||||
Input Arguments:-
|
||||
checkIndex - The heap index to retrieve.
|
||||
|
||||
Return:-
|
||||
The terrain definition, NULL if it didn't exist.
|
||||
--------------------------------------------------*/
|
||||
|
||||
terrain_t *K_GetTerrainByIndex(size_t checkIndex);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
terrain_t *K_GetTerrainByName(const char *checkName);
|
||||
|
||||
Retrieves a terrain definition by its lookup name.
|
||||
|
||||
Input Arguments:-
|
||||
checkName - The lookup name to retrieve.
|
||||
|
||||
Return:-
|
||||
The terrain definition, NULL if it didn't exist.
|
||||
--------------------------------------------------*/
|
||||
|
||||
terrain_t *K_GetTerrainByName(const char *checkName);
|
||||
|
||||
/*--------------------------------------------------
|
||||
terrain_t *K_GetDefaultTerrain(void);
|
||||
|
||||
Returns the default terrain definition, used
|
||||
in cases where terrain is not set for a texture.
|
||||
|
||||
Input Arguments:-
|
||||
None
|
||||
|
||||
Return:-
|
||||
The default terrain definition, NULL if it didn't exist.
|
||||
--------------------------------------------------*/
|
||||
|
||||
terrain_t *K_GetDefaultTerrain(void);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
terrain_t *K_GetTerrainForTextureName(const char *checkName);
|
||||
|
||||
Returns the terrain definition applied to
|
||||
the texture name inputted.
|
||||
|
||||
Input Arguments:-
|
||||
checkName - The texture's name.
|
||||
|
||||
Return:-
|
||||
The texture's terrain definition if it exists,
|
||||
otherwise the default terrain if it exists,
|
||||
otherwise NULL.
|
||||
--------------------------------------------------*/
|
||||
|
||||
terrain_t *K_GetTerrainForTextureName(const char *checkName);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
terrain_t *K_GetTerrainForTextureNum(INT32 textureNum);
|
||||
|
||||
Returns the terrain definition applied to
|
||||
the texture ID inputted.
|
||||
|
||||
Input Arguments:-
|
||||
textureNum - The texture's ID.
|
||||
|
||||
Return:-
|
||||
The texture's terrain definition if it exists,
|
||||
otherwise the default terrain if it exists,
|
||||
otherwise NULL.
|
||||
--------------------------------------------------*/
|
||||
|
||||
terrain_t *K_GetTerrainForTextureNum(INT32 textureNum);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
terrain_t *K_GetTerrainForFlatNum(INT32 flatID);
|
||||
|
||||
Returns the terrain definition applied to
|
||||
the level flat ID.
|
||||
|
||||
Input Arguments:-
|
||||
flatID - The level flat's ID.
|
||||
|
||||
Return:-
|
||||
The level flat's terrain definition if it exists,
|
||||
otherwise the default terrain if it exists,
|
||||
otherwise NULL.
|
||||
--------------------------------------------------*/
|
||||
|
||||
terrain_t *K_GetTerrainForFlatNum(INT32 flatID);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_UpdateMobjTerrain(mobj_t *mo, INT32 flatID);
|
||||
|
||||
Updates an object's terrain pointer, based on
|
||||
the level flat ID supplied. Intended to be called
|
||||
when the object moves to new floors.
|
||||
|
||||
Input Arguments:-
|
||||
mo - The object to update.
|
||||
flatID - The level flat ID the object is standing on.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_UpdateMobjTerrain(mobj_t *mo, INT32 flatID);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_ProcessTerrainEffect(mobj_t *mo);
|
||||
|
||||
Handles applying terrain effects to the object,
|
||||
intended to be called in a thinker.
|
||||
|
||||
Currently only intended for players, but
|
||||
could be modified to be inclusive of all
|
||||
object types.
|
||||
|
||||
Input Arguments:-
|
||||
mo - The object to apply effects to.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_ProcessTerrainEffect(mobj_t *mo);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_SetDefaultFriction(mobj_t *mo);
|
||||
|
||||
Resets an object to their default friction values.
|
||||
If they are on terrain with different friction,
|
||||
they will update to that value.
|
||||
|
||||
Input Arguments:-
|
||||
mo - The object to reset the friction values of.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_SetDefaultFriction(mobj_t *mo);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_SpawnSplashForMobj(mobj_t *mo, fixed_t impact);
|
||||
|
||||
Spawns the splash particles for an object's
|
||||
terrain type. Intended to be called when hitting a floor.
|
||||
|
||||
Input Arguments:-
|
||||
mo - The object to spawn a splash for.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
void K_SpawnSplashForMobj(mobj_t *mo, fixed_t impact);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_HandleFootstepParticles(mobj_t *mo);
|
||||
|
||||
Spawns the footstep particles for an object's
|
||||
terrain type. Intended to be called every tic.
|
||||
|
||||
Input Arguments:-
|
||||
mo - The object to spawn footsteps for.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_HandleFootstepParticles(mobj_t *mo);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_InitTerrain(UINT16 wadNum);
|
||||
|
||||
Finds the TERRAIN lumps in a WAD/PK3, and
|
||||
processes all of them.
|
||||
|
||||
Input Arguments:-
|
||||
wadNum - WAD file ID to process.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_InitTerrain(UINT16 wadNum);
|
||||
|
||||
#endif // __K_TERRAIN_H__
|
||||
|
|
@ -1414,7 +1414,7 @@ static int lib_pTeleportMove(lua_State *L)
|
|||
INLEVEL
|
||||
if (!thing)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
LUA_Deprecated(L, "P_TeleportMove", "P_SetOrigin or P_MoveOrigin");
|
||||
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);
|
||||
|
|
@ -1455,6 +1455,42 @@ static int lib_pMoveOrigin(lua_State *L)
|
|||
return 2;
|
||||
}
|
||||
|
||||
static int lib_pInitAngle(lua_State *L)
|
||||
{
|
||||
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
angle_t newValue = luaL_checkangle(L, 2);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!thing)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
P_InitAngle(thing, newValue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pInitPitch(lua_State *L)
|
||||
{
|
||||
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
angle_t newValue = luaL_checkangle(L, 2);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!thing)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
P_InitPitch(thing, newValue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pInitRoll(lua_State *L)
|
||||
{
|
||||
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
angle_t newValue = luaL_checkangle(L, 2);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!thing)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
P_InitRoll(thing, newValue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pSlideMove(lua_State *L)
|
||||
{
|
||||
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
|
@ -1978,8 +2014,12 @@ static int lib_pSetSkyboxMobj(lua_State *L)
|
|||
if (w > 1 || w < 0)
|
||||
return luaL_error(L, "skybox mobj index %d is out of range for P_SetSkyboxMobj argument #2 (expected 0 or 1)", w);
|
||||
|
||||
#if 0
|
||||
if (!user || P_IsLocalPlayer(user))
|
||||
skyboxmo[w] = mo;
|
||||
#else
|
||||
CONS_Alert(CONS_WARNING, "TODO: P_SetSkyboxMobj is unimplemented\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3587,11 +3627,10 @@ static int lib_kSpawnSparkleTrail(lua_State *L)
|
|||
static int lib_kSpawnWipeoutTrail(lua_State *L)
|
||||
{
|
||||
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
boolean offroad = lua_optboolean(L, 2);
|
||||
NOHUD
|
||||
if (!mo)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
K_SpawnWipeoutTrail(mo, offroad);
|
||||
K_SpawnWipeoutTrail(mo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3871,6 +3910,9 @@ static luaL_Reg lib[] = {
|
|||
{"P_TeleportMove",lib_pTeleportMove},
|
||||
{"P_SetOrigin",lib_pSetOrigin},
|
||||
{"P_MoveOrigin",lib_pMoveOrigin},
|
||||
{"P_InitAngle",lib_pInitAngle},
|
||||
{"P_InitPitch",lib_pInitPitch},
|
||||
{"P_InitRoll",lib_pInitRoll},
|
||||
{"P_SlideMove",lib_pSlideMove},
|
||||
{"P_BounceMove",lib_pBounceMove},
|
||||
{"P_CheckSight", lib_pCheckSight},
|
||||
|
|
|
|||
|
|
@ -494,9 +494,6 @@ static int mobj_set(lua_State *L)
|
|||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter mobj_t in CMD building code!");
|
||||
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter mobj_t in BuildCMD code!");
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case mobj_valid:
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ static int player_get(lua_State *L)
|
|||
else if (fastcmp(field,"handleboost"))
|
||||
lua_pushinteger(L, plr->handleboost);
|
||||
else if (fastcmp(field,"boostangle"))
|
||||
lua_pushinteger(L, plr->boostangle);
|
||||
lua_pushangle(L, plr->boostangle);
|
||||
else if (fastcmp(field,"draftpower"))
|
||||
lua_pushinteger(L, plr->draftpower);
|
||||
else if (fastcmp(field,"draftleeway"))
|
||||
|
|
@ -499,9 +499,6 @@ static int player_set(lua_State *L)
|
|||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter player_t in CMD building code!");
|
||||
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter player_t in BuildCMD code!");
|
||||
|
||||
if (fastcmp(field,"mo")) {
|
||||
mobj_t *newmo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
||||
plr->mo->player = NULL; // remove player pointer from old mobj
|
||||
|
|
@ -626,7 +623,7 @@ static int player_set(lua_State *L)
|
|||
else if (fastcmp(field,"handleboost"))
|
||||
plr->handleboost = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"boostangle"))
|
||||
plr->boostangle = luaL_checkinteger(L, 3);
|
||||
plr->boostangle = luaL_checkangle(L, 3);
|
||||
else if (fastcmp(field,"draftpower"))
|
||||
plr->draftpower = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"draftleeway"))
|
||||
|
|
@ -861,7 +858,7 @@ static int karthud_set(lua_State *L)
|
|||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter player_t in BuildCMD code!");
|
||||
return luaL_error(L, "Do not alter player_t in CMD building code!");
|
||||
karthud[ks] = i;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
80
src/m_misc.c
80
src/m_misc.c
|
|
@ -2680,26 +2680,25 @@ const char *M_FileError(FILE *fp)
|
|||
|
||||
/** Return the number of parts of this path.
|
||||
*/
|
||||
int M_PathParts(const char *path)
|
||||
int M_PathParts(const char *p)
|
||||
{
|
||||
int n;
|
||||
const char *p;
|
||||
const char *t;
|
||||
if (path == NULL)
|
||||
int parts = 0;
|
||||
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
for (n = 0, p = path ;; ++n)
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!strncmp(&p[1], ":\\", 2))
|
||||
p += 3;
|
||||
#endif
|
||||
|
||||
while (*(p += strspn(p, PATHSEP)))
|
||||
{
|
||||
t = p;
|
||||
if (( p = strchr(p, PATHSEP[0]) ))
|
||||
p += strspn(p, PATHSEP);
|
||||
else
|
||||
{
|
||||
if (*t)/* there is something after the final delimiter */
|
||||
n++;
|
||||
break;
|
||||
}
|
||||
parts++;
|
||||
p += strcspn(p, PATHSEP);
|
||||
}
|
||||
return n;
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
/** Check whether a path is an absolute path.
|
||||
|
|
@ -2717,50 +2716,43 @@ boolean M_IsPathAbsolute(const char *path)
|
|||
*/
|
||||
void M_MkdirEachUntil(const char *cpath, int start, int end, int mode)
|
||||
{
|
||||
char path[MAX_WADPATH];
|
||||
char path[256];
|
||||
char *p;
|
||||
char *t;
|
||||
int n;
|
||||
int c;
|
||||
|
||||
if (end > 0 && end <= start)
|
||||
return;
|
||||
|
||||
strlcpy(path, cpath, sizeof path);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (strncmp(&path[1], ":\\", 2) == 0)
|
||||
if (!strncmp(&path[1], ":\\", 2))
|
||||
p = &path[3];
|
||||
else
|
||||
#endif
|
||||
p = path;
|
||||
|
||||
if (end > 0)
|
||||
end -= start;
|
||||
|
||||
for (; start > 0; --start)
|
||||
while (end != 0 && *(p += strspn(p, PATHSEP)))
|
||||
{
|
||||
p += strspn(p, PATHSEP);
|
||||
if (!( p = strchr(p, PATHSEP[0]) ))
|
||||
return;
|
||||
}
|
||||
p += strspn(p, PATHSEP);
|
||||
for (;;)
|
||||
{
|
||||
if (end > 0 && !--end)
|
||||
break;
|
||||
n = strcspn(p, PATHSEP);
|
||||
|
||||
t = p;
|
||||
if (( p = strchr(p, PATHSEP[0]) ))
|
||||
{
|
||||
*p = '\0';
|
||||
I_mkdir(path, mode);
|
||||
*p = PATHSEP[0];
|
||||
p += strspn(p, PATHSEP);
|
||||
}
|
||||
if (start > 0)
|
||||
start--;
|
||||
else
|
||||
{
|
||||
if (*t)
|
||||
I_mkdir(path, mode);
|
||||
break;
|
||||
c = p[n];
|
||||
p[n] = '\0';
|
||||
|
||||
I_mkdir(path, mode);
|
||||
|
||||
p[n] = c;
|
||||
}
|
||||
|
||||
p += n;
|
||||
|
||||
if (end > 0)
|
||||
end--;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2822,4 +2814,4 @@ const char * M_Ftrim (double f)
|
|||
dig[i + 1] = '\0';
|
||||
return &dig[1];/* skip the 0 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
28
src/mserv.c
28
src/mserv.c
|
|
@ -63,6 +63,8 @@ static void MasterServer_OnChange(void);
|
|||
|
||||
static void Advertise_OnChange(void);
|
||||
|
||||
static void RendezvousServer_OnChange(void);
|
||||
|
||||
static CV_PossibleValue_t masterserver_update_rate_cons_t[] = {
|
||||
{2, "MIN"},
|
||||
{60, "MAX"},
|
||||
|
|
@ -70,7 +72,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = {
|
|||
};
|
||||
|
||||
consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://ms.kartkrew.org/ms/api", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange);
|
||||
consvar_t cv_rendezvousserver = CVAR_INIT ("rendezvousserver", "jart-dev.jameds.org", CV_SAVE, NULL, NULL);
|
||||
consvar_t cv_rendezvousserver = CVAR_INIT ("rendezvousserver", "relay.kartkrew.org", CV_SAVE|CV_CALL, NULL, RendezvousServer_OnChange);
|
||||
consvar_t cv_servername = CVAR_INIT ("servername", "SRB2Kart server", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters);
|
||||
consvar_t cv_server_contact = CVAR_INIT ("server_contact", "", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters);
|
||||
|
||||
|
|
@ -517,17 +519,6 @@ static void MasterServer_OnChange(void)
|
|||
#ifdef MASTERSERVER
|
||||
UnregisterServer();
|
||||
|
||||
/*
|
||||
TODO: remove this for v2, it's just a hack
|
||||
for those coming in with an old config.
|
||||
*/
|
||||
if (
|
||||
! cv_masterserver.changed &&
|
||||
strcmp(cv_masterserver.string, "ms.srb2.org:28900") == 0
|
||||
){
|
||||
CV_StealthSet(&cv_masterserver, cv_masterserver.defaultvalue);
|
||||
}
|
||||
|
||||
Set_api(cv_masterserver.string);
|
||||
|
||||
if (Online())
|
||||
|
|
@ -565,3 +556,16 @@ Advertise_OnChange(void)
|
|||
DRPC_UpdatePresence();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEVELOP
|
||||
static void
|
||||
RendezvousServer_OnChange (void)
|
||||
{
|
||||
consvar_t *cvar = &cv_rendezvousserver;
|
||||
|
||||
if (!strcmp(cvar->string, "jart-dev.jameds.org"))
|
||||
CV_StealthSet(cvar, cvar->defaultvalue);
|
||||
}
|
||||
#else
|
||||
#error "This was an indev thing, remove at release."
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1220,7 +1220,7 @@ void A_StatueBurst(mobj_t *actor)
|
|||
if (!locvar1 || !(new = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar1)))
|
||||
return;
|
||||
|
||||
new->angle = actor->angle;
|
||||
P_InitAngle(new, actor->angle);
|
||||
P_SetTarget(&new->target, actor->target);
|
||||
if (locvar2)
|
||||
P_SetMobjState(new, (statenum_t)locvar2);
|
||||
|
|
@ -2519,8 +2519,8 @@ void A_LobShot(mobj_t *actor)
|
|||
|
||||
P_SetTarget(&shot->target, actor); // where it came from
|
||||
|
||||
shot->angle = an = actor->angle;
|
||||
an >>= ANGLETOFINESHIFT;
|
||||
P_InitAngle(shot, actor->angle);
|
||||
an = actor->angle >> ANGLETOFINESHIFT;
|
||||
|
||||
dist = P_AproxDistance(actor->target->x - shot->x, actor->target->y - shot->y);
|
||||
|
||||
|
|
@ -2886,7 +2886,7 @@ void A_Boss1Laser(mobj_t *actor)
|
|||
S_StartSound(actor, mobjinfo[locvar1].seesound);
|
||||
|
||||
point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET);
|
||||
point->angle = actor->angle;
|
||||
P_InitAngle(point, actor->angle);
|
||||
point->fuse = dur+1;
|
||||
P_SetTarget(&point->target, actor->target);
|
||||
P_SetTarget(&actor->target, point);
|
||||
|
|
@ -2896,7 +2896,7 @@ void A_Boss1Laser(mobj_t *actor)
|
|||
|
||||
point = P_SpawnMobj(x, y, z, locvar1);
|
||||
P_SetTarget(&point->target, actor);
|
||||
point->angle = actor->angle;
|
||||
P_InitAngle(point, actor->angle);
|
||||
speed = point->radius;
|
||||
point->momz = FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT), speed);
|
||||
point->momx = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(point->angle>>ANGLETOFINESHIFT), speed));
|
||||
|
|
@ -2905,7 +2905,7 @@ void A_Boss1Laser(mobj_t *actor)
|
|||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
mobj_t *mo = P_SpawnMobj(point->x, point->y, point->z, point->type);
|
||||
mo->angle = point->angle;
|
||||
P_InitAngle(mo, point->angle);
|
||||
mo->color = LASERCOLORS[((UINT8)(i + 3*dur) >> 2) % sizeof(LASERCOLORS)]; // codeing
|
||||
P_UnsetThingPosition(mo);
|
||||
mo->flags = MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY;
|
||||
|
|
@ -2937,7 +2937,7 @@ void A_Boss1Laser(mobj_t *actor)
|
|||
if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1 && dur & 1)
|
||||
{
|
||||
point = P_SpawnMobj(x, y, floorz, MT_EGGMOBILE_FIRE);
|
||||
point->angle = actor->angle;
|
||||
P_InitAngle(point, actor->angle);
|
||||
point->destscale = actor->scale;
|
||||
P_SetScale(point, point->destscale);
|
||||
P_SetTarget(&point->target, actor);
|
||||
|
|
@ -3521,7 +3521,7 @@ bossjustdie:
|
|||
P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<<FRACBITS),
|
||||
P_ReturnThrustY(mo, mo->angle - ANGLE_90, 32<<FRACBITS),
|
||||
32<<FRACBITS, MT_BOSSJUNK);
|
||||
mo2->angle = mo->angle;
|
||||
P_InitAngle(mo2, mo->angle);
|
||||
P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale);
|
||||
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
|
||||
P_SetMobjState(mo2, S_BOSSEGLZ1);
|
||||
|
|
@ -3530,7 +3530,7 @@ bossjustdie:
|
|||
P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<<FRACBITS),
|
||||
P_ReturnThrustY(mo, mo->angle + ANGLE_90, 32<<FRACBITS),
|
||||
32<<FRACBITS, MT_BOSSJUNK);
|
||||
mo2->angle = mo->angle;
|
||||
P_InitAngle(mo2, mo->angle);
|
||||
P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale);
|
||||
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
|
||||
P_SetMobjState(mo2, S_BOSSEGLZ2);
|
||||
|
|
@ -3542,7 +3542,7 @@ bossjustdie:
|
|||
P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<<FRACBITS),
|
||||
P_ReturnThrustY(mo, mo->angle - ANGLE_90, 32<<FRACBITS),
|
||||
32<<FRACBITS, MT_BOSSJUNK);
|
||||
mo2->angle = mo->angle;
|
||||
P_InitAngle(mo2, mo->angle);
|
||||
P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale);
|
||||
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
|
||||
P_SetMobjState(mo2, S_BOSSTANK1);
|
||||
|
|
@ -3551,7 +3551,7 @@ bossjustdie:
|
|||
P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<<FRACBITS),
|
||||
P_ReturnThrustY(mo, mo->angle + ANGLE_90, 32<<FRACBITS),
|
||||
32<<FRACBITS, MT_BOSSJUNK);
|
||||
mo2->angle = mo->angle;
|
||||
P_InitAngle(mo2, mo->angle);
|
||||
P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale);
|
||||
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
|
||||
P_SetMobjState(mo2, S_BOSSTANK2);
|
||||
|
|
@ -3559,7 +3559,7 @@ bossjustdie:
|
|||
mo2 = P_SpawnMobjFromMobj(mo, 0, 0,
|
||||
mobjinfo[MT_EGGMOBILE2].height + (32<<FRACBITS),
|
||||
MT_BOSSJUNK);
|
||||
mo2->angle = mo->angle;
|
||||
P_InitAngle(mo2, mo->angle);
|
||||
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
|
||||
mo2->momz += mo->momz;
|
||||
P_SetMobjState(mo2, S_BOSSSPIGOT);
|
||||
|
|
@ -3568,7 +3568,7 @@ bossjustdie:
|
|||
case MT_EGGMOBILE3:
|
||||
{
|
||||
mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK);
|
||||
mo2->angle = mo->angle;
|
||||
P_InitAngle(mo2, mo->angle);
|
||||
P_SetMobjState(mo2, S_BOSSSEBH1);
|
||||
}
|
||||
break;
|
||||
|
|
@ -3642,7 +3642,8 @@ bossjustdie:
|
|||
pole->tracer->flags |= MF_NOCLIPTHING;
|
||||
P_SetScale(pole, (pole->destscale = 2*FRACUNIT));
|
||||
P_SetScale(pole->tracer, (pole->tracer->destscale = 2*FRACUNIT));
|
||||
pole->angle = pole->tracer->angle = mo->tracer->angle;
|
||||
P_InitAngle(pole, mo->tracer->angle);
|
||||
P_InitAngle(pole->tracer, mo->tracer->angle);
|
||||
pole->tracer->tracer->angle = pole->angle - ANGLE_90;
|
||||
pole->momx = P_ReturnThrustX(pole, pole->angle, speed);
|
||||
pole->momy = P_ReturnThrustY(pole, pole->angle, speed);
|
||||
|
|
@ -4011,7 +4012,7 @@ void A_AttractChase(mobj_t *actor)
|
|||
|
||||
sparkle = P_SpawnMobj(actor->target->x, actor->target->y, actor->target->z, MT_RINGSPARKS);
|
||||
P_SetTarget(&sparkle->target, actor->target);
|
||||
sparkle->angle = (actor->target->angle + (offset>>1)) + (offset * actor->target->player->sparkleanim);
|
||||
P_InitAngle(sparkle, (actor->target->angle + (offset>>1)) + (offset * actor->target->player->sparkleanim));
|
||||
actor->target->player->sparkleanim = (actor->target->player->sparkleanim+1) % 20;
|
||||
|
||||
P_KillMobj(actor, actor->target, actor->target, DMG_NORMAL);
|
||||
|
|
@ -5265,7 +5266,7 @@ void A_RockSpawn(mobj_t *actor)
|
|||
|
||||
mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FALLINGROCK);
|
||||
P_SetMobjState(mo, mobjinfo[type].spawnstate);
|
||||
mo->angle = R_PointToAngle2(line->v2->x, line->v2->y, line->v1->x, line->v1->y);
|
||||
P_InitAngle(mo, R_PointToAngle2(line->v2->x, line->v2->y, line->v1->x, line->v1->y));
|
||||
|
||||
P_InstaThrust(mo, mo->angle, dist + randomoomph);
|
||||
mo->momz = dist + randomoomph;
|
||||
|
|
@ -7131,7 +7132,7 @@ void A_Boss3ShockThink(mobj_t *actor)
|
|||
snew->momx = (actor->momx + snext->momx) >> 1;
|
||||
snew->momy = (actor->momy + snext->momy) >> 1;
|
||||
snew->momz = (actor->momz + snext->momz) >> 1; // is this really needed?
|
||||
snew->angle = (actor->angle + snext->angle) >> 1;
|
||||
P_InitAngle(snew, (actor->angle + snext->angle) >> 1);
|
||||
P_SetTarget(&snew->target, actor->target);
|
||||
snew->fuse = actor->fuse;
|
||||
|
||||
|
|
@ -7283,7 +7284,7 @@ void A_SpawnObjectAbsolute(mobj_t *actor)
|
|||
mo = P_SpawnMobj(x<<FRACBITS, y<<FRACBITS, z<<FRACBITS, type);
|
||||
|
||||
// Spawn objects with an angle matching the spawner's, rather than spawning Eastwards - Monster Iestyn
|
||||
mo->angle = actor->angle;
|
||||
P_InitAngle(mo, actor->angle);
|
||||
|
||||
if (actor->eflags & MFE_VERTICALFLIP)
|
||||
mo->flags2 |= MF2_OBJECTFLIP;
|
||||
|
|
@ -7325,7 +7326,7 @@ void A_SpawnObjectRelative(mobj_t *actor)
|
|||
(actor->eflags & MFE_VERTICALFLIP) ? ((actor->z + actor->height - mobjinfo[type].height) - FixedMul(z<<FRACBITS, actor->scale)) : (actor->z + FixedMul(z<<FRACBITS, actor->scale)), type);
|
||||
|
||||
// Spawn objects with an angle matching the spawner's, rather than spawning Eastwards - Monster Iestyn
|
||||
mo->angle = actor->angle;
|
||||
P_InitAngle(mo, actor->angle);
|
||||
|
||||
if (actor->eflags & MFE_VERTICALFLIP)
|
||||
mo->flags2 |= MF2_OBJECTFLIP;
|
||||
|
|
@ -8035,7 +8036,7 @@ void A_BossJetFume(mobj_t *actor)
|
|||
P_SetScale(filler, filler->destscale);
|
||||
if (actor->eflags & MFE_VERTICALFLIP)
|
||||
filler->flags2 |= MF2_OBJECTFLIP;
|
||||
filler->angle = actor->angle - ANGLE_180;
|
||||
P_InitAngle(filler, actor->angle - ANGLE_180);
|
||||
|
||||
P_SetTarget(&actor->tracer, filler);
|
||||
}*/
|
||||
|
|
@ -9745,7 +9746,7 @@ void A_TrapShot(mobj_t *actor)
|
|||
S_StartSound(missile, missile->info->seesound);
|
||||
|
||||
P_SetTarget(&missile->target, actor);
|
||||
missile->angle = actor->angle;
|
||||
P_InitAngle(missile, actor->angle);
|
||||
|
||||
speed = FixedMul(missile->info->speed, missile->scale);
|
||||
|
||||
|
|
@ -10324,7 +10325,7 @@ void A_BrakLobShot(mobj_t *actor)
|
|||
S_StartSound(shot, shot->info->seesound);
|
||||
P_SetTarget(&shot->target, actor); // where it came from
|
||||
|
||||
shot->angle = actor->angle;
|
||||
P_InitAngle(shot, actor->angle);
|
||||
|
||||
// Horizontal axes first. First parameter is initial horizontal impulse, second is to correct its angle.
|
||||
shot->momx = FixedMul(FixedMul(v, FINECOSINE(theta >> ANGLETOFINESHIFT)), FINECOSINE(shot->angle >> ANGLETOFINESHIFT));
|
||||
|
|
@ -10391,7 +10392,7 @@ void A_NapalmScatter(mobj_t *actor)
|
|||
mo = P_SpawnMobj(actor->x, actor->y, actor->z, typeOfShot);
|
||||
P_SetTarget(&mo->target, actor->target); // Transfer target so Brak doesn't hit himself like an idiot
|
||||
|
||||
mo->angle = fa << ANGLETOFINESHIFT;
|
||||
P_InitAngle(mo, fa << ANGLETOFINESHIFT);
|
||||
mo->momx = FixedMul(FINECOSINE(fa),vx);
|
||||
mo->momy = FixedMul(FINESINE(fa),vx);
|
||||
mo->momz = vy;
|
||||
|
|
@ -10415,7 +10416,7 @@ void A_SpawnFreshCopy(mobj_t *actor)
|
|||
|
||||
newObject = P_SpawnMobjFromMobj(actor, 0, 0, 0, actor->type);
|
||||
newObject->flags2 = actor->flags2 & MF2_AMBUSH;
|
||||
newObject->angle = actor->angle;
|
||||
P_InitAngle(newObject, actor->angle);
|
||||
newObject->color = actor->color;
|
||||
P_SetTarget(&newObject->target, actor->target);
|
||||
P_SetTarget(&newObject->tracer, actor->tracer);
|
||||
|
|
@ -10451,7 +10452,7 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz
|
|||
}
|
||||
|
||||
flicky = P_SpawnMobjFromMobj(actor, offsx, offsy, 0, flickytype);
|
||||
flicky->angle = actor->angle;
|
||||
P_InitAngle(flicky, actor->angle);
|
||||
|
||||
if (flickytype == MT_SEED)
|
||||
flicky->z += P_MobjFlip(actor)*(actor->height - flicky->height)/2;
|
||||
|
|
@ -10601,7 +10602,7 @@ void A_FlickyCenter(mobj_t *actor)
|
|||
else if (actor->flags & MF_SLIDEME) // aimless
|
||||
{
|
||||
actor->tracer->fuse = 0; // less than 2*TICRATE means move aimlessly.
|
||||
actor->tracer->angle = P_RandomKey(180)*ANG2;
|
||||
P_InitAngle(actor->tracer, P_RandomKey(180)*ANG2);
|
||||
}
|
||||
else //orbit
|
||||
actor->tracer->fuse = FRACUNIT;
|
||||
|
|
@ -11302,7 +11303,7 @@ void A_ConnectToGround(mobj_t *actor)
|
|||
{
|
||||
work = P_SpawnMobjFromMobj(actor, 0, 0, workz, locvar1);
|
||||
if (work)
|
||||
work->angle = ang;
|
||||
P_InitAngle(work, ang);
|
||||
ang += ANGLE_90;
|
||||
workz += workh;
|
||||
}
|
||||
|
|
@ -11348,7 +11349,7 @@ void A_SpawnParticleRelative(mobj_t *actor)
|
|||
(actor->eflags & MFE_VERTICALFLIP) ? ((actor->z + actor->height - mobjinfo[MT_PARTICLE].height) - FixedMul(z<<FRACBITS, actor->scale)) : (actor->z + FixedMul(z<<FRACBITS, actor->scale)), MT_PARTICLE);
|
||||
|
||||
// Spawn objects with an angle matching the spawner's, rather than spawning Eastwards - Monster Iestyn
|
||||
mo->angle = actor->angle;
|
||||
P_InitAngle(mo, actor->angle);
|
||||
|
||||
if (actor->eflags & MFE_VERTICALFLIP)
|
||||
mo->flags2 |= MF2_OBJECTFLIP;
|
||||
|
|
@ -12095,7 +12096,7 @@ void A_Boss5MakeJunk(mobj_t *actor)
|
|||
broked->fuse = TICRATE;
|
||||
else
|
||||
broked->fuse = (((locvar2 & 1) ? 4 : 2)*TICRATE)/3;
|
||||
broked->angle = ang;
|
||||
P_InitAngle(broked, ang);
|
||||
P_InstaThrust(broked, ang, ((locvar2 & 2) ? 8 : 5)*actor->scale);
|
||||
P_SetObjectMomZ(broked, (((locvar2) ? 4 : 0) + P_RandomRange(2, 5))<<FRACBITS, false);
|
||||
if (locvar1 > 0)
|
||||
|
|
@ -12174,7 +12175,7 @@ static void P_DustRing(mobjtype_t mobjtype, UINT32 div, fixed_t x, fixed_t y, fi
|
|||
mobjtype
|
||||
);
|
||||
|
||||
dust->angle = ang*i + ANGLE_90;
|
||||
P_InitAngle(dust, ang*i + ANGLE_90);
|
||||
P_SetScale(dust, FixedMul(initscale, scale));
|
||||
dust->destscale = FixedMul(4*FRACUNIT + P_RandomFixed(), scale);
|
||||
dust->scalespeed = scale/24;
|
||||
|
|
@ -12379,7 +12380,7 @@ static mobj_t *P_TrainSeg(mobj_t *src, fixed_t x, fixed_t y, fixed_t z, angle_t
|
|||
s->fuse = 16*TICRATE;
|
||||
s->sprite = spr;
|
||||
s->frame = frame|FF_PAPERSPRITE;
|
||||
s->angle = ang;
|
||||
P_InitAngle(s, ang);
|
||||
P_Thrust(s, src->angle, 7*FRACUNIT);
|
||||
return s;
|
||||
}
|
||||
|
|
@ -12751,7 +12752,7 @@ void A_SaloonDoorSpawn(mobj_t *actor)
|
|||
|
||||
// One door...
|
||||
if (!(door = P_SpawnMobjFromMobj(actor, c, s, 0, locvar1))) return;
|
||||
door->angle = ang + ANGLE_180;
|
||||
P_InitAngle(door, ang + ANGLE_180);
|
||||
door->extravalue1 = AngleFixed(door->angle); // Origin angle
|
||||
door->extravalue2 = 0; // Angular speed
|
||||
P_SetTarget(&door->tracer, actor); // Origin door
|
||||
|
|
@ -12759,7 +12760,7 @@ void A_SaloonDoorSpawn(mobj_t *actor)
|
|||
|
||||
// ...two door!
|
||||
if (!(door = P_SpawnMobjFromMobj(actor, -c, -s, 0, locvar1))) return;
|
||||
door->angle = ang;
|
||||
P_InitAngle(door, ang);
|
||||
door->extravalue1 = AngleFixed(door->angle); // Origin angle
|
||||
door->extravalue2 = 0; // Angular speed
|
||||
P_SetTarget(&door->tracer, actor); // Origin door
|
||||
|
|
@ -12955,7 +12956,7 @@ void A_SpawnPterabytes(mobj_t *actor)
|
|||
c = FINECOSINE(fa);
|
||||
s = FINESINE(fa);
|
||||
waypoint = P_SpawnMobjFromMobj(actor, FixedMul(c, rad), FixedMul(s, rad), 0, MT_PTERABYTEWAYPOINT);
|
||||
waypoint->angle = ang + ANGLE_90;
|
||||
P_InitAngle(waypoint, ang + ANGLE_90);
|
||||
P_SetTarget(&waypoint->tracer, actor);
|
||||
ptera = P_SpawnMobjFromMobj(waypoint, 0, 0, 0, MT_PTERABYTE);
|
||||
ptera->angle = waypoint->angle;
|
||||
|
|
@ -13129,7 +13130,7 @@ void A_DragonbomberSpawn(mobj_t *actor)
|
|||
segment = P_SpawnMobjFromMobj(mo, x, y, 0, MT_DRAGONTAIL);
|
||||
P_SetTarget(&segment->target, mo);
|
||||
P_SetTarget(&mo->tracer, segment);
|
||||
segment->angle = mo->angle;
|
||||
P_InitAngle(segment, mo->angle);
|
||||
mo = segment;
|
||||
}
|
||||
for (i = 0; i < 2; i++) // spawn wings
|
||||
|
|
@ -13399,6 +13400,9 @@ void A_JawzChase(mobj_t *actor)
|
|||
}
|
||||
|
||||
ret = P_SpawnMobj(actor->tracer->x, actor->tracer->y, actor->tracer->z, MT_PLAYERRETICULE);
|
||||
ret->old_x = actor->tracer->old_x;
|
||||
ret->old_y = actor->tracer->old_y;
|
||||
ret->old_z = actor->tracer->old_z;
|
||||
P_SetTarget(&ret->target, actor->tracer);
|
||||
ret->frame |= ((leveltime % 10) / 2) + 5;
|
||||
ret->color = actor->cvmem;
|
||||
|
|
@ -13531,7 +13535,7 @@ static void SpawnSPBDust(mobj_t *mo)
|
|||
P_SetScale(dust, mo->scale*2);
|
||||
dust->colorized = true;
|
||||
dust->color = SKINCOLOR_RED;
|
||||
dust->angle = mo->angle - FixedAngle(FRACUNIT*90 - FRACUNIT*180*i); // The first one will spawn to the right of the spb, the second one to the left.
|
||||
P_InitAngle(dust, mo->angle - FixedAngle(FRACUNIT*90 - FRACUNIT*180*i)); // The first one will spawn to the right of the spb, the second one to the left.
|
||||
P_Thrust(dust, dust->angle, 6*dust->scale);
|
||||
|
||||
K_MatchGenericExtraFlags(dust, mo);
|
||||
|
|
@ -13568,7 +13572,7 @@ static void SpawnSPBAIZDust(mobj_t *mo, INT32 dir)
|
|||
spark->flags = MF_NOGRAVITY|MF_PAIN;
|
||||
P_SetTarget(&spark->target, mo);
|
||||
|
||||
spark->angle = travelangle+(dir*ANGLE_90);
|
||||
P_InitAngle(spark, travelangle+(dir*ANGLE_90));
|
||||
P_SetScale(spark, (spark->destscale = mo->scale*3/2));
|
||||
|
||||
spark->momx = (6*mo->momx)/5;
|
||||
|
|
@ -13587,7 +13591,7 @@ static void SpawnSPBSpeedLines(mobj_t *actor)
|
|||
MT_FASTLINE);
|
||||
|
||||
P_SetTarget(&fast->target, actor);
|
||||
fast->angle = K_MomentumAngle(actor);
|
||||
P_InitAngle(fast, K_MomentumAngle(actor));
|
||||
fast->color = SKINCOLOR_RED;
|
||||
fast->colorized = true;
|
||||
K_MatchGenericExtraFlags(fast, actor);
|
||||
|
|
@ -14103,7 +14107,7 @@ void A_SSMineExplode(mobj_t *actor)
|
|||
INT32 d;
|
||||
INT32 locvar1 = var1;
|
||||
mobjtype_t type;
|
||||
explodedist = FixedMul((3*actor->info->painchance)/2, mapobjectscale);
|
||||
explodedist = FixedMul((3*actor->info->painchance)/2, actor->scale);
|
||||
|
||||
if (LUA_CallAction(A_SSMINEEXPLODE, actor))
|
||||
return;
|
||||
|
|
@ -14289,7 +14293,7 @@ void A_RandomShadowFrame(mobj_t *actor)
|
|||
P_SetScale(fake, FRACUNIT*3/2);
|
||||
fake->scale = FRACUNIT*3/2;
|
||||
fake->destscale = FRACUNIT*3/2;
|
||||
fake->angle = actor->angle;
|
||||
P_InitAngle(fake, actor->angle);
|
||||
fake->tics = -1;
|
||||
actor->renderflags |= RF_DONTDRAW;
|
||||
actor->extravalue1 = 1;
|
||||
|
|
@ -14677,6 +14681,8 @@ void A_FlameShieldPaper(mobj_t *actor)
|
|||
paper->frame |= framea;
|
||||
}
|
||||
|
||||
P_InitAngle(paper, paper->angle);
|
||||
|
||||
paper->extravalue1 = i;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1054,6 +1054,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY;
|
||||
P_SetThingPosition(target);
|
||||
target->standingslope = NULL;
|
||||
target->terrain = NULL;
|
||||
target->pmomz = 0;
|
||||
|
||||
target->player->playerstate = PST_DEAD;
|
||||
|
|
@ -1184,7 +1185,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
mo->angle = FixedAngle((P_RandomKey(36)*10)<<FRACBITS);
|
||||
|
||||
mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK);
|
||||
mo2->angle = mo->angle;
|
||||
P_InitAngle(mo2, mo->angle);
|
||||
P_SetMobjState(mo2, S_BOSSSEBH2);
|
||||
|
||||
if (++i == 2) // we've already removed 2 of these, let's stop now
|
||||
|
|
@ -1251,6 +1252,12 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
kart->eflags |= MFE_DAMAGEHITLAG;
|
||||
P_SetObjectMomZ(kart, 6*FRACUNIT, false);
|
||||
kart->extravalue1 = target->player->kartweight;
|
||||
|
||||
// Copy interp data
|
||||
kart->old_angle = target->old_angle;
|
||||
kart->old_x = target->old_x;
|
||||
kart->old_y = target->old_y;
|
||||
kart->old_z = target->old_z;
|
||||
}
|
||||
|
||||
if (source && !P_MobjWasRemoved(source))
|
||||
|
|
@ -1322,7 +1329,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
mobj_t *blast = P_SpawnMobjFromMobj(target, 0, 0, target->info->height >> 1, MT_BATTLEBUMPER_BLAST);
|
||||
blast->angle = angle + i*ANGLE_90;
|
||||
P_InitAngle(blast, angle + i*ANGLE_90);
|
||||
P_SetScale(blast, 2*blast->scale/3);
|
||||
blast->destscale = 2*blast->scale;
|
||||
}
|
||||
|
|
@ -1547,7 +1554,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);\
|
||||
P_SetMobjState(chunk, target->info->xdeathstate);\
|
||||
chunk->health = 0;\
|
||||
chunk->angle = angtweak;\
|
||||
P_InitAngle(chunk, angtweak);\
|
||||
P_UnsetThingPosition(chunk);\
|
||||
chunk->flags = MF_NOCLIP;\
|
||||
chunk->x += xmov;\
|
||||
|
|
@ -1569,7 +1576,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);
|
||||
P_SetMobjState(chunk, target->info->deathstate);
|
||||
chunk->health = 0;
|
||||
chunk->angle = ang + ANGLE_180;
|
||||
P_InitAngle(chunk, ang + ANGLE_180);
|
||||
P_UnsetThingPosition(chunk);
|
||||
chunk->flags = MF_NOCLIP;
|
||||
chunk->x -= xoffs;
|
||||
|
|
@ -1615,7 +1622,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);\
|
||||
P_SetMobjState(chunk, target->info->xdeathstate);\
|
||||
chunk->health = 0;\
|
||||
chunk->angle = target->angle;\
|
||||
P_InitAngle(chunk, target->angle);\
|
||||
P_UnsetThingPosition(chunk);\
|
||||
chunk->flags = MF_NOCLIP;\
|
||||
chunk->x += xmov - forwardxoffs;\
|
||||
|
|
@ -1641,7 +1648,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
|
||||
P_SetMobjState(chunk, target->info->deathstate);
|
||||
chunk->health = 0;
|
||||
chunk->angle = target->angle;
|
||||
P_InitAngle(chunk, target->angle);
|
||||
P_UnsetThingPosition(chunk);
|
||||
chunk->flags = MF_NOCLIP;
|
||||
chunk->x += forwardxoffs - xoffs;
|
||||
|
|
@ -1766,7 +1773,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
|
|||
|
||||
boom = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FZEROBOOM);
|
||||
boom->scale = player->mo->scale;
|
||||
boom->angle = player->mo->angle;
|
||||
P_InitAngle(boom, player->mo->angle);
|
||||
P_SetTarget(&boom->target, player->mo);
|
||||
}
|
||||
|
||||
|
|
@ -1838,7 +1845,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
if (!(target->flags & MF_SHOOTABLE))
|
||||
return false; // shouldn't happen...
|
||||
|
||||
if (!(damagetype & DMG_DEATHMASK) && target->hitlag > 0)
|
||||
if (!(damagetype & DMG_DEATHMASK) && target->hitlag > 0 && inflictor == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1922,7 +1929,18 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
|
||||
if (combo == false)
|
||||
{
|
||||
if (player->flashing > 0)
|
||||
// Check if we should allow wombo combos (DMG_WOMBO)
|
||||
boolean allowcombo = false;
|
||||
|
||||
// For MISSILE OBJECTS, allow combo BY DEFAULT. If DMG_WOMBO is set, do *NOT* allow it.
|
||||
if (inflictor && !P_MobjWasRemoved(inflictor) && (inflictor->flags & MF_MISSILE) && !(damagetype & DMG_WOMBO))
|
||||
allowcombo = true;
|
||||
|
||||
// OTHERWISE, only allow combos IF DMG_WOMBO *IS* set.
|
||||
else if (damagetype & DMG_WOMBO)
|
||||
allowcombo = true;
|
||||
|
||||
if ((player->mo->hitlag == 0 || allowcombo == false) && player->flashing > 0)
|
||||
{
|
||||
// Post-hit invincibility
|
||||
K_DoInstashield(player);
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ struct demofreecam_s {
|
|||
|
||||
camera_t *cam; // this is useful when the game is paused, notably
|
||||
mobj_t *soundmobj; // mobj to play sound from, used in s_sound
|
||||
|
||||
|
||||
angle_t localangle; // keeps track of the cam angle for cmds
|
||||
angle_t localaiming; // ditto with aiming
|
||||
boolean turnheld; // holding turn button for gradual turn speed
|
||||
|
|
@ -168,7 +168,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec);
|
|||
boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec); // SRB2Kart
|
||||
#define P_IsObjectFlipped(o) ((o)->eflags & MFE_VERTICALFLIP)
|
||||
boolean P_InQuicksand(mobj_t *mo);
|
||||
boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff);
|
||||
boolean P_PlayerHitFloor(player_t *player, boolean fromAir);
|
||||
|
||||
void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative);
|
||||
void P_RestoreMusic(player_t *player);
|
||||
|
|
@ -385,6 +385,7 @@ extern camera_t *mapcampointer;
|
|||
extern fixed_t tmx;
|
||||
extern fixed_t tmy;
|
||||
extern pslope_t *tmfloorslope, *tmceilingslope;
|
||||
extern INT32 tmfloorpic, tmceilingpic;
|
||||
|
||||
/* cphipps 2004/08/30 */
|
||||
extern void P_MapStart(void);
|
||||
|
|
@ -410,6 +411,9 @@ 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_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_InitAngle(mobj_t *thing, angle_t newValue);
|
||||
void P_InitPitch(mobj_t *thing, angle_t newValue);
|
||||
void P_InitRoll(mobj_t *thing, angle_t newValue);
|
||||
void P_SlideMove(mobj_t *mo);
|
||||
void P_BouncePlayerMove(mobj_t *mo);
|
||||
void P_BounceMove(mobj_t *mo);
|
||||
|
|
@ -482,6 +486,7 @@ typedef struct BasicFF_s
|
|||
#define DMG_SPECTATOR 0x83
|
||||
#define DMG_TIMEOVER 0x84
|
||||
// Masks
|
||||
#define DMG_WOMBO 0x10 // Flag - setting this flag allows objects to damage you if you're already in spinout. The effect is reversed on objects with MF_MISSILE (setting it prevents them from comboing in spinout)
|
||||
#define DMG_STEAL 0x20 // Flag - can steal bumpers, will only deal damage to players, and will not deal damage outside Battle Mode.
|
||||
#define DMG_CANTHURTSELF 0x40 // Flag - cannot hurt your self or your team
|
||||
#define DMG_DEATHMASK DMG_INSTAKILL // if bit 7 is set, this is a death type instead of a damage type
|
||||
|
|
@ -530,5 +535,6 @@ fixed_t P_ScaleFromMap(fixed_t n, fixed_t scale);
|
|||
fixed_t P_GetMobjHead(const mobj_t *);
|
||||
fixed_t P_GetMobjFeet(const mobj_t *);
|
||||
fixed_t P_GetMobjGround(const mobj_t *);
|
||||
fixed_t P_GetMobjZMovement(mobj_t *mo);
|
||||
|
||||
#endif // __P_LOCAL__
|
||||
|
|
|
|||
99
src/p_map.c
99
src/p_map.c
|
|
@ -24,12 +24,13 @@
|
|||
#include "r_sky.h"
|
||||
#include "s_sound.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
#include "k_kart.h" // SRB2kart 011617
|
||||
#include "k_collide.h"
|
||||
#include "k_respawn.h"
|
||||
|
||||
#include "hu_stuff.h" // SRB2kart
|
||||
#include "i_system.h" // SRB2kart
|
||||
#include "k_terrain.h"
|
||||
|
||||
#include "r_splats.h"
|
||||
|
||||
|
|
@ -60,6 +61,7 @@ mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz
|
|||
mobj_t *tmhitthing; // the solid thing you bumped into (for collisions)
|
||||
ffloor_t *tmfloorrover, *tmceilingrover;
|
||||
pslope_t *tmfloorslope, *tmceilingslope;
|
||||
INT32 tmfloorpic, tmceilingpic;
|
||||
static fixed_t tmfloorstep;
|
||||
static fixed_t tmceilingstep;
|
||||
|
||||
|
|
@ -155,6 +157,30 @@ boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
|||
return P_TeleportMove(thing, x, y, z);
|
||||
}
|
||||
|
||||
//
|
||||
// P_InitAngle - Change an object's angle, including interp values.
|
||||
//
|
||||
void P_InitAngle(mobj_t *thing, angle_t newValue)
|
||||
{
|
||||
thing->angle = thing->old_angle = newValue;
|
||||
}
|
||||
|
||||
//
|
||||
// P_InitPitch - Change an object's pitch, including interp values.
|
||||
//
|
||||
void P_InitPitch(mobj_t *thing, angle_t newValue)
|
||||
{
|
||||
thing->pitch = thing->old_pitch = newValue;
|
||||
}
|
||||
|
||||
//
|
||||
// P_InitRoll - Change an object's roll, including interp values.
|
||||
//
|
||||
void P_InitRoll(mobj_t *thing, angle_t newValue)
|
||||
{
|
||||
thing->roll = thing->old_roll = newValue;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// MOVEMENT ITERATOR FUNCTIONS
|
||||
// =========================================================================
|
||||
|
|
@ -267,9 +293,7 @@ static boolean P_SpecialIsLinedefCrossType(line_t *ld)
|
|||
//
|
||||
boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
||||
{
|
||||
//INT32 pflags;
|
||||
const fixed_t hscale = mapobjectscale + (mapobjectscale - object->scale);
|
||||
const fixed_t vscale = mapobjectscale + (object->scale - mapobjectscale);
|
||||
const fixed_t scaleVal = FixedSqrt(FixedMul(mapobjectscale, spring->scale));
|
||||
fixed_t vertispeed = spring->info->mass;
|
||||
fixed_t horizspeed = spring->info->damage;
|
||||
UINT16 starcolor = (spring->info->painchance % numskincolors);
|
||||
|
|
@ -303,6 +327,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
}
|
||||
|
||||
object->standingslope = NULL; // Okay, now we know it's not going to be relevant - no launching off at silly angles for you.
|
||||
object->terrain = NULL;
|
||||
|
||||
object->eflags |= MFE_SPRUNG; // apply this flag asap!
|
||||
spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
|
||||
|
|
@ -346,13 +371,13 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
|
||||
if (vertispeed)
|
||||
{
|
||||
object->momz = FixedMul(vertispeed, FixedSqrt(FixedMul(vscale, spring->scale)));
|
||||
object->momz = FixedMul(vertispeed, scaleVal);
|
||||
}
|
||||
|
||||
if (horizspeed)
|
||||
{
|
||||
angle_t finalAngle = spring->angle;
|
||||
fixed_t finalSpeed = FixedMul(horizspeed, FixedSqrt(FixedMul(hscale, spring->scale)));
|
||||
fixed_t finalSpeed = FixedMul(horizspeed, scaleVal);
|
||||
fixed_t objectSpeed;
|
||||
|
||||
if (object->player)
|
||||
|
|
@ -408,7 +433,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
mobj_t *grease;
|
||||
grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE);
|
||||
P_SetTarget(&grease->target, object);
|
||||
grease->angle = K_MomentumAngle(object);
|
||||
P_InitAngle(grease, K_MomentumAngle(object));
|
||||
grease->extravalue1 = i;
|
||||
}
|
||||
|
||||
|
|
@ -444,6 +469,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
|
|||
}
|
||||
|
||||
object->standingslope = NULL; // No launching off at silly angles for you.
|
||||
object->terrain = NULL;
|
||||
|
||||
switch (spring->type)
|
||||
{
|
||||
|
|
@ -756,7 +782,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
return true;
|
||||
|
||||
// Player Damage
|
||||
P_DamageMobj(tmthing, ((thing->type == MT_BUBBLESHIELD) ? thing->target : thing), thing, 1, DMG_NORMAL);
|
||||
P_DamageMobj(tmthing, ((thing->type == MT_BUBBLESHIELD) ? thing->target : thing), thing, 1, DMG_NORMAL|DMG_WOMBO);
|
||||
S_StartSound(thing, sfx_s3k44);
|
||||
}
|
||||
else
|
||||
|
|
@ -1430,6 +1456,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
tmfloorz = thing->z + thing->height;
|
||||
tmfloorrover = NULL;
|
||||
tmfloorslope = NULL;
|
||||
tmfloorpic = -1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1449,6 +1476,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
tmfloorz = tmceilingz = topz; // block while in air
|
||||
tmceilingrover = NULL;
|
||||
tmceilingslope = NULL;
|
||||
tmceilingpic = -1;
|
||||
tmfloorthing = thing; // needed for side collision
|
||||
}
|
||||
else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height)
|
||||
|
|
@ -1456,6 +1484,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
tmceilingz = topz;
|
||||
tmceilingrover = NULL;
|
||||
tmceilingslope = NULL;
|
||||
tmceilingpic = -1;
|
||||
tmfloorthing = thing; // thing we may stand on
|
||||
}
|
||||
}
|
||||
|
|
@ -1471,6 +1500,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
tmceilingz = thing->z;
|
||||
tmceilingrover = NULL;
|
||||
tmceilingslope = NULL;
|
||||
tmceilingpic = -1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1490,6 +1520,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
tmfloorz = tmceilingz = topz; // block while in air
|
||||
tmfloorrover = NULL;
|
||||
tmfloorslope = NULL;
|
||||
tmfloorpic = -1;
|
||||
tmfloorthing = thing; // needed for side collision
|
||||
}
|
||||
else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z)
|
||||
|
|
@ -1497,6 +1528,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
tmfloorz = topz;
|
||||
tmfloorrover = NULL;
|
||||
tmfloorslope = NULL;
|
||||
tmfloorpic = -1;
|
||||
tmfloorthing = thing; // thing we may stand on
|
||||
}
|
||||
}
|
||||
|
|
@ -1676,6 +1708,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
|||
ceilingline = ld;
|
||||
tmceilingrover = openceilingrover;
|
||||
tmceilingslope = opentopslope;
|
||||
tmceilingpic = opentoppic;
|
||||
tmceilingstep = openceilingstep;
|
||||
if (thingtop == tmthing->ceilingz)
|
||||
{
|
||||
|
|
@ -1688,6 +1721,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
|||
tmfloorz = openbottom;
|
||||
tmfloorrover = openfloorrover;
|
||||
tmfloorslope = openbottomslope;
|
||||
tmfloorpic = openbottompic;
|
||||
tmfloorstep = openfloorstep;
|
||||
if (tmthing->z == tmthing->floorz)
|
||||
{
|
||||
|
|
@ -1784,6 +1818,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
tmceilingrover = NULL;
|
||||
tmfloorslope = newsubsec->sector->f_slope;
|
||||
tmceilingslope = newsubsec->sector->c_slope;
|
||||
tmfloorpic = newsubsec->sector->floorpic;
|
||||
tmceilingpic = newsubsec->sector->ceilingpic;
|
||||
|
||||
tmfloorstep = 0;
|
||||
tmceilingstep = 0;
|
||||
|
|
@ -1837,6 +1873,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
tmfloorz = topheight - sinklevel;
|
||||
tmfloorrover = rover;
|
||||
tmfloorslope = *rover->t_slope;
|
||||
tmfloorpic = *rover->toppic;
|
||||
}
|
||||
}
|
||||
else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0)
|
||||
|
|
@ -1845,6 +1882,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
tmceilingz = bottomheight + sinklevel;
|
||||
tmceilingrover = rover;
|
||||
tmceilingslope = *rover->b_slope;
|
||||
tmceilingpic = *rover->bottompic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1868,6 +1906,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
tmfloorz = thing->z;
|
||||
tmfloorrover = rover;
|
||||
tmfloorslope = NULL;
|
||||
tmfloorpic = *rover->toppic;
|
||||
}
|
||||
}
|
||||
// Quicksand blocks never change heights otherwise.
|
||||
|
|
@ -1885,6 +1924,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
tmfloorz = tmdropoffz = topheight;
|
||||
tmfloorrover = rover;
|
||||
tmfloorslope = *rover->t_slope;
|
||||
tmfloorpic = *rover->toppic;
|
||||
}
|
||||
if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2)
|
||||
&& !(rover->flags & FF_PLATFORM)
|
||||
|
|
@ -1893,6 +1933,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
tmceilingz = tmdrpoffceilz = bottomheight;
|
||||
tmceilingrover = rover;
|
||||
tmceilingslope = *rover->b_slope;
|
||||
tmceilingpic = *rover->bottompic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1967,12 +2008,14 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
tmfloorz = tmdropoffz = polytop;
|
||||
tmfloorslope = NULL;
|
||||
tmfloorrover = NULL;
|
||||
tmfloorpic = polysec->ceilingpic;
|
||||
}
|
||||
|
||||
if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) {
|
||||
tmceilingz = tmdrpoffceilz = polybottom;
|
||||
tmceilingslope = NULL;
|
||||
tmceilingrover = NULL;
|
||||
tmceilingpic = polysec->floorpic;
|
||||
}
|
||||
}
|
||||
plink = (polymaplink_t *)(plink->link.next);
|
||||
|
|
@ -2390,6 +2433,8 @@ boolean PIT_PushableMoved(mobj_t *thing)
|
|||
ffloor_t *oldceilrover = tmceilingrover;
|
||||
pslope_t *oldfslope = tmfloorslope;
|
||||
pslope_t *oldcslope = tmceilingslope;
|
||||
INT32 oldfpic = tmfloorpic;
|
||||
INT32 oldcpic = tmceilingpic;
|
||||
|
||||
// Move the player
|
||||
P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true);
|
||||
|
|
@ -2406,6 +2451,8 @@ boolean PIT_PushableMoved(mobj_t *thing)
|
|||
tmceilingrover = oldceilrover;
|
||||
tmfloorslope = oldfslope;
|
||||
tmceilingslope = oldcslope;
|
||||
tmfloorpic = oldfpic;
|
||||
tmceilingpic = oldcpic;
|
||||
thing->momz = stand->momz;
|
||||
}
|
||||
else
|
||||
|
|
@ -2655,9 +2702,14 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
if (!(thing->flags & MF_NOCLIPHEIGHT))
|
||||
{
|
||||
// Assign thing's standingslope if needed
|
||||
if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) {
|
||||
if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP))
|
||||
{
|
||||
K_UpdateMobjTerrain(thing, tmfloorpic);
|
||||
|
||||
if (!startingonground && tmfloorslope)
|
||||
{
|
||||
P_HandleSlopeLanding(thing, tmfloorslope);
|
||||
}
|
||||
|
||||
if (thing->momz <= 0)
|
||||
{
|
||||
|
|
@ -2665,12 +2717,19 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
P_SetPitchRollFromSlope(thing, thing->standingslope);
|
||||
|
||||
if (thing->momz == 0 && thing->player && !startingonground)
|
||||
{
|
||||
P_PlayerHitFloor(thing->player, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) {
|
||||
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP))
|
||||
{
|
||||
K_UpdateMobjTerrain(thing, tmceilingpic);
|
||||
|
||||
if (!startingonground && tmceilingslope)
|
||||
{
|
||||
P_HandleSlopeLanding(thing, tmceilingslope);
|
||||
}
|
||||
|
||||
if (thing->momz >= 0)
|
||||
{
|
||||
|
|
@ -2678,12 +2737,18 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
P_SetPitchRollFromSlope(thing, thing->standingslope);
|
||||
|
||||
if (thing->momz == 0 && thing->player && !startingonground)
|
||||
{
|
||||
P_PlayerHitFloor(thing->player, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // don't set standingslope if you're not going to clip against it
|
||||
else
|
||||
{
|
||||
// don't set standingslope if you're not going to clip against it
|
||||
thing->standingslope = NULL;
|
||||
thing->terrain = NULL;
|
||||
}
|
||||
|
||||
/* FIXME: slope step down (even up) has some false
|
||||
positives, so just ignore them entirely. */
|
||||
|
|
@ -3431,6 +3496,9 @@ void P_SlideMove(mobj_t *mo)
|
|||
vertex_t v1, v2; // fake vertexes
|
||||
line_t junk; // fake linedef
|
||||
|
||||
if (P_MobjWasRemoved(mo))
|
||||
return;
|
||||
|
||||
if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height)
|
||||
{
|
||||
// Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already.
|
||||
|
|
@ -3667,7 +3735,7 @@ stairstep:
|
|||
tmymove = 0;
|
||||
}
|
||||
if (!P_TryMove(mo, newx, newy, true)) {
|
||||
if (success)
|
||||
if (success || P_MobjWasRemoved(mo))
|
||||
return; // Good enough!!
|
||||
else
|
||||
goto retry;
|
||||
|
|
@ -3791,6 +3859,9 @@ void P_BounceMove(mobj_t *mo)
|
|||
INT32 hitcount;
|
||||
fixed_t mmomx = 0, mmomy = 0;
|
||||
|
||||
if (P_MobjWasRemoved(mo))
|
||||
return;
|
||||
|
||||
if (mo->player)
|
||||
{
|
||||
P_BouncePlayerMove(mo);
|
||||
|
|
@ -3914,7 +3985,11 @@ bounceback:
|
|||
mo->momy = tmymove;
|
||||
|
||||
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true))
|
||||
{
|
||||
if (P_MobjWasRemoved(mo))
|
||||
return;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -342,6 +342,7 @@ fixed_t openceilingstep;
|
|||
fixed_t openceilingdrop;
|
||||
fixed_t openfloorstep;
|
||||
fixed_t openfloordrop;
|
||||
INT32 opentoppic, openbottompic;
|
||||
|
||||
// P_CameraLineOpening
|
||||
// P_LineOpening, but for camera
|
||||
|
|
@ -537,6 +538,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
highceiling = INT32_MIN;
|
||||
lowfloor = INT32_MAX;
|
||||
opentopslope = openbottomslope = NULL;
|
||||
opentoppic = openbottompic = -1;
|
||||
openceilingstep = 0;
|
||||
openceilingdrop = 0;
|
||||
openfloorstep = 0;
|
||||
|
|
@ -556,6 +558,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
opentop = height[lo];
|
||||
highceiling = height[hi];
|
||||
opentopslope = sector[lo]->c_slope;
|
||||
opentoppic = sector[lo]->ceilingpic;
|
||||
|
||||
if (mobj)
|
||||
{
|
||||
|
|
@ -575,6 +578,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
openbottom = height[hi];
|
||||
lowfloor = height[lo];
|
||||
openbottomslope = sector[hi]->f_slope;
|
||||
openbottompic = sector[hi]->floorpic;
|
||||
|
||||
if (mobj)
|
||||
{
|
||||
|
|
@ -747,6 +751,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if (bottomheight < open[FRONT].top) {
|
||||
open[FRONT].top = bottomheight;
|
||||
opentopslope = *rover->b_slope;
|
||||
opentoppic = *rover->bottompic;
|
||||
open[FRONT].ceilingrover = rover;
|
||||
}
|
||||
else if (bottomheight < highceiling)
|
||||
|
|
@ -758,6 +763,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if (topheight > open[FRONT].bottom) {
|
||||
open[FRONT].bottom = topheight;
|
||||
openbottomslope = *rover->t_slope;
|
||||
openbottompic = *rover->toppic;
|
||||
open[FRONT].floorrover = rover;
|
||||
}
|
||||
else if (topheight > lowfloor)
|
||||
|
|
@ -789,6 +795,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if (bottomheight < open[BACK].top) {
|
||||
open[BACK].top = bottomheight;
|
||||
opentopslope = *rover->b_slope;
|
||||
opentoppic = *rover->bottompic;
|
||||
open[BACK].ceilingrover = rover;
|
||||
}
|
||||
else if (bottomheight < highceiling)
|
||||
|
|
@ -800,6 +807,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if (topheight > open[BACK].bottom) {
|
||||
open[BACK].bottom = topheight;
|
||||
openbottomslope = *rover->t_slope;
|
||||
openbottompic = *rover->toppic;
|
||||
open[BACK].floorrover = rover;
|
||||
}
|
||||
else if (topheight > lowfloor)
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ extern fixed_t openceilingstep;
|
|||
extern fixed_t openceilingdrop;
|
||||
extern fixed_t openfloorstep;
|
||||
extern fixed_t openfloordrop;
|
||||
extern INT32 opentoppic, openbottompic;
|
||||
|
||||
void P_LineOpening(line_t *plinedef, mobj_t *mobj);
|
||||
|
||||
|
|
|
|||
407
src/p_mobj.c
407
src/p_mobj.c
|
|
@ -40,6 +40,7 @@
|
|||
#include "k_color.h"
|
||||
#include "k_respawn.h"
|
||||
#include "k_bot.h"
|
||||
#include "k_terrain.h"
|
||||
|
||||
static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL);
|
||||
|
|
@ -1201,7 +1202,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
gravityadd = -((gravityadd/5) + (gravityadd/8));
|
||||
}
|
||||
|
||||
gravityadd = FixedMul(gravityadd, mo->scale);
|
||||
gravityadd = FixedMul(gravityadd, mapobjectscale);
|
||||
|
||||
return gravityadd;
|
||||
}
|
||||
|
|
@ -1340,7 +1341,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
|
|||
mo->momy = FixedMul(mo->momy, mo->friction);
|
||||
}
|
||||
|
||||
mo->friction = ORIG_FRICTION;
|
||||
K_SetDefaultFriction(mo);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1505,7 +1506,10 @@ void P_XYMovement(mobj_t *mo)
|
|||
oldy = mo->y;
|
||||
|
||||
if (mo->flags & MF_NOCLIPHEIGHT)
|
||||
{
|
||||
mo->standingslope = NULL;
|
||||
mo->terrain = NULL;
|
||||
}
|
||||
|
||||
// adjust various things based on slope
|
||||
if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) {
|
||||
|
|
@ -1671,6 +1675,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
{
|
||||
mo->momz = transfermomz;
|
||||
mo->standingslope = NULL;
|
||||
mo->terrain = NULL;
|
||||
P_SetPitchRoll(mo, ANGLE_90,
|
||||
transferslope->xydirection
|
||||
+ (transferslope->zangle
|
||||
|
|
@ -1684,11 +1689,15 @@ void P_XYMovement(mobj_t *mo)
|
|||
if (mo->flags & MF_SLIDEME)
|
||||
{
|
||||
P_SlideMove(mo);
|
||||
if (P_MobjWasRemoved(mo))
|
||||
return;
|
||||
xmove = ymove = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
P_BounceMove(mo);
|
||||
if (P_MobjWasRemoved(mo))
|
||||
return;
|
||||
xmove = ymove = 0;
|
||||
S_StartSound(mo, mo->info->activesound);
|
||||
|
||||
|
|
@ -1782,6 +1791,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
mo->momz = P_MobjFlip(mo)*FRACUNIT/2;
|
||||
mo->z = predictedz + P_MobjFlip(mo);
|
||||
mo->standingslope = NULL;
|
||||
mo->terrain = NULL;
|
||||
//CONS_Printf("Launched off of flat surface running into downward slope\n");
|
||||
}
|
||||
}
|
||||
|
|
@ -1837,6 +1847,9 @@ void P_SceneryXYMovement(mobj_t *mo)
|
|||
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy))
|
||||
P_BounceMove(mo);
|
||||
|
||||
if (P_MobjWasRemoved(mo))
|
||||
return;
|
||||
|
||||
if ((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz))
|
||||
return; // no friction when airborne
|
||||
|
||||
|
|
@ -2274,6 +2287,8 @@ boolean P_ZMovement(mobj_t *mo)
|
|||
}
|
||||
|
||||
P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly
|
||||
K_UpdateMobjTerrain(mo, ((mo->eflags & MFE_VERTICALFLIP) ? tmceilingpic : tmfloorpic));
|
||||
|
||||
if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM))
|
||||
{
|
||||
mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
|
||||
|
|
@ -2383,7 +2398,7 @@ boolean P_ZMovement(mobj_t *mo)
|
|||
MT_KART_TIRE
|
||||
);
|
||||
|
||||
tire->angle = mo->angle;
|
||||
P_InitAngle(tire, mo->angle);
|
||||
tire->fuse = 3*TICRATE;
|
||||
P_InstaThrust(tire, tireAngle, 4 * mo->scale);
|
||||
P_SetObjectMomZ(tire, 4*FRACUNIT, false);
|
||||
|
|
@ -2403,7 +2418,7 @@ boolean P_ZMovement(mobj_t *mo)
|
|||
MT_KART_TIRE
|
||||
);
|
||||
|
||||
tire->angle = mo->angle;
|
||||
P_InitAngle(tire, mo->angle);
|
||||
tire->fuse = 3*TICRATE;
|
||||
P_InstaThrust(tire, tireAngle, 4 * mo->scale);
|
||||
P_SetObjectMomZ(tire, 4*FRACUNIT, false);
|
||||
|
|
@ -2503,12 +2518,17 @@ boolean P_ZMovement(mobj_t *mo)
|
|||
if (mo->type == MT_STEAM)
|
||||
return true;
|
||||
}
|
||||
else if (!(mo->flags & MF_NOGRAVITY)) // Gravity here!
|
||||
else
|
||||
{
|
||||
/// \todo may not be needed (done in P_MobjThinker normally)
|
||||
mo->eflags &= ~MFE_JUSTHITFLOOR;
|
||||
mo->terrain = NULL;
|
||||
|
||||
P_CheckGravity(mo, true);
|
||||
if (!(mo->flags & MF_NOGRAVITY)) // Gravity here!
|
||||
{
|
||||
/// \todo may not be needed (done in P_MobjThinker normally)
|
||||
mo->eflags &= ~MFE_JUSTHITFLOOR;
|
||||
|
||||
P_CheckGravity(mo, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (((mo->z + mo->height > mo->ceilingz && !(mo->eflags & MFE_VERTICALFLIP))
|
||||
|
|
@ -2712,20 +2732,29 @@ void P_PlayerZMovement(mobj_t *mo)
|
|||
if (onground && !(mo->flags & MF_NOCLIPHEIGHT))
|
||||
{
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
mo->z = mo->ceilingz - mo->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
mo->z = mo->floorz;
|
||||
}
|
||||
|
||||
K_UpdateMobjTerrain(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingpic : tmfloorpic));
|
||||
|
||||
// Get up if you fell.
|
||||
if (mo->player->panim == PA_HURT && mo->player->spinouttimer == 0 && mo->player->tumbleBounces == 0)
|
||||
{
|
||||
P_SetPlayerMobjState(mo, S_KART_STILL);
|
||||
}
|
||||
|
||||
if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) {
|
||||
if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope))
|
||||
{
|
||||
// Handle landing on slope during Z movement
|
||||
P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope));
|
||||
}
|
||||
|
||||
if (P_MobjFlip(mo)*mo->momz < 0) // falling
|
||||
if (P_MobjFlip(mo) * mo->momz < 0) // falling
|
||||
{
|
||||
boolean clipmomz = !(P_CheckDeathPitCollide(mo));
|
||||
|
||||
|
|
@ -2736,29 +2765,38 @@ void P_PlayerZMovement(mobj_t *mo)
|
|||
P_PlayerPolyObjectZMovement(mo);
|
||||
|
||||
if (clipmomz)
|
||||
{
|
||||
mo->momz = (tmfloorthing ? tmfloorthing->momz : 0);
|
||||
}
|
||||
}
|
||||
else if (tmfloorthing)
|
||||
mo->momz = tmfloorthing->momz;
|
||||
}
|
||||
else if (!(mo->flags & MF_NOGRAVITY)) // Gravity here!
|
||||
{
|
||||
if (P_IsObjectInGoop(mo) && !(mo->flags & MF_NOCLIPHEIGHT))
|
||||
{
|
||||
if (mo->z < mo->floorz)
|
||||
{
|
||||
mo->z = mo->floorz;
|
||||
mo->momz = 0;
|
||||
}
|
||||
else if (mo->z + mo->height > mo->ceilingz)
|
||||
{
|
||||
mo->z = mo->ceilingz - mo->height;
|
||||
mo->momz = 0;
|
||||
}
|
||||
mo->momz = tmfloorthing->momz;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mo->terrain = NULL;
|
||||
|
||||
if (!(mo->flags & MF_NOGRAVITY)) // Gravity here!
|
||||
{
|
||||
if (P_IsObjectInGoop(mo) && !(mo->flags & MF_NOCLIPHEIGHT))
|
||||
{
|
||||
if (mo->z < mo->floorz)
|
||||
{
|
||||
mo->z = mo->floorz;
|
||||
mo->momz = 0;
|
||||
}
|
||||
else if (mo->z + mo->height > mo->ceilingz)
|
||||
{
|
||||
mo->z = mo->ceilingz - mo->height;
|
||||
mo->momz = 0;
|
||||
}
|
||||
}
|
||||
/// \todo may not be needed (done in P_MobjThinker normally)
|
||||
mo->eflags &= ~MFE_JUSTHITFLOOR;
|
||||
P_CheckGravity(mo, true);
|
||||
}
|
||||
/// \todo may not be needed (done in P_MobjThinker normally)
|
||||
mo->eflags &= ~MFE_JUSTHITFLOOR;
|
||||
P_CheckGravity(mo, true);
|
||||
}
|
||||
|
||||
if (((mo->eflags & MFE_VERTICALFLIP && mo->z < mo->floorz) || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z + mo->height > mo->ceilingz))
|
||||
|
|
@ -3048,6 +3086,26 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
}
|
||||
}
|
||||
|
||||
if (mobj->terrain != NULL)
|
||||
{
|
||||
if (mobj->terrain->flags & TRF_LIQUID)
|
||||
{
|
||||
// This floor is water.
|
||||
mobj->eflags |= MFE_TOUCHWATER;
|
||||
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
mobj->watertop = thingtop + height;
|
||||
mobj->waterbottom = thingtop;
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->watertop = mobj->z;
|
||||
mobj->waterbottom = mobj->z - height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mobj->watertop > top2)
|
||||
mobj->watertop = top2;
|
||||
|
||||
|
|
@ -3056,7 +3114,9 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
|
||||
// Spectators and dead players don't get to do any of the things after this.
|
||||
if (p && (p->spectator || p->playerstate != PST_LIVE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// The rest of this code only executes on a water state change.
|
||||
if (!!(mobj->eflags & MFE_UNDERWATER) == wasinwater)
|
||||
|
|
@ -3073,6 +3133,30 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
|| ((mobj->info->flags & MF_PUSHABLE) && mobj->fuse) // Previously pushable, might be moving still
|
||||
)
|
||||
{
|
||||
fixed_t waterZ = INT32_MAX;
|
||||
fixed_t solidZ = INT32_MAX;
|
||||
fixed_t diff = INT32_MAX;
|
||||
|
||||
fixed_t thingZ = INT32_MAX;
|
||||
boolean splashValid = false;
|
||||
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
waterZ = mobj->waterbottom;
|
||||
solidZ = mobj->ceilingz;
|
||||
}
|
||||
else
|
||||
{
|
||||
waterZ = mobj->watertop;
|
||||
solidZ = mobj->floorz;
|
||||
}
|
||||
|
||||
diff = waterZ - solidZ;
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
diff = -diff;
|
||||
}
|
||||
|
||||
// Time to spawn the bubbles!
|
||||
{
|
||||
INT32 i;
|
||||
|
|
@ -3131,12 +3215,15 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
|
||||
// Check to make sure you didn't just cross into a sector to jump out of
|
||||
// that has shallower water than the block you were originally in.
|
||||
if ((!(mobj->eflags & MFE_VERTICALFLIP) && mobj->watertop-mobj->floorz <= height>>1)
|
||||
|| ((mobj->eflags & MFE_VERTICALFLIP) && mobj->ceilingz-mobj->waterbottom <= height>>1))
|
||||
if (diff <= (height >> 1))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mobj->eflags & MFE_GOOWATER || wasingoo) { // Decide what happens to your momentum when you enter/leave goopy water.
|
||||
if (P_MobjFlip(mobj)*mobj->momz > 0)
|
||||
if (mobj->eflags & MFE_GOOWATER || wasingoo)
|
||||
{
|
||||
// Decide what happens to your momentum when you enter/leave goopy water.
|
||||
if (P_MobjFlip(mobj) * mobj->momz > 0)
|
||||
{
|
||||
mobj->momz -= (mobj->momz/8); // cut momentum a little bit to prevent multiple bobs
|
||||
//CONS_Printf("leaving\n");
|
||||
|
|
@ -3148,25 +3235,42 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
//CONS_Printf("entering\n");
|
||||
}
|
||||
}
|
||||
else if (wasinwater && P_MobjFlip(mobj)*mobj->momz > 0)
|
||||
mobj->momz = FixedMul(mobj->momz, FixedDiv(780*FRACUNIT, 457*FRACUNIT)); // Give the mobj a little out-of-water boost.
|
||||
|
||||
if (P_MobjFlip(mobj)*mobj->momz < 0)
|
||||
else if (wasinwater && P_MobjFlip(mobj) * mobj->momz > 0)
|
||||
{
|
||||
if ((mobj->eflags & MFE_VERTICALFLIP && thingtop-(height>>1)-mobj->momz <= mobj->waterbottom)
|
||||
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(height>>1)-mobj->momz >= mobj->watertop))
|
||||
// Give the mobj a little out-of-water boost.
|
||||
mobj->momz = FixedMul(mobj->momz, FixedDiv(780*FRACUNIT, 457*FRACUNIT));
|
||||
}
|
||||
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
thingZ = thingtop - (height >> 1);
|
||||
splashValid = (thingZ - mobj->momz <= waterZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
thingZ = mobj->z + (height >> 1);
|
||||
splashValid = (thingZ - mobj->momz >= waterZ);
|
||||
}
|
||||
|
||||
if (P_MobjFlip(mobj) * mobj->momz <= 0)
|
||||
{
|
||||
if (splashValid == true)
|
||||
{
|
||||
// Spawn a splash
|
||||
mobj_t *splish;
|
||||
mobjtype_t splishtype = (mobj->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH;
|
||||
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->waterbottom-FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype);
|
||||
splish = P_SpawnMobj(mobj->x, mobj->y, waterZ - FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype);
|
||||
splish->flags2 |= MF2_OBJECTFLIP;
|
||||
splish->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
else
|
||||
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype);
|
||||
{
|
||||
splish = P_SpawnMobj(mobj->x, mobj->y, waterZ, splishtype);
|
||||
}
|
||||
|
||||
splish->destscale = mobj->scale;
|
||||
P_SetScale(splish, mobj->scale);
|
||||
}
|
||||
|
|
@ -3175,40 +3279,37 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
if (p && p->waterskip < 2
|
||||
&& ((p->speed/3 > abs(mobj->momz)) // Going more forward than horizontal, so you can skip across the water.
|
||||
|| (p->speed > 20*mapobjectscale && p->waterskip)) // Already skipped once, so you can skip once more!
|
||||
&& ((!(mobj->eflags & MFE_VERTICALFLIP) && thingtop - mobj->momz > mobj->watertop)
|
||||
|| ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z - mobj->momz < mobj->waterbottom)))
|
||||
&& (splashValid == true))
|
||||
{
|
||||
const fixed_t hop = 5<<FRACBITS;
|
||||
const fixed_t hop = 5 * mobj->scale;
|
||||
|
||||
mobj->momx = (4*mobj->momx)/5;
|
||||
mobj->momy = (4*mobj->momy)/5;
|
||||
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
mobj->momz = FixedMul(-hop, mobj->scale);
|
||||
else
|
||||
mobj->momz = FixedMul(hop, mobj->scale);
|
||||
mobj->momz = hop * P_MobjFlip(mobj);
|
||||
|
||||
p->waterskip++;
|
||||
}
|
||||
|
||||
}
|
||||
else if (P_MobjFlip(mobj)*mobj->momz > 0)
|
||||
else if (P_MobjFlip(mobj) * mobj->momz > 0)
|
||||
{
|
||||
if (((mobj->eflags & MFE_VERTICALFLIP && thingtop-(height>>1)-mobj->momz > mobj->waterbottom)
|
||||
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(height>>1)-mobj->momz < mobj->watertop))
|
||||
&& !(mobj->eflags & MFE_UNDERWATER)) // underwater check to prevent splashes on opposite side
|
||||
if (splashValid == true && !(mobj->eflags & MFE_UNDERWATER)) // underwater check to prevent splashes on opposite side
|
||||
{
|
||||
// Spawn a splash
|
||||
mobj_t *splish;
|
||||
mobjtype_t splishtype = (mobj->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH;
|
||||
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->waterbottom-FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype);
|
||||
splish = P_SpawnMobj(mobj->x, mobj->y, waterZ - FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype);
|
||||
splish->flags2 |= MF2_OBJECTFLIP;
|
||||
splish->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
else
|
||||
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype);
|
||||
{
|
||||
splish = P_SpawnMobj(mobj->x, mobj->y, waterZ, splishtype);
|
||||
}
|
||||
|
||||
splish->destscale = mobj->scale;
|
||||
P_SetScale(splish, mobj->scale);
|
||||
}
|
||||
|
|
@ -3574,7 +3675,8 @@ static void P_CheckFloatbobPlatforms(mobj_t *mobj)
|
|||
|
||||
static void P_SquishThink(mobj_t *mobj)
|
||||
{
|
||||
if (!(mobj->eflags & MFE_SLOPELAUNCHED))
|
||||
if (!(mobj->flags & MF_NOSQUISH) &&
|
||||
!(mobj->eflags & MFE_SLOPELAUNCHED))
|
||||
{
|
||||
K_Squish(mobj);
|
||||
}
|
||||
|
|
@ -4049,7 +4151,7 @@ static void P_SpawnItemCapsuleParts(mobj_t *mobj)
|
|||
part = part->hnext;
|
||||
P_SetTarget(&part->target, mobj);
|
||||
P_SetMobjState(part, buttState);
|
||||
part->angle = i * ANG_CAPSULE;
|
||||
P_InitAngle(part, i * ANG_CAPSULE);
|
||||
part->movedir = spin; // rotation speed
|
||||
part->movefactor = 0; // z offset
|
||||
part->extravalue1 = buttScale; // relative scale
|
||||
|
|
@ -4060,7 +4162,7 @@ static void P_SpawnItemCapsuleParts(mobj_t *mobj)
|
|||
part = part->hnext;
|
||||
P_SetTarget(&part->target, mobj);
|
||||
P_SetMobjState(part, S_ITEMCAPSULE_TOP_SIDE);
|
||||
part->angle = i * ANG_CAPSULE;
|
||||
P_InitAngle(part, i * ANG_CAPSULE);
|
||||
part->movedir = spin; // rotation speed
|
||||
part->movefactor = mobj->info->height - part->info->height; // z offset
|
||||
}
|
||||
|
|
@ -4385,7 +4487,7 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb
|
|||
mobj->z -= mobj->height>>1;
|
||||
|
||||
// change angle
|
||||
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, x, y);
|
||||
P_InitAngle(mobj, R_PointToAngle2(mobj->x, mobj->y, x, y));
|
||||
|
||||
// change slope
|
||||
dist = P_AproxDistance(P_AproxDistance(x - mobj->x, y - mobj->y), z - mobj->z);
|
||||
|
|
@ -5068,7 +5170,7 @@ static void P_FlameJetSceneryThink(mobj_t *mobj)
|
|||
flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME);
|
||||
P_SetMobjState(flame, S_FLAMEJETFLAME4);
|
||||
|
||||
flame->angle = mobj->angle;
|
||||
P_InitAngle(flame, mobj->angle);
|
||||
|
||||
if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side
|
||||
flame->momz = mobj->fuse << (FRACBITS - 2);
|
||||
|
|
@ -5529,7 +5631,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
{
|
||||
mobj_t *blast = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BATTLEBUMPER_BLAST);
|
||||
|
||||
blast->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy) + ANGLE_45;
|
||||
P_InitAngle(blast, R_PointToAngle2(0, 0, mobj->momx, mobj->momy) + ANGLE_45);
|
||||
blast->destscale *= 4;
|
||||
|
||||
if (i & 1)
|
||||
|
|
@ -6814,12 +6916,15 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
if (( mobj->fuse & 1 ))
|
||||
{
|
||||
nudge = 4*mobj->target->radius;
|
||||
/* unrotate interp angle */
|
||||
mobj->old_angle -= ANGLE_90;
|
||||
}
|
||||
else
|
||||
{
|
||||
nudge = 2*mobj->target->radius;
|
||||
/* rotate the papersprite frames to see the flat angle */
|
||||
mobj->angle += ANGLE_90;
|
||||
mobj->old_angle += ANGLE_90;
|
||||
}
|
||||
|
||||
P_MoveOrigin(mobj,
|
||||
|
|
@ -7014,6 +7119,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
return false;
|
||||
}
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
mobj->old_x = mobj->target->old_x;
|
||||
mobj->old_y = mobj->target->old_y;
|
||||
mobj->old_z = mobj->target->old_z;
|
||||
break;
|
||||
case MT_INSTASHIELDB:
|
||||
mobj->renderflags ^= RF_DONTDRAW;
|
||||
|
|
@ -7026,6 +7134,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
return false;
|
||||
}
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
mobj->old_x = mobj->target->old_x;
|
||||
mobj->old_y = mobj->target->old_y;
|
||||
mobj->old_z = mobj->target->old_z;
|
||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
break;
|
||||
case MT_BATTLEPOINT:
|
||||
|
|
@ -7398,10 +7509,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->z + (mobj->height/2) + (P_RandomRange(-20,20) * mobj->scale),
|
||||
MT_FASTLINE);
|
||||
|
||||
fast->angle = mobj->angle;
|
||||
P_InitAngle(fast, mobj->angle);
|
||||
fast->momx = 3*mobj->target->momx/4;
|
||||
fast->momy = 3*mobj->target->momy/4;
|
||||
fast->momz = 3*mobj->target->momz/4;
|
||||
fast->momz = 3*P_GetMobjZMovement(mobj->target)/4;
|
||||
|
||||
K_MatchGenericExtraFlags(fast, mobj);
|
||||
P_SetMobjState(fast, S_FLAMESHIELDLINE1 + i);
|
||||
|
|
@ -7460,7 +7571,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
if (underlayst != S_NULL)
|
||||
{
|
||||
mobj_t *underlay = P_SpawnMobj(mobj->target->x, mobj->target->y, mobj->target->z, MT_FLAMESHIELDUNDERLAY);
|
||||
underlay->angle = mobj->angle;
|
||||
P_InitAngle(underlay, mobj->angle);
|
||||
P_SetMobjState(underlay, underlayst);
|
||||
}
|
||||
break;
|
||||
|
|
@ -8838,7 +8949,7 @@ static boolean P_FuseThink(mobj_t *mobj)
|
|||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
mobj_t *debris = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_DEBRIS);
|
||||
debris->angle = FixedAngle(P_RandomRange(0,360)<<FRACBITS);
|
||||
P_InitAngle(debris, FixedAngle(P_RandomRange(0,360)<<FRACBITS));
|
||||
P_InstaThrust(debris, debris->angle, P_RandomRange(3,18)*(FRACUNIT/4));
|
||||
debris->momz = P_RandomRange(4,8)<<FRACBITS;
|
||||
if (!i) // kinda hacky :V
|
||||
|
|
@ -9614,7 +9725,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
case MT_CRUSHSTACEAN:
|
||||
{
|
||||
mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_CRUSHCLAW);
|
||||
bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);;
|
||||
P_InitAngle(bigmeatyclaw, mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270));
|
||||
P_SetTarget(&mobj->tracer, bigmeatyclaw);
|
||||
P_SetTarget(&bigmeatyclaw->tracer, mobj);
|
||||
mobj->reactiontime >>= 1;
|
||||
|
|
@ -9623,7 +9734,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
case MT_BANPYURA:
|
||||
{
|
||||
mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BANPSPRING);
|
||||
bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);;
|
||||
P_InitAngle(bigmeatyclaw, mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270));
|
||||
P_SetTarget(&mobj->tracer, bigmeatyclaw);
|
||||
P_SetTarget(&bigmeatyclaw->tracer, mobj);
|
||||
mobj->reactiontime >>= 1;
|
||||
|
|
@ -9756,7 +9867,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
break;
|
||||
case MT_MINECARTEND:
|
||||
P_SetTarget(&mobj->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID));
|
||||
mobj->tracer->angle = mobj->angle + ANGLE_90;
|
||||
P_InitAngle(mobj->tracer, mobj->angle + ANGLE_90);
|
||||
break;
|
||||
case MT_TORCHFLOWER:
|
||||
{
|
||||
|
|
@ -9878,7 +9989,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
angle_t ang = i * diff;
|
||||
mobj_t *side = P_SpawnMobj(mobj->x + FINECOSINE((ang>>ANGLETOFINESHIFT) & FINEMASK),
|
||||
mobj->y + FINESINE((ang>>ANGLETOFINESHIFT) & FINEMASK), mobj->z, MT_DAYTONAPINETREE_SIDE);
|
||||
side->angle = ang;
|
||||
P_InitAngle(side, ang);
|
||||
side->target = mobj;
|
||||
side->threshold = i;
|
||||
}
|
||||
|
|
@ -9895,7 +10006,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
|
||||
cur = P_SpawnMobj(mobj->x + FINECOSINE(((mobj->angle*8)>>ANGLETOFINESHIFT) & FINEMASK),
|
||||
mobj->y + FINESINE(((mobj->angle*8)>>ANGLETOFINESHIFT) & FINEMASK), mobj->z, MT_EZZPROPELLER_BLADE);
|
||||
cur->angle = mobj->angle;
|
||||
P_InitAngle(cur, mobj->angle);
|
||||
|
||||
P_SetTarget(&cur->hprev, prev);
|
||||
P_SetTarget(&prev->hnext, cur);
|
||||
|
|
@ -9955,7 +10066,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
cur->threshold = i;
|
||||
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);
|
||||
P_InitAngle(cur, ANGLE_90*(cur->threshold+1));
|
||||
|
||||
P_SetTarget(&cur->hprev, prev);
|
||||
P_SetTarget(&prev->hnext, cur);
|
||||
|
|
@ -10384,6 +10495,8 @@ void P_PrecipitationEffects(void)
|
|||
boolean effects_lightning = (precipprops[curWeather].effects & PRECIPFX_LIGHTNING);
|
||||
boolean lightningStrike = false;
|
||||
|
||||
boolean sounds_rain = (rainsfx != sfx_None && (!leveltime || leveltime % rainfreq == 1));
|
||||
|
||||
// No thunder except every other tic.
|
||||
if (!(leveltime & 1))
|
||||
{
|
||||
|
|
@ -10428,29 +10541,48 @@ void P_PrecipitationEffects(void)
|
|||
if (sound_disabled)
|
||||
return; // Sound off? D'aw, no fun.
|
||||
|
||||
if (!sounds_rain && !sounds_thunder)
|
||||
return; // no need to calculate volume at ALL
|
||||
|
||||
if (players[g_localplayers[0]].mo->subsector->sector->ceilingpic == skyflatnum)
|
||||
volume = 255; // Sky above? We get it full blast.
|
||||
else
|
||||
{
|
||||
fixed_t x, y, yl, yh, xl, xh;
|
||||
INT64 x, y, yl, yh, xl, xh;
|
||||
fixed_t closedist, newdist;
|
||||
|
||||
// Essentially check in a 1024 unit radius of the player for an outdoor area.
|
||||
yl = players[g_localplayers[0]].mo->y - 1024*FRACUNIT;
|
||||
yh = players[g_localplayers[0]].mo->y + 1024*FRACUNIT;
|
||||
xl = players[g_localplayers[0]].mo->x - 1024*FRACUNIT;
|
||||
xh = players[g_localplayers[0]].mo->x + 1024*FRACUNIT;
|
||||
closedist = 2048*FRACUNIT;
|
||||
for (y = yl; y <= yh; y += FRACUNIT*64)
|
||||
for (x = xl; x <= xh; x += FRACUNIT*64)
|
||||
#define RADIUSSTEP (64*FRACUNIT)
|
||||
#define SEARCHRADIUS (16*RADIUSSTEP)
|
||||
yl = yh = players[g_localplayers[0]].mo->y;
|
||||
yl -= SEARCHRADIUS;
|
||||
while (yl < INT32_MIN)
|
||||
yl += RADIUSSTEP;
|
||||
yh += SEARCHRADIUS;
|
||||
while (yh > INT32_MAX)
|
||||
yh -= RADIUSSTEP;
|
||||
|
||||
xl = xh = players[g_localplayers[0]].mo->x;
|
||||
xl -= SEARCHRADIUS;
|
||||
while (xl < INT32_MIN)
|
||||
xl += RADIUSSTEP;
|
||||
xh += SEARCHRADIUS;
|
||||
while (xh > INT32_MAX)
|
||||
xh -= RADIUSSTEP;
|
||||
|
||||
closedist = SEARCHRADIUS*2;
|
||||
#undef SEARCHRADIUS
|
||||
for (y = yl; y <= yh; y += RADIUSSTEP)
|
||||
for (x = xl; x <= xh; x += RADIUSSTEP)
|
||||
{
|
||||
if (R_PointInSubsector(x, y)->sector->ceilingpic == skyflatnum) // Found the outdoors!
|
||||
if (R_PointInSubsector((fixed_t)x, (fixed_t)y)->sector->ceilingpic == skyflatnum) // Found the outdoors!
|
||||
{
|
||||
newdist = S_CalculateSoundDistance(players[g_localplayers[0]].mo->x, players[g_localplayers[0]].mo->y, 0, x, y, 0);
|
||||
newdist = S_CalculateSoundDistance(players[g_localplayers[0]].mo->x, players[g_localplayers[0]].mo->y, 0, (fixed_t)x, (fixed_t)y, 0);
|
||||
if (newdist < closedist)
|
||||
closedist = newdist;
|
||||
}
|
||||
}
|
||||
#undef RADIUSSTEP
|
||||
|
||||
volume = 255 - (closedist>>(FRACBITS+2));
|
||||
}
|
||||
|
|
@ -10460,7 +10592,7 @@ void P_PrecipitationEffects(void)
|
|||
else if (volume > 255)
|
||||
volume = 255;
|
||||
|
||||
if (rainsfx != sfx_None && (!leveltime || leveltime % rainfreq == 1))
|
||||
if (sounds_rain)
|
||||
S_StartSoundAtVolume(players[g_localplayers[0]].mo, rainsfx, volume);
|
||||
|
||||
if (!sounds_thunder)
|
||||
|
|
@ -10716,7 +10848,7 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER);
|
||||
(mobj->player = p)->mo = mobj;
|
||||
|
||||
mobj->angle = 0;
|
||||
mobj->angle = mobj->old_angle = 0;
|
||||
|
||||
// set color translations for player sprites
|
||||
mobj->color = p->skincolor;
|
||||
|
|
@ -10737,11 +10869,17 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
p->awayviewmobj = NULL;
|
||||
p->awayviewtics = 0;
|
||||
|
||||
p->skybox.viewpoint = skyboxviewpnts[0];
|
||||
p->skybox.centerpoint = skyboxcenterpnts[0];
|
||||
|
||||
P_SetTarget(&p->follower, NULL); // cleanse follower from existence
|
||||
|
||||
if (K_PlayerShrinkCheat(p) == true)
|
||||
{
|
||||
mobj->destscale = FixedMul(mobj->destscale, SHRINK_SCALE);
|
||||
}
|
||||
|
||||
// set the scale to the mobj's destscale so settings get correctly set. if we don't, they sometimes don't.
|
||||
if (cv_kartdebugshrink.value && !modeattacking && !p->bot)
|
||||
mobj->destscale = 6*mobj->destscale/8;
|
||||
P_SetScale(mobj, mobj->destscale);
|
||||
P_FlashPal(p, 0, 0); // Resets
|
||||
|
||||
|
|
@ -10803,6 +10941,12 @@ void P_AfterPlayerSpawn(INT32 playernum)
|
|||
mobj_t *mobj = p->mo;
|
||||
UINT8 i;
|
||||
|
||||
// Update interpolation
|
||||
mobj->old_x = mobj->x;
|
||||
mobj->old_y = mobj->y;
|
||||
mobj->old_z = mobj->z;
|
||||
mobj->old_angle = mobj->angle;
|
||||
|
||||
P_SetPlayerAngle(p, mobj->angle);
|
||||
|
||||
p->viewheight = P_GetPlayerViewHeight(p);
|
||||
|
|
@ -11397,7 +11541,7 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle)
|
|||
spawnee->friction = mroll;\
|
||||
spawnee->movefactor = mwidthset;\
|
||||
spawnee->movecount = dist;\
|
||||
spawnee->angle = myaw;\
|
||||
P_InitAngle(spawnee, myaw);\
|
||||
spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\
|
||||
spawnee->flags2 |= (mflags2apply|moreflags2);\
|
||||
spawnee->eflags |= meflagsapply;\
|
||||
|
|
@ -11596,29 +11740,29 @@ static boolean P_SetupBooster(mapthing_t* mthing, mobj_t* mobj, boolean strong)
|
|||
statenum_t rollerstate = strong ? S_REDBOOSTERROLLER : S_YELLOWBOOSTERROLLER;
|
||||
|
||||
mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle - ANGLE_90;
|
||||
P_InitAngle(seg, angle - ANGLE_90);
|
||||
P_SetMobjState(seg, facestate);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle + ANGLE_90;
|
||||
P_InitAngle(seg, angle + ANGLE_90);
|
||||
P_SetMobjState(seg, facestate);
|
||||
seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle;
|
||||
P_InitAngle(seg, angle);
|
||||
P_SetMobjState(seg, leftstate);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle;
|
||||
P_InitAngle(seg, angle);
|
||||
P_SetMobjState(seg, rightstate);
|
||||
|
||||
seg = P_SpawnMobjFromMobj(mobj, 13*(x1 + x2), 13*(y1 + y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_InitAngle(seg, angle);
|
||||
P_SetMobjState(seg, rollerstate);
|
||||
seg = P_SpawnMobjFromMobj(mobj, 13*(x1 - x2), 13*(y1 - y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_InitAngle(seg, angle);
|
||||
P_SetMobjState(seg, rollerstate);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -13*(x1 + x2), -13*(y1 + y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_InitAngle(seg, angle);
|
||||
P_SetMobjState(seg, rollerstate);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -13*(x1 - x2), -13*(y1 - y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_InitAngle(seg, angle);
|
||||
P_SetMobjState(seg, rollerstate);
|
||||
|
||||
return true;
|
||||
|
|
@ -11795,19 +11939,19 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
case MT_THZTREE:
|
||||
{ // Spawn the branches
|
||||
angle_t mobjangle = FixedAngle((mthing->angle % 113) << FRACBITS);
|
||||
P_SpawnMobjFromMobj(mobj, FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_22h;
|
||||
P_SpawnMobjFromMobj(mobj, 0, FRACUNIT, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_157h;
|
||||
P_SpawnMobjFromMobj(mobj, -FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_270;
|
||||
P_InitAngle(P_SpawnMobjFromMobj(mobj, FRACUNIT, 0, 0, MT_THZTREEBRANCH), mobjangle + ANGLE_22h);
|
||||
P_InitAngle(P_SpawnMobjFromMobj(mobj, 0, FRACUNIT, 0, MT_THZTREEBRANCH), mobjangle + ANGLE_157h);
|
||||
P_InitAngle(P_SpawnMobjFromMobj(mobj, -FRACUNIT, 0, 0, MT_THZTREEBRANCH), mobjangle + ANGLE_270);
|
||||
}
|
||||
break;
|
||||
case MT_CEZPOLE1:
|
||||
case MT_CEZPOLE2:
|
||||
{ // Spawn the banner
|
||||
angle_t mobjangle = FixedAngle(mthing->angle << FRACBITS);
|
||||
P_SpawnMobjFromMobj(mobj,
|
||||
P_InitAngle(P_SpawnMobjFromMobj(mobj,
|
||||
P_ReturnThrustX(mobj, mobjangle, 4 << FRACBITS),
|
||||
P_ReturnThrustY(mobj, mobjangle, 4 << FRACBITS),
|
||||
0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2))->angle = mobjangle + ANGLE_90;
|
||||
0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2)), mobjangle + ANGLE_90);
|
||||
}
|
||||
break;
|
||||
case MT_HHZTREE_TOP:
|
||||
|
|
@ -11816,7 +11960,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
mobj_t* leaf;
|
||||
#define doleaf(x, y) \
|
||||
leaf = P_SpawnMobjFromMobj(mobj, x, y, 0, MT_HHZTREE_PART);\
|
||||
leaf->angle = mobjangle;\
|
||||
P_InitAngle(leaf, mobjangle);\
|
||||
P_SetMobjState(leaf, leaf->info->seestate);\
|
||||
mobjangle += ANGLE_90
|
||||
doleaf(FRACUNIT, 0);
|
||||
|
|
@ -11840,7 +11984,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
fixed_t xoffs = FINECOSINE(fa);
|
||||
fixed_t yoffs = FINESINE(fa);
|
||||
mobj_t* leaf = P_SpawnMobjFromMobj(mobj, xoffs, yoffs, 0, MT_BIGFERNLEAF);
|
||||
leaf->angle = angle;
|
||||
P_InitAngle(leaf, angle);
|
||||
angle += ANGLE_45;
|
||||
}
|
||||
break;
|
||||
|
|
@ -11950,7 +12094,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius),
|
||||
mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius),
|
||||
mobj->z, MT_WALLSPIKEBASE);
|
||||
base->angle = mobjangle + ANGLE_90;
|
||||
P_InitAngle(base, mobjangle + ANGLE_90);
|
||||
base->destscale = mobj->destscale;
|
||||
P_SetScale(base, mobj->scale);
|
||||
P_SetTarget(&base->target, mobj);
|
||||
|
|
@ -12136,7 +12280,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
|
||||
leaf = P_SpawnMobj(mobj->x + FINECOSINE((mobj->angle>>ANGLETOFINESHIFT) & FINEMASK),
|
||||
mobj->y + FINESINE((mobj->angle>>ANGLETOFINESHIFT) & FINEMASK), top, MT_AAZTREE_LEAF);
|
||||
leaf->angle = mobj->angle;
|
||||
P_InitAngle(leaf, mobj->angle);
|
||||
|
||||
// Small coconut for each leaf
|
||||
P_SpawnMobj(mobj->x + (32 * FINECOSINE((mobj->angle>>ANGLETOFINESHIFT) & FINEMASK)),
|
||||
|
|
@ -12353,7 +12497,9 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y,
|
|||
return mobj;
|
||||
|
||||
if (doangle)
|
||||
mobj->angle = FixedAngle(mthing->angle << FRACBITS);
|
||||
{
|
||||
P_InitAngle(mobj, FixedAngle(mthing->angle << FRACBITS));
|
||||
}
|
||||
|
||||
if ((mobj->flags & MF_SPRING)
|
||||
&& mobj->info->damage != 0
|
||||
|
|
@ -12365,8 +12511,8 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y,
|
|||
mobj->spryoff = FixedMul(mobj->radius, FINESINE(a >> ANGLETOFINESHIFT));
|
||||
}
|
||||
|
||||
mobj->pitch = FixedAngle(mthing->pitch << FRACBITS);
|
||||
mobj->roll = FixedAngle(mthing->roll << FRACBITS);
|
||||
P_InitPitch(mobj, FixedAngle(mthing->pitch << FRACBITS));
|
||||
P_InitRoll(mobj, FixedAngle(mthing->roll << FRACBITS));
|
||||
|
||||
mthing->mobj = mobj;
|
||||
|
||||
|
|
@ -12773,7 +12919,7 @@ mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type,
|
|||
P_SetTarget(&th->target, source); // where it came from
|
||||
an = R_PointToAngle2(x, y, dest->x, dest->y);
|
||||
|
||||
th->angle = an;
|
||||
P_InitAngle(th, an);
|
||||
an >>= ANGLETOFINESHIFT;
|
||||
th->momx = FixedMul(speed, FINECOSINE(an));
|
||||
th->momy = FixedMul(speed, FINESINE(an));
|
||||
|
|
@ -12835,7 +12981,7 @@ mobj_t *P_SpawnAlteredDirectionMissile(mobj_t *source, mobjtype_t type, fixed_t
|
|||
P_SetTarget(&th->target, source->target); // where it came from
|
||||
an = R_PointToAngle2(0, 0, source->momx, source->momy) + (ANG1*shiftingAngle);
|
||||
|
||||
th->angle = an;
|
||||
P_InitAngle(th, an);
|
||||
an >>= ANGLETOFINESHIFT;
|
||||
th->momx = FixedMul(speed, FINECOSINE(an));
|
||||
th->momy = FixedMul(speed, FINESINE(an));
|
||||
|
|
@ -12900,7 +13046,7 @@ mobj_t *P_SpawnPointMissile(mobj_t *source, fixed_t xa, fixed_t ya, fixed_t za,
|
|||
P_SetTarget(&th->target, source); // where it came from
|
||||
an = R_PointToAngle2(x, y, xa, ya);
|
||||
|
||||
th->angle = an;
|
||||
P_InitAngle(th, an);
|
||||
an >>= ANGLETOFINESHIFT;
|
||||
th->momx = FixedMul(speed, FINECOSINE(an));
|
||||
th->momy = FixedMul(speed, FINESINE(an));
|
||||
|
|
@ -12979,7 +13125,7 @@ mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type)
|
|||
else
|
||||
an = R_PointToAngle2(source->x, source->y, dest->x, dest->y);
|
||||
|
||||
th->angle = an;
|
||||
P_InitAngle(th, an);
|
||||
an >>= ANGLETOFINESHIFT;
|
||||
th->momx = FixedMul(speed, FINECOSINE(an));
|
||||
th->momy = FixedMul(speed, FINESINE(an));
|
||||
|
|
@ -13067,7 +13213,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai
|
|||
|
||||
speed = th->info->speed;
|
||||
|
||||
th->angle = an;
|
||||
P_InitAngle(th, an);
|
||||
th->momx = FixedMul(speed, FINECOSINE(an>>ANGLETOFINESHIFT));
|
||||
th->momy = FixedMul(speed, FINESINE(an>>ANGLETOFINESHIFT));
|
||||
|
||||
|
|
@ -13137,6 +13283,17 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
|
|||
newmobj->z = mobj->z + mobj->height - zofs - newmobj->height;
|
||||
}
|
||||
|
||||
// EXPERIMENT: Let all objects set their interp values relative to their owner's old values.
|
||||
// This will hopefully create a lot less mobj-specific spawn cases,
|
||||
// but if there's any weird scenarios feel free to remove again.
|
||||
newmobj->old_x = mobj->old_x + xofs;
|
||||
newmobj->old_y = mobj->old_y + yofs;
|
||||
newmobj->old_z = mobj->old_z + zofs;
|
||||
/*
|
||||
newmobj->angle = mobj->angle;
|
||||
newmobj->old_angle = mobj->old_angle;
|
||||
*/
|
||||
|
||||
return newmobj;
|
||||
}
|
||||
|
||||
|
|
@ -13153,6 +13310,14 @@ fixed_t P_GetMobjHead(const mobj_t *mobj)
|
|||
|
||||
fixed_t P_GetMobjFeet(const mobj_t *mobj)
|
||||
{
|
||||
/*
|
||||
| |
|
||||
| |
|
||||
/--\------/ |
|
||||
| |
|
||||
-----------------
|
||||
*/
|
||||
|
||||
return P_IsObjectFlipped(mobj) ? mobj->z + mobj->height : mobj->z;
|
||||
}
|
||||
|
||||
|
|
@ -13164,3 +13329,25 @@ fixed_t P_GetMobjGround(const mobj_t *mobj)
|
|||
{
|
||||
return P_IsObjectFlipped(mobj) ? mobj->ceilingz : mobj->floorz;
|
||||
}
|
||||
|
||||
//
|
||||
// P_GetMobjZMovement
|
||||
// Returns the Z momentum of the object, accounting for slopes if the object is grounded
|
||||
//
|
||||
fixed_t P_GetMobjZMovement(mobj_t *mo)
|
||||
{
|
||||
pslope_t *slope = mo->standingslope;
|
||||
angle_t angDiff;
|
||||
fixed_t speed;
|
||||
|
||||
if (!P_IsObjectOnGround(mo))
|
||||
return mo->momz;
|
||||
|
||||
if (!slope)
|
||||
return 0;
|
||||
|
||||
angDiff = R_PointToAngle2(0, 0, mo->momx, mo->momy) - slope->xydirection;
|
||||
speed = FixedHypot(mo->momx, mo->momy);
|
||||
|
||||
return P_ReturnThrustY(mo, slope->zangle, P_ReturnThrustX(mo, angDiff, speed));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,7 +159,11 @@ typedef enum
|
|||
MF_DONTENCOREMAP = 1<<28,
|
||||
// Hitbox extends just as far below as above.
|
||||
MF_PICKUPFROMBELOW = 1<<29,
|
||||
// free: to and including 1<<31
|
||||
// Disable momentum-based squash and stretch.
|
||||
MF_NOSQUISH = 1<<30,
|
||||
// Disable hitlag for this object
|
||||
MF_NOHITLAGFORME = 1<<31,
|
||||
// no more free slots, next up I suppose we can get rid of shit like MF_BOXICON?
|
||||
} mobjflag_t;
|
||||
|
||||
typedef enum
|
||||
|
|
@ -395,6 +399,7 @@ typedef struct mobj_s
|
|||
|
||||
fixed_t sprxoff, spryoff, sprzoff; // Sprite offsets in real space, does NOT affect position or collision
|
||||
|
||||
struct terrain_s *terrain; // Terrain definition of the floor this object last hit. NULL when in the air.
|
||||
INT32 hitlag; // Sal-style hit lag, straight from Captain Fetch's jowls
|
||||
|
||||
// WARNING: New fields must be added separately to savegame and Lua.
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
// SRB2Kart
|
||||
#include "k_battle.h"
|
||||
#include "k_pwrlv.h"
|
||||
#include "k_terrain.h"
|
||||
|
||||
savedata_t savedata;
|
||||
UINT8 *save_p;
|
||||
|
|
@ -59,6 +60,8 @@ typedef enum
|
|||
AWAYVIEW = 0x01,
|
||||
FOLLOWITEM = 0x02,
|
||||
FOLLOWER = 0x04,
|
||||
SKYBOXVIEW = 0x08,
|
||||
SKYBOXCENTER = 0x10,
|
||||
} player_saveflags;
|
||||
|
||||
static inline void P_ArchivePlayer(void)
|
||||
|
|
@ -177,6 +180,12 @@ static void P_NetArchivePlayers(void)
|
|||
if (players[i].follower)
|
||||
flags |= FOLLOWER;
|
||||
|
||||
if (players[i].skybox.viewpoint)
|
||||
flags |= SKYBOXVIEW;
|
||||
|
||||
if (players[i].skybox.centerpoint)
|
||||
flags |= SKYBOXCENTER;
|
||||
|
||||
WRITEINT16(save_p, players[i].lastsidehit);
|
||||
WRITEINT16(save_p, players[i].lastlinehit);
|
||||
|
||||
|
|
@ -189,6 +198,12 @@ static void P_NetArchivePlayers(void)
|
|||
|
||||
WRITEUINT16(save_p, flags);
|
||||
|
||||
if (flags & SKYBOXVIEW)
|
||||
WRITEUINT32(save_p, players[i].skybox.viewpoint->mobjnum);
|
||||
|
||||
if (flags & SKYBOXCENTER)
|
||||
WRITEUINT32(save_p, players[i].skybox.centerpoint->mobjnum);
|
||||
|
||||
if (flags & AWAYVIEW)
|
||||
WRITEUINT32(save_p, players[i].awayviewmobj->mobjnum);
|
||||
|
||||
|
|
@ -446,6 +461,12 @@ static void P_NetUnArchivePlayers(void)
|
|||
|
||||
flags = READUINT16(save_p);
|
||||
|
||||
if (flags & SKYBOXVIEW)
|
||||
players[i].skybox.viewpoint = (mobj_t *)(size_t)READUINT32(save_p);
|
||||
|
||||
if (flags & SKYBOXCENTER)
|
||||
players[i].skybox.centerpoint = (mobj_t *)(size_t)READUINT32(save_p);
|
||||
|
||||
if (flags & AWAYVIEW)
|
||||
players[i].awayviewmobj = (mobj_t *)(size_t)READUINT32(save_p);
|
||||
|
||||
|
|
@ -1540,6 +1561,7 @@ typedef enum
|
|||
MD2_KITEMCAP = 1<<26,
|
||||
MD2_ITNEXT = 1<<27,
|
||||
MD2_LASTMOMZ = 1<<28,
|
||||
MD2_TERRAIN = 1<<29,
|
||||
} mobj_diff2_t;
|
||||
|
||||
typedef enum
|
||||
|
|
@ -1782,6 +1804,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
diff2 |= MD2_ITNEXT;
|
||||
if (mobj->lastmomz)
|
||||
diff2 |= MD2_LASTMOMZ;
|
||||
if (mobj->terrain != NULL)
|
||||
diff2 |= MD2_TERRAIN;
|
||||
|
||||
if (diff2 != 0)
|
||||
diff |= MD_MORE;
|
||||
|
|
@ -1979,6 +2003,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
{
|
||||
WRITEINT32(save_p, mobj->lastmomz);
|
||||
}
|
||||
if (diff2 & MD2_TERRAIN)
|
||||
{
|
||||
WRITEUINT32(save_p, K_GetTerrainHeapIndex(mobj->terrain));
|
||||
}
|
||||
|
||||
WRITEUINT32(save_p, mobj->mobjnum);
|
||||
}
|
||||
|
|
@ -2885,19 +2913,19 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
mobj->info = &mobjinfo[mobj->type];
|
||||
if (diff & MD_POS)
|
||||
{
|
||||
mobj->x = READFIXED(save_p);
|
||||
mobj->y = READFIXED(save_p);
|
||||
mobj->angle = READANGLE(save_p);
|
||||
mobj->pitch = READANGLE(save_p);
|
||||
mobj->roll = READANGLE(save_p);
|
||||
mobj->x = mobj->old_x = READFIXED(save_p);
|
||||
mobj->y = mobj->old_y = READFIXED(save_p);
|
||||
mobj->angle = mobj->old_angle = READANGLE(save_p);
|
||||
mobj->pitch = mobj->old_pitch = READANGLE(save_p);
|
||||
mobj->roll = mobj->old_roll = READANGLE(save_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->x = mobj->spawnpoint->x << FRACBITS;
|
||||
mobj->y = mobj->spawnpoint->y << FRACBITS;
|
||||
mobj->angle = FixedAngle(mobj->spawnpoint->angle*FRACUNIT);
|
||||
mobj->pitch = FixedAngle(mobj->spawnpoint->pitch*FRACUNIT);
|
||||
mobj->roll = FixedAngle(mobj->spawnpoint->roll*FRACUNIT);
|
||||
mobj->x = mobj->old_x = mobj->spawnpoint->x << FRACBITS;
|
||||
mobj->y = mobj->old_y = mobj->spawnpoint->y << FRACBITS;
|
||||
mobj->angle = mobj->old_angle = FixedAngle(mobj->spawnpoint->angle*FRACUNIT);
|
||||
mobj->pitch = mobj->old_pitch = FixedAngle(mobj->spawnpoint->pitch*FRACUNIT);
|
||||
mobj->roll = mobj->old_roll = FixedAngle(mobj->spawnpoint->roll*FRACUNIT);
|
||||
}
|
||||
if (diff & MD_MOM)
|
||||
{
|
||||
|
|
@ -3077,6 +3105,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
{
|
||||
mobj->lastmomz = READINT32(save_p);
|
||||
}
|
||||
if (diff2 & MD2_TERRAIN)
|
||||
{
|
||||
mobj->terrain = (terrain_t *)(size_t)READUINT32(save_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->terrain = NULL;
|
||||
}
|
||||
|
||||
if (diff & MD_REDFLAG)
|
||||
{
|
||||
|
|
@ -4103,8 +4139,31 @@ static void P_RelinkPointers(void)
|
|||
if (!(mobj->itnext = P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "itnext not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->terrain)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->terrain;
|
||||
mobj->terrain = K_GetTerrainByIndex(temp);
|
||||
if (mobj->terrain == NULL)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "terrain not found on %d\n", mobj->type);
|
||||
}
|
||||
}
|
||||
if (mobj->player)
|
||||
{
|
||||
if ( mobj->player->skybox.viewpoint)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->skybox.viewpoint;
|
||||
mobj->player->skybox.viewpoint = NULL;
|
||||
if (!P_SetTarget(&mobj->player->skybox.viewpoint, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "skybox.viewpoint not found on %d\n", mobj->type);
|
||||
}
|
||||
if ( mobj->player->skybox.centerpoint)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->skybox.centerpoint;
|
||||
mobj->player->skybox.centerpoint = NULL;
|
||||
if (!P_SetTarget(&mobj->player->skybox.centerpoint, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "skybox.centerpoint not found on %d\n", mobj->type);
|
||||
}
|
||||
if ( mobj->player->awayviewmobj)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->awayviewmobj;
|
||||
|
|
|
|||
124
src/p_setup.c
124
src/p_setup.c
|
|
@ -91,7 +91,9 @@
|
|||
#include "k_waypoint.h"
|
||||
#include "k_bot.h"
|
||||
#include "k_grandprix.h"
|
||||
#include "k_terrain.h" // TRF_TRIPWIRE
|
||||
#include "k_brightmap.h"
|
||||
#include "k_director.h" // K_InitDirector
|
||||
|
||||
// Replay names have time
|
||||
#if !defined (UNDER_CE)
|
||||
|
|
@ -660,6 +662,9 @@ flatfound:
|
|||
levelflat->u.flat.baselumpnum = LUMPERROR;
|
||||
}
|
||||
|
||||
levelflat->terrain =
|
||||
K_GetTerrainForTextureName(levelflat->name);
|
||||
|
||||
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
|
||||
|
||||
return ( numlevelflats++ );
|
||||
|
|
@ -1935,26 +1940,85 @@ static void P_LoadTextmap(void)
|
|||
}
|
||||
}
|
||||
|
||||
static fixed_t
|
||||
P_MirrorTextureOffset
|
||||
( fixed_t offset,
|
||||
fixed_t source_width,
|
||||
fixed_t actual_width)
|
||||
{
|
||||
/*
|
||||
Adjusting the horizontal alignment is a bit ASS...
|
||||
Textures on the opposite side of the line will begin
|
||||
drawing from the opposite end.
|
||||
|
||||
Start with the texture width and subtract the seg
|
||||
length to account for cropping/wrapping. Subtract the
|
||||
offset to mirror the alignment.
|
||||
*/
|
||||
return source_width - actual_width - offset;
|
||||
}
|
||||
|
||||
static boolean P_CheckLineSideTripWire(line_t *ld, int p)
|
||||
{
|
||||
INT32 n;
|
||||
|
||||
side_t *sda;
|
||||
side_t *sdb;
|
||||
|
||||
terrain_t *terrain;
|
||||
|
||||
boolean tripwire;
|
||||
|
||||
n = ld->sidenum[p];
|
||||
|
||||
if (n == 0xffff)
|
||||
return false;
|
||||
|
||||
sda = &sides[n];
|
||||
|
||||
terrain = K_GetTerrainForTextureNum(sda->midtexture);
|
||||
tripwire = terrain && (terrain->flags & TRF_TRIPWIRE);
|
||||
|
||||
if (tripwire)
|
||||
{
|
||||
// copy midtexture to other side
|
||||
n = ld->sidenum[!p];
|
||||
|
||||
if (n != 0xffff)
|
||||
{
|
||||
fixed_t linelength = FixedHypot(ld->dx, ld->dy);
|
||||
texture_t *tex = textures[sda->midtexture];
|
||||
|
||||
sdb = &sides[n];
|
||||
|
||||
sdb->midtexture = sda->midtexture;
|
||||
sdb->rowoffset = sda->rowoffset;
|
||||
|
||||
// mirror texture alignment
|
||||
sdb->textureoffset = P_MirrorTextureOffset(
|
||||
sda->textureoffset, tex->width * FRACUNIT,
|
||||
linelength);
|
||||
}
|
||||
}
|
||||
|
||||
return tripwire;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
// Check for tripwire, if either side matches then
|
||||
// copy that (mid)texture to the other side.
|
||||
ld->tripwire =
|
||||
P_CheckLineSideTripWire(ld, 0) ||
|
||||
P_CheckLineSideTripWire(ld, 1);
|
||||
|
||||
switch (ld->special)
|
||||
{
|
||||
|
|
@ -3464,6 +3528,7 @@ static void P_InitLevelSettings(void)
|
|||
players[i].lives = 3;
|
||||
|
||||
G_PlayerReborn(i, true);
|
||||
K_UpdateShrinkCheat(&players[i]);
|
||||
}
|
||||
|
||||
racecountdown = exitcountdown = exitfadestarted = 0;
|
||||
|
|
@ -3513,6 +3578,7 @@ static void P_InitLevelSettings(void)
|
|||
speedscramble = encorescramble = -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Respawns all the mapthings and mobjs in the map from the already loaded map data.
|
||||
void P_RespawnThings(void)
|
||||
{
|
||||
|
|
@ -3547,6 +3613,7 @@ void P_RespawnThings(void)
|
|||
skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0];
|
||||
skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0];
|
||||
}
|
||||
#endif
|
||||
|
||||
static void P_RunLevelScript(const char *scriptname)
|
||||
{
|
||||
|
|
@ -3621,14 +3688,19 @@ static void P_ResetSpawnpoints(void)
|
|||
|
||||
// reset the player starts
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL;
|
||||
|
||||
if (playeringame[i])
|
||||
{
|
||||
players[i].skybox.viewpoint = NULL;
|
||||
players[i].skybox.centerpoint = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_DM_STARTS; i++)
|
||||
deathmatchstarts[i] = NULL;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
skyboxmo[i] = NULL;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL;
|
||||
}
|
||||
|
|
@ -3797,12 +3869,20 @@ static void P_InitGametype(void)
|
|||
//@TODO I'd like to fix dedis crashing when recording replays for the future too...
|
||||
if (!demo.playback && multiplayer && !dedicated)
|
||||
{
|
||||
static char buf[256];
|
||||
char *path;
|
||||
sprintf(buf, "media"PATHSEP"replay"PATHSEP"online"PATHSEP"%d-%s", (int) (time(NULL)), G_BuildMapName(gamemap));
|
||||
char buf[MAX_WADPATH];
|
||||
char ver[128];
|
||||
int parts;
|
||||
|
||||
path = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online", srb2home);
|
||||
M_MkdirEach(path, M_PathParts(path) - 4, 0755);
|
||||
#ifdef DEVELOP
|
||||
sprintf(ver, "%s-%s", compbranch, comprevision);
|
||||
#else
|
||||
strcpy(ver, VERSIONSTRING);
|
||||
#endif
|
||||
sprintf(buf, "%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online"PATHSEP"%s"PATHSEP"%d-%s",
|
||||
srb2home, ver, (int) (time(NULL)), G_BuildMapName(gamemap));
|
||||
|
||||
parts = M_PathParts(buf);
|
||||
M_MkdirEachUntil(buf, parts - 5, parts - 1, 0755);
|
||||
|
||||
G_RecordDemo(buf);
|
||||
}
|
||||
|
|
@ -4067,8 +4147,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
P_SpawnSpecialsAfterSlopes();
|
||||
|
||||
P_SpawnMapThings(!fromnetsave);
|
||||
skyboxmo[0] = skyboxviewpnts[0];
|
||||
skyboxmo[1] = skyboxcenterpnts[0];
|
||||
|
||||
for (numcoopstarts = 0; numcoopstarts < MAXPLAYERS; numcoopstarts++)
|
||||
if (!playerstarts[numcoopstarts])
|
||||
|
|
@ -4128,6 +4206,8 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
memset(localaiming, 0, sizeof(localaiming));
|
||||
}
|
||||
|
||||
K_InitDirector();
|
||||
|
||||
wantedcalcdelay = wantedfrequency*2;
|
||||
indirectitemcooldown = 0;
|
||||
hyubgone = 0;
|
||||
|
|
@ -4227,7 +4307,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
return true;
|
||||
|
||||
// If so...
|
||||
G_PreLevelTitleCard();
|
||||
// but not if joining because the fade may time us out
|
||||
if (!fromnetsave)
|
||||
G_PreLevelTitleCard();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "doomdata.h"
|
||||
#include "doomstat.h"
|
||||
#include "r_defs.h"
|
||||
#include "k_terrain.h"
|
||||
|
||||
// map md5, sent to players via PT_SERVERINFO
|
||||
extern unsigned char mapmd5[16];
|
||||
|
|
@ -71,6 +72,8 @@ typedef struct
|
|||
|
||||
UINT16 width, height;
|
||||
|
||||
terrain_t *terrain;
|
||||
|
||||
// for flat animation
|
||||
INT32 animseq; // start pos. in the anim sequence
|
||||
INT32 numpics;
|
||||
|
|
|
|||
|
|
@ -850,6 +850,7 @@ void P_SlopeLaunch(mobj_t *mo)
|
|||
|
||||
//CONS_Printf("Launched off of slope.\n");
|
||||
mo->standingslope = NULL;
|
||||
mo->terrain = NULL;
|
||||
|
||||
if (mo->player)
|
||||
{
|
||||
|
|
|
|||
63
src/p_spec.c
63
src/p_spec.c
|
|
@ -43,6 +43,7 @@
|
|||
#include "k_kart.h"
|
||||
#include "console.h" // CON_LogMessage
|
||||
#include "k_respawn.h"
|
||||
#include "k_terrain.h"
|
||||
|
||||
#ifdef HW3SOUND
|
||||
#include "hardware/hw3sound.h"
|
||||
|
|
@ -51,7 +52,6 @@
|
|||
// Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog
|
||||
#include <errno.h>
|
||||
|
||||
mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint
|
||||
mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs
|
||||
mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs
|
||||
|
||||
|
|
@ -2089,6 +2089,19 @@ static mobj_t *P_GetObjectTypeInSectorNum(mobjtype_t type, size_t s)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void P_SwitchSkybox(INT32 ldflags, player_t *player, skybox_t *skybox)
|
||||
{
|
||||
if (!(ldflags & ML_EFFECT4)) // Solid Midtexture turns off viewpoint setting
|
||||
{
|
||||
player->skybox.viewpoint = skybox->viewpoint;
|
||||
}
|
||||
|
||||
if (ldflags & ML_BLOCKPLAYERS) // Block Enemies turns ON centerpoint setting
|
||||
{
|
||||
player->skybox.centerpoint = skybox->centerpoint;
|
||||
}
|
||||
}
|
||||
|
||||
/** Processes the line special triggered by an object.
|
||||
*
|
||||
* \param line Line with the special command on it.
|
||||
|
|
@ -3154,7 +3167,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
break;
|
||||
}
|
||||
case 448: // Change skybox viewpoint/centerpoint
|
||||
if ((mo && mo->player && P_IsLocalPlayer(mo->player)) || (line->flags & ML_NOCLIMB))
|
||||
if ((mo && mo->player) || (line->flags & ML_NOCLIMB))
|
||||
{
|
||||
INT32 viewid = sides[line->sidenum[0]].textureoffset>>FRACBITS;
|
||||
INT32 centerid = sides[line->sidenum[0]].rowoffset>>FRACBITS;
|
||||
|
|
@ -3167,23 +3180,32 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
}
|
||||
else
|
||||
{
|
||||
skybox_t skybox;
|
||||
|
||||
// set viewpoint mobj
|
||||
if (!(line->flags & ML_EFFECT4)) // Solid Midtexture turns off viewpoint setting
|
||||
{
|
||||
if (viewid >= 0 && viewid < 16)
|
||||
skyboxmo[0] = skyboxviewpnts[viewid];
|
||||
else
|
||||
skyboxmo[0] = NULL;
|
||||
}
|
||||
if (viewid >= 0 && viewid < 16)
|
||||
skybox.viewpoint = skyboxviewpnts[viewid];
|
||||
else
|
||||
skybox.viewpoint = NULL;
|
||||
|
||||
// set centerpoint mobj
|
||||
if (line->flags & ML_BLOCKPLAYERS) // Block Enemies turns ON centerpoint setting
|
||||
if (centerid >= 0 && centerid < 16)
|
||||
skybox.centerpoint = skyboxcenterpnts[centerid];
|
||||
else
|
||||
skybox.centerpoint = NULL;
|
||||
|
||||
if (line->flags & ML_NOCLIMB) // Applies to all players
|
||||
{
|
||||
if (centerid >= 0 && centerid < 16)
|
||||
skyboxmo[1] = skyboxcenterpnts[centerid];
|
||||
else
|
||||
skyboxmo[1] = NULL;
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (playeringame[i])
|
||||
P_SwitchSkybox(line->flags, &players[i], &skybox);
|
||||
}
|
||||
}
|
||||
else
|
||||
P_SwitchSkybox(line->flags, mo->player, &skybox);
|
||||
}
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 448 Executor: viewid = %d, centerid = %d, viewpoint? = %s, centerpoint? = %s\n",
|
||||
|
|
@ -3598,6 +3620,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
INT32 delay = (sides[line->sidenum[0]].rowoffset>>FRACBITS);
|
||||
if (mo && mo->player)
|
||||
{
|
||||
// Don't award rings while SPB is targetting you
|
||||
if (mo->player->pflags & PF_RINGLOCK)
|
||||
return;
|
||||
|
||||
if (delay <= 0 || !(leveltime % delay))
|
||||
P_GivePlayerRings(mo->player, rings);
|
||||
}
|
||||
|
|
@ -3633,7 +3659,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
if (mobj)
|
||||
{
|
||||
if (line->flags & ML_EFFECT1)
|
||||
mobj->angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y);
|
||||
P_InitAngle(mobj, R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y));
|
||||
CONS_Debug(DBG_GAMELOGIC, "Linedef Type %d - Spawn Object: %d spawned at (%d, %d, %d)\n", line->special, mobj->type, mobj->x>>FRACBITS, mobj->y>>FRACBITS, mobj->z>>FRACBITS); //TODO: Convert mobj->type to a string somehow.
|
||||
}
|
||||
else
|
||||
|
|
@ -3928,7 +3954,7 @@ void P_SetupSignExit(player_t *player)
|
|||
if (player->mo && !P_MobjWasRemoved(player->mo))
|
||||
{
|
||||
thing = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->floorz, MT_SIGN);
|
||||
thing->angle = player->mo->angle;
|
||||
P_InitAngle(thing, player->mo->angle);
|
||||
P_SetupSignObject(thing, player->mo, true); // Use :youfuckedup: sign face
|
||||
}
|
||||
}
|
||||
|
|
@ -4333,7 +4359,9 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
|
||||
// Conveyor stuff
|
||||
if (section3 == 2 || section3 == 4)
|
||||
{
|
||||
player->onconveyor = section3;
|
||||
}
|
||||
|
||||
special = section1;
|
||||
|
||||
|
|
@ -4657,7 +4685,7 @@ DoneSection2:
|
|||
case 6: // SRB2kart 190117 - Sneaker Panel
|
||||
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
|
||||
{
|
||||
if (!player->floorboost)
|
||||
if (player->floorboost == 0)
|
||||
player->floorboost = 3;
|
||||
else
|
||||
player->floorboost = 2;
|
||||
|
|
@ -5050,6 +5078,7 @@ void P_PlayerInSpecialSector(player_t *player)
|
|||
if (!player->mo)
|
||||
return;
|
||||
|
||||
K_ProcessTerrainEffect(player->mo);
|
||||
originalsector = player->mo->subsector->sector;
|
||||
|
||||
P_PlayerOnSpecial3DFloor(player, originalsector); // Handle FOFs first.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
#ifndef __P_SPEC__
|
||||
#define __P_SPEC__
|
||||
|
||||
extern mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint
|
||||
extern mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs
|
||||
extern mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
|
|||
P_FlashPal(thing->player, PAL_MIXUP, 10);
|
||||
}
|
||||
|
||||
thing->angle = angle;
|
||||
P_InitAngle(thing, angle);
|
||||
|
||||
thing->momx = thing->momy = thing->momz = 0;
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
|
|||
P_FlashPal(thing->player, PAL_MIXUP, 10);
|
||||
}
|
||||
|
||||
thing->angle = angle;
|
||||
P_InitAngle(thing, angle);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "k_race.h"
|
||||
#include "k_battle.h"
|
||||
#include "k_waypoint.h"
|
||||
#include "k_director.h"
|
||||
|
||||
tic_t leveltime;
|
||||
|
||||
|
|
@ -706,6 +707,8 @@ void P_Ticker(boolean run)
|
|||
}
|
||||
}
|
||||
|
||||
K_UpdateDirector();
|
||||
|
||||
// Always move the camera.
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
{
|
||||
|
|
|
|||
42
src/p_user.c
42
src/p_user.c
|
|
@ -52,6 +52,7 @@
|
|||
#include "k_respawn.h"
|
||||
#include "k_bot.h"
|
||||
#include "k_grandprix.h"
|
||||
#include "k_terrain.h" // K_SpawnSplashForMobj
|
||||
|
||||
#ifdef HW3SOUND
|
||||
#include "hardware/hw3sound.h"
|
||||
|
|
@ -379,7 +380,7 @@ void P_GiveFinishFlags(player_t *player)
|
|||
fixed_t xoffs = FINECOSINE(fa);
|
||||
fixed_t yoffs = FINESINE(fa);
|
||||
mobj_t* flag = P_SpawnMobjFromMobj(player->mo, xoffs, yoffs, 0, MT_FINISHFLAG);
|
||||
flag->angle = angle;
|
||||
P_InitAngle(flag, angle);
|
||||
angle += FixedAngle(120*FRACUNIT);
|
||||
|
||||
P_SetTarget(&flag->target, player->mo);
|
||||
|
|
@ -1274,17 +1275,18 @@ void P_DoPlayerExit(player_t *player)
|
|||
//
|
||||
// Handles player hitting floor surface.
|
||||
// Returns whether to clip momz.
|
||||
boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
||||
boolean P_PlayerHitFloor(player_t *player, boolean fromAir)
|
||||
{
|
||||
boolean clipmomz;
|
||||
|
||||
(void)dorollstuff;
|
||||
|
||||
I_Assert(player->mo != NULL);
|
||||
|
||||
clipmomz = !(P_CheckDeathPitCollide(player->mo));
|
||||
|
||||
// SRB2Kart: removed lots of really vanilla-specific code here
|
||||
if (fromAir == true && clipmomz == true)
|
||||
{
|
||||
K_SpawnSplashForMobj(player->mo, abs(player->mo->momz));
|
||||
}
|
||||
|
||||
return clipmomz;
|
||||
}
|
||||
|
|
@ -2138,8 +2140,6 @@ void P_MovePlayer(player_t *player)
|
|||
player->mo->rollangle = 0;
|
||||
}
|
||||
|
||||
player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame.
|
||||
|
||||
//{ SRB2kart
|
||||
|
||||
// Drifting sound
|
||||
|
|
@ -2176,7 +2176,7 @@ void P_MovePlayer(player_t *player)
|
|||
if (trailScale > 0)
|
||||
{
|
||||
const angle_t forwardangle = K_MomentumAngle(player->mo);
|
||||
const fixed_t playerVisualRadius = player->mo->radius + 8*FRACUNIT;
|
||||
const fixed_t playerVisualRadius = player->mo->radius + (8 * player->mo->scale);
|
||||
const size_t numFrames = S_WATERTRAIL8 - S_WATERTRAIL1;
|
||||
const statenum_t curOverlayFrame = S_WATERTRAIL1 + (leveltime % numFrames);
|
||||
const statenum_t curUnderlayFrame = S_WATERTRAILUNDERLAY1 + (leveltime % numFrames);
|
||||
|
|
@ -2197,7 +2197,7 @@ void P_MovePlayer(player_t *player)
|
|||
// underlay
|
||||
water = P_SpawnMobj(x1, y1,
|
||||
((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;
|
||||
P_InitAngle(water, forwardangle - ANGLE_180 - ANGLE_22h);
|
||||
water->destscale = trailScale;
|
||||
water->momx = player->mo->momx;
|
||||
water->momy = player->mo->momy;
|
||||
|
|
@ -2208,7 +2208,7 @@ void P_MovePlayer(player_t *player)
|
|||
// overlay
|
||||
water = P_SpawnMobj(x1, y1,
|
||||
((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;
|
||||
P_InitAngle(water, forwardangle - ANGLE_180 - ANGLE_22h);
|
||||
water->destscale = trailScale;
|
||||
water->momx = player->mo->momx;
|
||||
water->momy = player->mo->momy;
|
||||
|
|
@ -2220,7 +2220,7 @@ void P_MovePlayer(player_t *player)
|
|||
// Underlay
|
||||
water = P_SpawnMobj(x2, y2,
|
||||
((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;
|
||||
P_InitAngle(water, forwardangle - ANGLE_180 + ANGLE_22h);
|
||||
water->destscale = trailScale;
|
||||
water->momx = player->mo->momx;
|
||||
water->momy = player->mo->momy;
|
||||
|
|
@ -2231,7 +2231,7 @@ void P_MovePlayer(player_t *player)
|
|||
// Overlay
|
||||
water = P_SpawnMobj(x2, y2,
|
||||
((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;
|
||||
P_InitAngle(water, forwardangle - ANGLE_180 + ANGLE_22h);
|
||||
water->destscale = trailScale;
|
||||
water->momx = player->mo->momx;
|
||||
water->momy = player->mo->momy;
|
||||
|
|
@ -2267,7 +2267,7 @@ void P_MovePlayer(player_t *player)
|
|||
K_SpawnSparkleTrail(player->mo);
|
||||
|
||||
if (player->wipeoutslow > 1 && (leveltime & 1))
|
||||
K_SpawnWipeoutTrail(player->mo, false);
|
||||
K_SpawnWipeoutTrail(player->mo);
|
||||
|
||||
K_DriftDustHandling(player->mo);
|
||||
|
||||
|
|
@ -2464,8 +2464,10 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
|
|||
indirectitemcooldown = 0;
|
||||
}
|
||||
|
||||
if (mo->flags & MF_BOSS || mo->type == MT_PLAYER) //don't OHKO bosses nor players!
|
||||
if (mo->flags & MF_BOSS) //don't OHKO bosses nor players!
|
||||
P_DamageMobj(mo, inflictor, source, 1, DMG_NORMAL|DMG_CANTHURTSELF);
|
||||
else if (mo->type == MT_PLAYER) // Thunder shield: Combo players.
|
||||
P_DamageMobj(mo, inflictor, source, 1, DMG_NORMAL|DMG_CANTHURTSELF|DMG_WOMBO);
|
||||
else
|
||||
P_DamageMobj(mo, inflictor, source, 1000, DMG_NORMAL|DMG_CANTHURTSELF);
|
||||
}
|
||||
|
|
@ -3989,7 +3991,7 @@ static void P_HandleFollower(player_t *player)
|
|||
P_SetTarget(&player->follower, P_SpawnMobj(sx, sy, sz, MT_FOLLOWER));
|
||||
P_SetFollowerState(player->follower, fl.idlestate);
|
||||
P_SetTarget(&player->follower->target, player->mo); // we need that to know when we need to disappear
|
||||
player->follower->angle = player->mo->angle;
|
||||
P_InitAngle(player->follower, player->mo->angle);
|
||||
|
||||
// This is safe to only spawn it here, the follower is removed then respawned when switched.
|
||||
if (bubble)
|
||||
|
|
@ -4052,10 +4054,8 @@ static void P_HandleFollower(player_t *player)
|
|||
if (player->pflags & PF_NOCONTEST)
|
||||
player->follower->renderflags |= RF_DONTDRAW;
|
||||
|
||||
if (player->speed && (player->follower->momx || player->follower->momy))
|
||||
player->follower->angle = K_MomentumAngle(player->follower);
|
||||
// if we're moving let's make the angle the direction we're moving towards. This is to avoid drifting / reverse looking awkward.
|
||||
// Make sure the follower itself is also moving however, otherwise we'll be facing angle 0
|
||||
// if we're moving let's make the angle the direction we're moving towards. This is to avoid drifting / reverse looking awkward.
|
||||
player->follower->angle = K_MomentumAngle(player->follower);
|
||||
|
||||
// Finally, if the follower has bubbles, move them, set their scale, etc....
|
||||
// This is what I meant earlier by it being easier, now we can just use this weird lil loop to get the job done!
|
||||
|
|
@ -4504,8 +4504,6 @@ void P_PlayerThink(player_t *player)
|
|||
P_MovePlayer(player);
|
||||
}
|
||||
|
||||
player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame.
|
||||
|
||||
// Unset statis flag after moving.
|
||||
// In other words, if you manually set stasis via code,
|
||||
// it lasts for one tic.
|
||||
|
|
@ -4557,7 +4555,7 @@ void P_PlayerThink(player_t *player)
|
|||
|| (player->pflags & PF_NOCONTEST) // NO CONTEST explosion
|
||||
|| ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0 && player->karmadelay)))
|
||||
{
|
||||
if (player->flashing > 0 && player->flashing < K_GetKartFlashing(player)
|
||||
if (player->flashing > 1 && player->flashing < K_GetKartFlashing(player)
|
||||
&& (leveltime & 1))
|
||||
player->mo->renderflags |= RF_DONTDRAW;
|
||||
else
|
||||
|
|
|
|||
32
src/r_bsp.c
32
src/r_bsp.c
|
|
@ -23,6 +23,8 @@
|
|||
#include "z_zone.h" // Check R_Prep3DFloors
|
||||
#include "taglist.h"
|
||||
|
||||
#include "k_terrain.h"
|
||||
|
||||
seg_t *curline;
|
||||
side_t *sidedef;
|
||||
line_t *linedef;
|
||||
|
|
@ -67,11 +69,35 @@ boolean R_IsRipplePlane(sector_t *sector, ffloor_t *rover, int ceiling)
|
|||
|
||||
static void R_PlaneLightOverride(sector_t *sector, boolean ceiling, INT32 *lightlevel)
|
||||
{
|
||||
if (GETSECSPECIAL(sector->special, 4) == 6) // Fullbright sneaker panels
|
||||
terrain_t *t = NULL;
|
||||
|
||||
if (ceiling == true)
|
||||
{
|
||||
if ((ceiling && (sector->flags & SF_FLIPSPECIAL_CEILING))
|
||||
|| (!ceiling && (sector->flags & SF_FLIPSPECIAL_FLOOR)))
|
||||
t = K_GetTerrainForFlatNum(sector->ceilingpic);
|
||||
}
|
||||
else
|
||||
{
|
||||
t = K_GetTerrainForFlatNum(sector->floorpic);
|
||||
}
|
||||
|
||||
if (t != NULL)
|
||||
{
|
||||
if (t->flags & TRF_SNEAKERPANEL)
|
||||
{
|
||||
*lightlevel = 255;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sector effect sneaker panels (DEPRECATED)
|
||||
if (GETSECSPECIAL(sector->special, 4) == 6)
|
||||
{
|
||||
if ((ceiling && (sector->flags & SF_FLIPSPECIAL_CEILING))
|
||||
|| (!ceiling && (sector->flags & SF_FLIPSPECIAL_FLOOR)))
|
||||
{
|
||||
*lightlevel = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ void R_DrawViewBorder(void);
|
|||
void R_DrawColumn_8(void);
|
||||
void R_DrawShadeColumn_8(void);
|
||||
void R_DrawTranslucentColumn_8(void);
|
||||
void R_DrawDropShadowColumn_8(void);
|
||||
void R_DrawTranslatedColumn_8(void);
|
||||
void R_DrawTranslatedTranslucentColumn_8(void);
|
||||
void R_Draw2sMultiPatchColumn_8(void);
|
||||
|
|
|
|||
|
|
@ -566,6 +566,39 @@ void R_DrawTranslucentColumn_8(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Hack: A cut-down copy of R_DrawTranslucentColumn_8 that does not read texture
|
||||
// data since something about calculating the texture reading address for drop shadows is broken.
|
||||
// dc_texturemid and dc_iscale get wrong values for drop shadows, however those are not strictly
|
||||
// needed for the current design of the shadows, so this function bypasses the issue
|
||||
// by not using those variables at all.
|
||||
void R_DrawDropShadowColumn_8(void)
|
||||
{
|
||||
register INT32 count;
|
||||
register UINT8 *dest;
|
||||
|
||||
count = dc_yh - dc_yl + 1;
|
||||
|
||||
if (count <= 0) // Zero length, column does not exceed a pixel.
|
||||
return;
|
||||
|
||||
dest = &topleft[dc_yl*vid.width + dc_x];
|
||||
|
||||
{
|
||||
#define DSCOLOR 15 // palette index for the color of the shadow
|
||||
register const UINT8 *transmap_offset = dc_transmap + (dc_colormap[DSCOLOR] << 8);
|
||||
#undef DSCOLOR
|
||||
while ((count -= 2) >= 0)
|
||||
{
|
||||
*dest = *(transmap_offset + (*dest));
|
||||
dest += vid.width;
|
||||
*dest = *(transmap_offset + (*dest));
|
||||
dest += vid.width;
|
||||
}
|
||||
if (count & 1)
|
||||
*dest = *(transmap_offset + (*dest));
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief The R_DrawTranslatedTranslucentColumn_8 function
|
||||
Spiffy function. Not only does it colormap a sprite, but does translucency as well.
|
||||
Uber-kudos to Cyan Helkaraxe
|
||||
|
|
|
|||
30
src/r_fps.c
30
src/r_fps.c
|
|
@ -32,7 +32,6 @@ 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)
|
||||
|
|
@ -81,12 +80,19 @@ static void R_SetupFreelook(player_t *player, boolean skybox)
|
|||
|
||||
#undef AIMINGTODY
|
||||
|
||||
void R_InterpolateViewRollAngle(fixed_t frac)
|
||||
{
|
||||
viewroll = oldview->roll + R_LerpAngle(oldview->roll, newview->roll, frac);
|
||||
}
|
||||
|
||||
void R_InterpolateView(fixed_t frac)
|
||||
{
|
||||
if (frac < 0)
|
||||
frac = 0;
|
||||
#if 0
|
||||
if (frac > FRACUNIT)
|
||||
frac = FRACUNIT;
|
||||
#endif
|
||||
|
||||
viewx = oldview->x + R_LerpFixed(oldview->x, newview->x, frac);
|
||||
viewy = oldview->y + R_LerpFixed(oldview->y, newview->y, frac);
|
||||
|
|
@ -94,7 +100,7 @@ void R_InterpolateView(fixed_t frac)
|
|||
|
||||
viewangle = oldview->angle + R_LerpAngle(oldview->angle, newview->angle, frac);
|
||||
aimingangle = oldview->aim + R_LerpAngle(oldview->aim, newview->aim, frac);
|
||||
viewroll = oldview->roll + R_LerpAngle(oldview->roll, newview->roll, frac);
|
||||
R_InterpolateViewRollAngle(frac);
|
||||
|
||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
|
|
@ -147,3 +153,23 @@ void R_SetViewContext(enum viewcontext_e _viewcontext)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fixed_t R_InterpolateFixed(fixed_t from, fixed_t to)
|
||||
{
|
||||
if (cv_frameinterpolation.value == 0)
|
||||
{
|
||||
return to;
|
||||
}
|
||||
|
||||
return (from + R_LerpFixed(from, to, rendertimefrac));
|
||||
}
|
||||
|
||||
angle_t R_InterpolateAngle(angle_t from, angle_t to)
|
||||
{
|
||||
if (cv_frameinterpolation.value == 0)
|
||||
{
|
||||
return to;
|
||||
}
|
||||
|
||||
return (from + R_LerpAngle(from, to, rendertimefrac));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,9 +51,14 @@ 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);
|
||||
// Special function just for software
|
||||
void R_InterpolateViewRollAngle(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);
|
||||
|
||||
fixed_t R_InterpolateFixed(fixed_t from, fixed_t to);
|
||||
angle_t R_InterpolateAngle(angle_t from, angle_t to);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
19
src/r_main.c
19
src/r_main.c
|
|
@ -28,7 +28,7 @@
|
|||
#include "am_map.h"
|
||||
#include "d_main.h"
|
||||
#include "v_video.h"
|
||||
#include "p_spec.h" // skyboxmo
|
||||
//#include "p_spec.h"
|
||||
#include "p_setup.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_random.h" // quake camera shake
|
||||
|
|
@ -1331,7 +1331,7 @@ void R_SkyboxFrame(player_t *player)
|
|||
|
||||
// cut-away view stuff
|
||||
newview->sky = true;
|
||||
r_viewmobj = skyboxmo[0];
|
||||
r_viewmobj = player->skybox.viewpoint;
|
||||
#ifdef PARANOIA
|
||||
if (!r_viewmobj)
|
||||
{
|
||||
|
|
@ -1372,6 +1372,7 @@ void R_SkyboxFrame(player_t *player)
|
|||
{
|
||||
mapheader_t *mh = mapheaderinfo[gamemap-1];
|
||||
vector3_t campos = {0,0,0}; // Position of player's actual view point
|
||||
mobj_t *center = player->skybox.centerpoint;
|
||||
|
||||
if (player->awayviewtics) {
|
||||
campos.x = player->awayviewmobj->x;
|
||||
|
|
@ -1393,18 +1394,18 @@ void R_SkyboxFrame(player_t *player)
|
|||
campos.y += quake.y;
|
||||
campos.z += quake.z;
|
||||
|
||||
if (skyboxmo[1]) // Is there a viewpoint?
|
||||
if (center) // Is there a viewpoint?
|
||||
{
|
||||
fixed_t x = 0, y = 0;
|
||||
if (mh->skybox_scalex > 0)
|
||||
x = (campos.x - skyboxmo[1]->x) / mh->skybox_scalex;
|
||||
x = (campos.x - center->x) / mh->skybox_scalex;
|
||||
else if (mh->skybox_scalex < 0)
|
||||
x = (campos.x - skyboxmo[1]->x) * -mh->skybox_scalex;
|
||||
x = (campos.x - center->x) * -mh->skybox_scalex;
|
||||
|
||||
if (mh->skybox_scaley > 0)
|
||||
y = (campos.y - skyboxmo[1]->y) / mh->skybox_scaley;
|
||||
y = (campos.y - center->y) / mh->skybox_scaley;
|
||||
else if (mh->skybox_scaley < 0)
|
||||
y = (campos.y - skyboxmo[1]->y) * -mh->skybox_scaley;
|
||||
y = (campos.y - center->y) * -mh->skybox_scaley;
|
||||
|
||||
if (r_viewmobj->angle == 0)
|
||||
{
|
||||
|
|
@ -1617,8 +1618,8 @@ void R_RenderPlayerView(void)
|
|||
|
||||
|
||||
// Add skybox portals caused by sky visplanes.
|
||||
if (cv_skybox.value && skyboxmo[0])
|
||||
Portal_AddSkyboxPortals();
|
||||
if (cv_skybox.value && player->skybox.viewpoint)
|
||||
Portal_AddSkyboxPortals(player);
|
||||
|
||||
// Portal rendering. Hijacks the BSP traversal.
|
||||
ps_sw_portaltime = I_GetPreciseTime();
|
||||
|
|
|
|||
|
|
@ -127,6 +127,4 @@ typedef struct planemgr_s
|
|||
|
||||
extern visffloor_t ffloor[MAXFFLOORS];
|
||||
extern INT32 numffloors;
|
||||
|
||||
void Portal_AddSkyboxPortals (void);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -256,12 +256,17 @@ static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16*
|
|||
* Applies the necessary offsets and rotation to give
|
||||
* a depth illusion to the skybox.
|
||||
*/
|
||||
void Portal_AddSkybox (const visplane_t* plane)
|
||||
void Portal_AddSkybox
|
||||
( const player_t * player,
|
||||
const visplane_t * plane)
|
||||
{
|
||||
INT16 start, end;
|
||||
mapheader_t *mh;
|
||||
portal_t* portal;
|
||||
|
||||
mobj_t *viewpoint = player->skybox.viewpoint;
|
||||
mobj_t *center = player->skybox.centerpoint;
|
||||
|
||||
if (TrimVisplaneBounds(plane, &start, &end))
|
||||
return;
|
||||
|
||||
|
|
@ -269,28 +274,28 @@ void Portal_AddSkybox (const visplane_t* plane)
|
|||
|
||||
Portal_ClipVisplane(plane, portal);
|
||||
|
||||
portal->viewx = skyboxmo[0]->x;
|
||||
portal->viewy = skyboxmo[0]->y;
|
||||
portal->viewz = skyboxmo[0]->z;
|
||||
portal->viewangle = viewangle + skyboxmo[0]->angle;
|
||||
portal->viewx = viewpoint->x;
|
||||
portal->viewy = viewpoint->y;
|
||||
portal->viewz = viewpoint->z;
|
||||
portal->viewangle = viewangle + viewpoint->angle;
|
||||
|
||||
mh = mapheaderinfo[gamemap-1];
|
||||
|
||||
// If a relative viewpoint exists, offset the viewpoint.
|
||||
if (skyboxmo[1])
|
||||
if (center)
|
||||
{
|
||||
fixed_t x = 0, y = 0;
|
||||
angle_t ang = skyboxmo[0]->angle>>ANGLETOFINESHIFT;
|
||||
angle_t ang = viewpoint->angle>>ANGLETOFINESHIFT;
|
||||
|
||||
if (mh->skybox_scalex > 0)
|
||||
x = (viewx - skyboxmo[1]->x) / mh->skybox_scalex;
|
||||
x = (viewx - center->x) / mh->skybox_scalex;
|
||||
else if (mh->skybox_scalex < 0)
|
||||
x = (viewx - skyboxmo[1]->x) * -mh->skybox_scalex;
|
||||
x = (viewx - center->x) * -mh->skybox_scalex;
|
||||
|
||||
if (mh->skybox_scaley > 0)
|
||||
y = (viewy - skyboxmo[1]->y) / mh->skybox_scaley;
|
||||
y = (viewy - center->y) / mh->skybox_scaley;
|
||||
else if (mh->skybox_scaley < 0)
|
||||
y = (viewy - skyboxmo[1]->y) * -mh->skybox_scaley;
|
||||
y = (viewy - center->y) * -mh->skybox_scaley;
|
||||
|
||||
// Apply transform to account for the skybox viewport angle.
|
||||
portal->viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||
|
|
@ -308,7 +313,7 @@ void Portal_AddSkybox (const visplane_t* plane)
|
|||
/** Creates portals for the currently existing sky visplanes.
|
||||
* The visplanes are also removed and cleared from the list.
|
||||
*/
|
||||
void Portal_AddSkyboxPortals (void)
|
||||
void Portal_AddSkyboxPortals (const player_t *player)
|
||||
{
|
||||
visplane_t *pl;
|
||||
INT32 i;
|
||||
|
|
@ -320,7 +325,7 @@ void Portal_AddSkyboxPortals (void)
|
|||
{
|
||||
if (pl->picnum == skyflatnum)
|
||||
{
|
||||
Portal_AddSkybox(pl);
|
||||
Portal_AddSkybox(player, pl);
|
||||
|
||||
pl->minx = 0;
|
||||
pl->maxx = -1;
|
||||
|
|
|
|||
|
|
@ -52,10 +52,10 @@ extern INT32 portalclipstart, portalclipend;
|
|||
void Portal_InitList (void);
|
||||
void Portal_Remove (portal_t* portal);
|
||||
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2);
|
||||
void Portal_AddSkybox (const visplane_t* plane);
|
||||
void Portal_AddSkybox (const player_t* player, const visplane_t* plane);
|
||||
|
||||
void Portal_ClipRange (portal_t* portal);
|
||||
void Portal_ClipApply (const portal_t* portal);
|
||||
|
||||
void Portal_AddSkyboxPortals (void);
|
||||
void Portal_AddSkyboxPortals (const player_t* player);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ INT32 *texturebrightmaps;
|
|||
// Painfully simple texture id cacheing to make maps load faster. :3
|
||||
static struct {
|
||||
char name[9];
|
||||
UINT32 hash;
|
||||
INT32 id;
|
||||
} *tidcache = NULL;
|
||||
static INT32 tidcachelen = 0;
|
||||
|
|
@ -803,6 +804,7 @@ Rloadflats (INT32 i, INT32 w)
|
|||
|
||||
// Set texture properties.
|
||||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
texture->hash = quickncasehash(texture->name, 8);
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG(header, lumplength))
|
||||
|
|
@ -901,6 +903,7 @@ Rloadtextures (INT32 i, INT32 w)
|
|||
|
||||
// Set texture properties.
|
||||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
texture->hash = quickncasehash(texture->name, 8);
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)&patchlump, lumplength))
|
||||
|
|
@ -1389,6 +1392,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture)
|
|||
// Allocate memory for a zero-patch texture. Obviously, we'll be adding patches momentarily.
|
||||
resultTexture = (texture_t *)Z_Calloc(sizeof(texture_t),PU_STATIC,NULL);
|
||||
M_Memcpy(resultTexture->name, newTextureName, 8);
|
||||
resultTexture->hash = quickncasehash(newTextureName, 8);
|
||||
resultTexture->width = newTextureWidth;
|
||||
resultTexture->height = newTextureHeight;
|
||||
resultTexture->type = TEXTURETYPE_COMPOSITE;
|
||||
|
|
@ -1614,25 +1618,29 @@ void R_ClearTextureNumCache(boolean btell)
|
|||
INT32 R_CheckTextureNumForName(const char *name)
|
||||
{
|
||||
INT32 i;
|
||||
UINT32 hash;
|
||||
|
||||
// "NoTexture" marker.
|
||||
if (name[0] == '-')
|
||||
return 0;
|
||||
|
||||
hash = quickncasehash(name, 8);
|
||||
|
||||
for (i = 0; i < tidcachelen; i++)
|
||||
if (!strncasecmp(tidcache[i].name, name, 8))
|
||||
if (tidcache[i].hash == hash && !strncasecmp(tidcache[i].name, name, 8))
|
||||
return tidcache[i].id;
|
||||
|
||||
// Need to parse the list backwards, so textures loaded more recently are used in lieu of ones loaded earlier
|
||||
//for (i = 0; i < numtextures; i++) <- old
|
||||
for (i = (numtextures - 1); i >= 0; i--) // <- new
|
||||
if (!strncasecmp(textures[i]->name, name, 8))
|
||||
if (textures[i]->hash == hash && !strncasecmp(textures[i]->name, name, 8))
|
||||
{
|
||||
tidcachelen++;
|
||||
Z_Realloc(tidcache, tidcachelen * sizeof(*tidcache), PU_STATIC, &tidcache);
|
||||
strncpy(tidcache[tidcachelen-1].name, name, 8);
|
||||
tidcache[tidcachelen-1].name[8] = '\0';
|
||||
CONS_Debug(DBG_SETUP, "texture #%s: %s\n", sizeu1(tidcachelen), tidcache[tidcachelen-1].name);
|
||||
tidcache[tidcachelen-1].hash = hash;
|
||||
tidcache[tidcachelen-1].id = i;
|
||||
return i;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ typedef struct
|
|||
{
|
||||
// Keep name for switch changing, etc.
|
||||
char name[8];
|
||||
UINT32 hash;
|
||||
UINT8 type; // TEXTURETYPE_
|
||||
INT16 width, height;
|
||||
boolean holes;
|
||||
|
|
|
|||
139
src/r_things.c
139
src/r_things.c
|
|
@ -46,6 +46,7 @@
|
|||
// SRB2kart
|
||||
#include "k_color.h"
|
||||
#include "k_kart.h" // HITLAGJITTERS
|
||||
#include "r_fps.h"
|
||||
|
||||
#define MINZ (FRACUNIT*4)
|
||||
#define BASEYCENTER (BASEVIDHEIGHT/2)
|
||||
|
|
@ -284,14 +285,13 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
|
|||
// store sprite info in lookup tables
|
||||
//FIXME : numspritelumps do not duplicate sprite replacements
|
||||
|
||||
W_ReadLumpHeaderPwad(wadnum, l, &patch, PNG_HEADER_SIZE, 0);
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
{
|
||||
UINT8 header[PNG_HEADER_SIZE];
|
||||
size_t len = W_LumpLengthPwad(wadnum, l);
|
||||
|
||||
W_ReadLumpHeaderPwad(wadnum, l, header, sizeof header, 0);
|
||||
|
||||
if (Picture_IsLumpPNG(header, len))
|
||||
if (Picture_IsLumpPNG((UINT8*)&patch, len))
|
||||
{
|
||||
UINT8 *png = W_CacheLumpNumPwad(wadnum, l, PU_STATIC);
|
||||
Picture_PNGDimensions((UINT8 *)png, &width, &height, &topoffset, &leftoffset, len);
|
||||
|
|
@ -303,7 +303,6 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
|
|||
if (!isPNG)
|
||||
#endif
|
||||
{
|
||||
W_ReadLumpHeaderPwad(wadnum, l, &patch, sizeof(INT16) * 4, 0);
|
||||
width = (INT32)(SHORT(patch.width));
|
||||
height = (INT32)(SHORT(patch.height));
|
||||
topoffset = (INT16)(SHORT(patch.topoffset));
|
||||
|
|
@ -837,7 +836,15 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
dc_fullbright = colormaps;
|
||||
dc_translation = R_GetSpriteTranslation(vis);
|
||||
|
||||
if (R_SpriteIsFlashing(vis)) // Bosses "flash"
|
||||
// Hack: Use a special column function for drop shadows that bypasses
|
||||
// invalid memory access crashes caused by R_ProjectDropShadow putting wrong values
|
||||
// in dc_texturemid and dc_iscale when the shadow is sloped.
|
||||
if (vis->cut & SC_SHADOW)
|
||||
{
|
||||
R_SetColumnFunc(COLDRAWFUNC_DROPSHADOW, false);
|
||||
dc_transmap = vis->transmap;
|
||||
}
|
||||
else if (R_SpriteIsFlashing(vis)) // Bosses "flash"
|
||||
R_SetColumnFunc(COLDRAWFUNC_TRANS, false); // translate certain pixels to white
|
||||
else if (vis->mobj->color && vis->transmap) // Color mapping
|
||||
{
|
||||
|
|
@ -854,7 +861,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome.
|
||||
R_SetColumnFunc(COLDRAWFUNC_TRANS, false);
|
||||
|
||||
if (vis->extra_colormap && !(vis->renderflags & RF_NOCOLORMAPS))
|
||||
if (vis->extra_colormap && !(vis->cut & SC_FULLBRIGHT) && !(vis->renderflags & RF_NOCOLORMAPS))
|
||||
{
|
||||
if (!dc_colormap)
|
||||
dc_colormap = vis->extra_colormap->colormap;
|
||||
|
|
@ -1149,15 +1156,21 @@ static void R_SplitSprite(vissprite_t *sprite)
|
|||
// Get the first visible floor below the object for shadows
|
||||
// shadowslope is filled with the floor's slope, if provided
|
||||
//
|
||||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
||||
fixed_t R_GetShadowZ(
|
||||
mobj_t *thing, pslope_t **shadowslope,
|
||||
fixed_t interpx, fixed_t interpy, fixed_t interpz)
|
||||
{
|
||||
fixed_t halfHeight = interpz + (thing->height >> 1);
|
||||
boolean isflipped = thing->eflags & MFE_VERTICALFLIP;
|
||||
fixed_t floorz = P_GetFloorZ(thing, thing->subsector->sector, interpx, interpy, NULL);
|
||||
fixed_t ceilingz = P_GetCeilingZ(thing, thing->subsector->sector, interpx, interpy, NULL);
|
||||
fixed_t z, groundz = isflipped ? INT32_MAX : INT32_MIN;
|
||||
pslope_t *slope, *groundslope = NULL;
|
||||
msecnode_t *node;
|
||||
sector_t *sector;
|
||||
ffloor_t *rover;
|
||||
#define CHECKZ (isflipped ? z > thing->z+thing->height/2 && z < groundz : z < thing->z+thing->height/2 && z > groundz)
|
||||
|
||||
#define CHECKZ (isflipped ? z > halfHeight && z < groundz : z < halfHeight && z > groundz)
|
||||
|
||||
for (node = thing->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
|
|
@ -1168,7 +1181,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
|||
if (sector->heightsec != -1)
|
||||
z = isflipped ? sectors[sector->heightsec].ceilingheight : sectors[sector->heightsec].floorheight;
|
||||
else
|
||||
z = isflipped ? P_GetSectorCeilingZAt(sector, thing->x, thing->y) : P_GetSectorFloorZAt(sector, thing->x, thing->y);
|
||||
z = isflipped ? P_GetSectorCeilingZAt(sector, interpx, interpy) : P_GetSectorFloorZAt(sector, interpx, interpy);
|
||||
|
||||
if CHECKZ
|
||||
{
|
||||
|
|
@ -1182,7 +1195,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
|||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE)))
|
||||
continue;
|
||||
|
||||
z = isflipped ? P_GetFFloorBottomZAt(rover, thing->x, thing->y) : P_GetFFloorTopZAt(rover, thing->x, thing->y);
|
||||
z = isflipped ? P_GetFFloorBottomZAt(rover, interpx, interpy) : P_GetFFloorTopZAt(rover, interpx, interpy);
|
||||
|
||||
if CHECKZ
|
||||
{
|
||||
|
|
@ -1192,10 +1205,10 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
|||
}
|
||||
}
|
||||
|
||||
if (isflipped ? (thing->ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2)))
|
||||
: (thing->floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2))))
|
||||
if (isflipped ? (ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2)))
|
||||
: (floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2))))
|
||||
{
|
||||
groundz = isflipped ? thing->ceilingz : thing->floorz;
|
||||
groundz = isflipped ? ceilingz : floorz;
|
||||
groundslope = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1206,10 +1219,10 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
|||
{
|
||||
INT32 xl, xh, yl, yh, bx, by;
|
||||
|
||||
xl = (unsigned)(thing->x - thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (unsigned)(thing->x + thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (unsigned)(thing->y - thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (unsigned)(thing->y + thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
xl = (unsigned)(interpx - thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (unsigned)(interpx + thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (unsigned)(interpy - thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (unsigned)(interpy + thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
|
||||
BMBOUNDFIX(xl, xh, yl, yh);
|
||||
|
||||
|
|
@ -1246,7 +1259,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
|||
// We're inside it! Yess...
|
||||
z = po->lines[0]->backsector->ceilingheight;
|
||||
|
||||
if (z < thing->z+thing->height/2 && z > groundz)
|
||||
if (z < halfHeight && z > groundz)
|
||||
{
|
||||
groundz = z;
|
||||
groundslope = NULL;
|
||||
|
|
@ -1269,11 +1282,12 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
|||
static void R_SkewShadowSprite(
|
||||
mobj_t *thing, pslope_t *groundslope,
|
||||
fixed_t groundz, INT32 spriteheight, fixed_t scalemul,
|
||||
fixed_t *shadowyscale, fixed_t *shadowskew)
|
||||
fixed_t *shadowyscale, fixed_t *shadowskew,
|
||||
fixed_t interpx, fixed_t interpy)
|
||||
{
|
||||
// haha let's try some dumb stuff
|
||||
fixed_t xslope, zslope;
|
||||
angle_t sloperelang = (R_PointToAngle(thing->x, thing->y) - groundslope->xydirection) >> ANGLETOFINESHIFT;
|
||||
angle_t sloperelang = (R_PointToAngle(interpx, interpy) - groundslope->xydirection) >> ANGLETOFINESHIFT;
|
||||
|
||||
xslope = FixedMul(FINESINE(sloperelang), groundslope->zdelta);
|
||||
zslope = FixedMul(FINECOSINE(sloperelang), groundslope->zdelta);
|
||||
|
|
@ -1289,7 +1303,10 @@ static void R_SkewShadowSprite(
|
|||
*shadowskew = xslope;
|
||||
}
|
||||
|
||||
static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz)
|
||||
static void R_ProjectDropShadow(
|
||||
mobj_t *thing, vissprite_t *vis,
|
||||
fixed_t scale, fixed_t tx, fixed_t tz,
|
||||
fixed_t interpx, fixed_t interpy, fixed_t interpz)
|
||||
{
|
||||
vissprite_t *shadow;
|
||||
patch_t *patch;
|
||||
|
|
@ -1298,7 +1315,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
fixed_t groundz;
|
||||
pslope_t *groundslope;
|
||||
|
||||
groundz = R_GetShadowZ(thing, &groundslope);
|
||||
groundz = R_GetShadowZ(thing, &groundslope, interpx, interpy, interpz);
|
||||
|
||||
if (abs(groundz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes
|
||||
|
||||
|
|
@ -1312,7 +1329,14 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
shadowskew = 0;
|
||||
|
||||
if (groundslope)
|
||||
R_SkewShadowSprite(thing, groundslope, groundz, patch->height, FRACUNIT, &shadowyscale, &shadowskew);
|
||||
{
|
||||
R_SkewShadowSprite(
|
||||
thing,
|
||||
groundslope, groundz,
|
||||
patch->height, FRACUNIT,
|
||||
&shadowyscale, &shadowskew,
|
||||
interpx, interpy);
|
||||
}
|
||||
|
||||
tx -= patch->width * shadowxscale/2;
|
||||
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
||||
|
|
@ -1331,8 +1355,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
shadow->mobjflags = 0;
|
||||
shadow->sortscale = vis->sortscale;
|
||||
shadow->dispoffset = vis->dispoffset - 5;
|
||||
shadow->gx = thing->x;
|
||||
shadow->gy = thing->y;
|
||||
shadow->gx = interpx;
|
||||
shadow->gy = interpy;
|
||||
shadow->gzt = groundz + patch->height * shadowyscale / 2;
|
||||
shadow->gz = shadow->gzt - patch->height * shadowyscale;
|
||||
shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale));
|
||||
|
|
@ -1470,26 +1494,18 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
#endif
|
||||
|
||||
// uncapped/interpolation
|
||||
fixed_t interpx = thing->x;
|
||||
fixed_t interpy = thing->y;
|
||||
fixed_t interpz = thing->z;
|
||||
angle_t interpangle = (thing->player ? thing->player->drawangle : thing->angle);
|
||||
fixed_t interpx = R_InterpolateFixed(thing->old_x, thing->x);
|
||||
fixed_t interpy = R_InterpolateFixed(thing->old_y, thing->y);
|
||||
fixed_t interpz = R_InterpolateFixed(thing->old_z, thing->z);
|
||||
angle_t interpangle = ANGLE_MAX;
|
||||
|
||||
// do interpolation
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
if (thing->player)
|
||||
{
|
||||
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->old_drawangle + FixedMul(rendertimefrac, thing->player->drawangle - thing->player->old_drawangle);
|
||||
}
|
||||
else
|
||||
{
|
||||
interpangle = thing->old_angle + FixedMul(rendertimefrac, thing->angle - thing->old_angle);
|
||||
}
|
||||
interpangle = R_InterpolateAngle(thing->player->old_drawangle, thing->player->drawangle);
|
||||
}
|
||||
else
|
||||
{
|
||||
interpangle = R_InterpolateAngle(thing->old_angle, thing->angle);
|
||||
}
|
||||
|
||||
// hitlag vibrating (todo: interp somehow?)
|
||||
|
|
@ -1817,11 +1833,10 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
fixed_t linkscale;
|
||||
|
||||
thing = thing->tracer;
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
interpx = thing->old_x + FixedMul(thing->x - thing->old_x, rendertimefrac);
|
||||
interpy = thing->old_y + FixedMul(thing->y - thing->old_y, rendertimefrac);
|
||||
}
|
||||
|
||||
interpx = R_InterpolateFixed(thing->old_x, thing->x);
|
||||
interpy = R_InterpolateFixed(thing->old_y, thing->y);
|
||||
interpz = R_InterpolateFixed(thing->old_z, thing->z);
|
||||
|
||||
// hitlag vibrating (todo: interp somehow?)
|
||||
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
|
||||
|
|
@ -1911,7 +1926,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (shadowdraw || shadoweffects)
|
||||
{
|
||||
fixed_t groundz = R_GetShadowZ(thing, NULL);
|
||||
fixed_t groundz = R_GetShadowZ(thing, NULL, interpx, interpy, interpz);
|
||||
boolean isflipped = (thing->eflags & MFE_VERTICALFLIP);
|
||||
|
||||
if (shadoweffects)
|
||||
|
|
@ -1935,7 +1950,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (shadowskew)
|
||||
{
|
||||
R_SkewShadowSprite(thing, thing->standingslope, groundz, patch->height, shadowscale, &spriteyscale, &sheartan);
|
||||
R_SkewShadowSprite(thing, thing->standingslope, groundz, patch->height, shadowscale, &spriteyscale, &sheartan, interpx, interpy);
|
||||
|
||||
gzt = (isflipped ? (thing->z + thing->height) : thing->z) + patch->height * spriteyscale / 2;
|
||||
gz = gzt - patch->height * spriteyscale;
|
||||
|
|
@ -2100,8 +2115,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
//
|
||||
// determine the colormap (lightlevel & special effects)
|
||||
//
|
||||
if (vis->cut & SC_FULLBRIGHT
|
||||
&& (!vis->extra_colormap || !(vis->extra_colormap->flags & CMF_FADEFULLBRIGHTSPRITES)))
|
||||
if (vis->cut & SC_FULLBRIGHT)
|
||||
{
|
||||
// full bright: goggles
|
||||
vis->colormap = colormaps;
|
||||
|
|
@ -2135,7 +2149,10 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
R_SplitSprite(vis);
|
||||
|
||||
if (oldthing->shadowscale && cv_shadow.value)
|
||||
R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, basetz);
|
||||
{
|
||||
R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, basetz,
|
||||
interpx, interpy, interpz);
|
||||
}
|
||||
|
||||
// Debug
|
||||
++objectsdrawn;
|
||||
|
|
@ -2161,17 +2178,9 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
fixed_t interpx = R_InterpolateFixed(thing->old_x, thing->x);
|
||||
fixed_t interpy = R_InterpolateFixed(thing->old_y, thing->y);
|
||||
fixed_t interpz = R_InterpolateFixed(thing->old_z, thing->z);
|
||||
|
||||
// transform the origin point
|
||||
tr_x = interpx - viewx;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap);
|
|||
extern INT16 negonearray[MAXVIDWIDTH];
|
||||
extern INT16 screenheightarray[MAXVIDWIDTH];
|
||||
|
||||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
|
||||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope, fixed_t interpx, fixed_t interpy, fixed_t interpz);
|
||||
|
||||
//SoM: 6/5/2000: Light sprites correctly!
|
||||
void R_AddSprites(sector_t *sec, INT32 lightlevel);
|
||||
|
|
|
|||
|
|
@ -1580,7 +1580,7 @@ void S_ShowMusicCredit(void)
|
|||
{
|
||||
cursongcredit.def = def;
|
||||
cursongcredit.anim = 5*TICRATE;
|
||||
cursongcredit.x = 0;
|
||||
cursongcredit.x = cursongcredit.old_x =0;
|
||||
cursongcredit.trans = NUMTRANSMAPS;
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,8 +179,9 @@ extern struct cursongcredit
|
|||
{
|
||||
musicdef_t *def;
|
||||
UINT16 anim;
|
||||
INT32 x;
|
||||
UINT8 trans;
|
||||
fixed_t x;
|
||||
fixed_t old_x;
|
||||
} cursongcredit;
|
||||
|
||||
extern musicdef_t *musicdefstart;
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ void SCR_SetDrawFuncs(void)
|
|||
colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8;
|
||||
colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS] = R_Draw2sMultiPatchTranslucentColumn_8;
|
||||
colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn_8;
|
||||
colfuncs[COLDRAWFUNC_DROPSHADOW] = R_DrawDropShadowColumn_8;
|
||||
|
||||
spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8;
|
||||
spanfuncs[SPANDRAWFUNC_TILTED] = R_DrawTiltedSpan_8;
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ enum
|
|||
COLDRAWFUNC_TWOSMULTIPATCH,
|
||||
COLDRAWFUNC_TWOSMULTIPATCHTRANS,
|
||||
COLDRAWFUNC_FOG,
|
||||
COLDRAWFUNC_DROPSHADOW,
|
||||
|
||||
COLDRAWFUNC_MAX
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1660,11 +1660,10 @@ tic_t I_GetTime(void)
|
|||
return (tic_t)f;
|
||||
}
|
||||
|
||||
fixed_t I_GetTimeFrac(void)
|
||||
float I_GetTimeFrac(void)
|
||||
{
|
||||
UpdateElapsedTics();
|
||||
|
||||
return FLOAT_TO_FIXED((float) (elapsed_tics - floor(elapsed_tics)));
|
||||
return elapsed_tics;
|
||||
}
|
||||
|
||||
precise_t I_GetPreciseTime(void)
|
||||
|
|
|
|||
|
|
@ -517,7 +517,7 @@ static inline void I_SetChannels(void)
|
|||
}
|
||||
}
|
||||
|
||||
void I_SetSfxVolume(UINT8 volume)
|
||||
void I_SetSfxVolume(int volume)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
|
|
@ -1466,7 +1466,7 @@ void I_ResumeSong(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
void I_SetMusicVolume(UINT8 volume)
|
||||
void I_SetMusicVolume(int volume)
|
||||
{
|
||||
(void)volume;
|
||||
}
|
||||
|
|
@ -1477,6 +1477,9 @@ boolean I_SetSongTrack(int track)
|
|||
return false;
|
||||
}
|
||||
|
||||
void I_UpdateSongLagThreshold(void){}
|
||||
void I_UpdateSongLagConditions(void){}
|
||||
|
||||
/// ------------------------
|
||||
/// MUSIC FADING
|
||||
/// ------------------------
|
||||
|
|
|
|||
10
src/tables.c
10
src/tables.c
|
|
@ -185,6 +185,16 @@ INT32 AngleDeltaSigned(angle_t a1, angle_t a2)
|
|||
return (INT32)(a1) - (INT32)(a2);
|
||||
}
|
||||
|
||||
float AngleToFloat(angle_t x)
|
||||
{
|
||||
return x / (float)ANG1;
|
||||
}
|
||||
|
||||
angle_t FloatToAngle(float f)
|
||||
{
|
||||
return (angle_t)(f * ANG1);
|
||||
}
|
||||
|
||||
#include "t_ftan.c"
|
||||
|
||||
#include "t_fsin.c"
|
||||
|
|
|
|||
|
|
@ -108,6 +108,8 @@ FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor);
|
|||
// difference between two angle_t
|
||||
FUNCMATH INT32 AngleDelta(angle_t a1, angle_t a2);
|
||||
FUNCMATH INT32 AngleDeltaSigned(angle_t a1, angle_t a2);
|
||||
FUNCMATH float AngleToFloat(angle_t x);
|
||||
FUNCMATH angle_t FloatToAngle(float f);
|
||||
|
||||
/// The FixedAcos function
|
||||
FUNCMATH angle_t FixedAcos(fixed_t x);
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ UINT8 *screens[5];
|
|||
// screens[3] = fade screen start
|
||||
// screens[4] = fade screen end, postimage tempoarary buffer
|
||||
|
||||
consvar_t cv_ticrate = CVAR_INIT ("showfps", "No", 0, CV_YesNo, NULL);
|
||||
consvar_t cv_ticrate = CVAR_INIT ("showfps", "No", CV_SAVE, CV_YesNo, NULL);
|
||||
|
||||
static void CV_palette_OnChange(void);
|
||||
|
||||
|
|
@ -2532,6 +2532,18 @@ void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *st
|
|||
V_DrawThinString(x, y, option, string);
|
||||
}
|
||||
|
||||
void V_DrawCenteredThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
|
||||
{
|
||||
x -= (V_ThinStringWidth(string, option) / 2) * FRACUNIT;
|
||||
V_DrawThinStringAtFixed(x, y, option, string);
|
||||
}
|
||||
|
||||
void V_DrawRightAlignedThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
|
||||
{
|
||||
x -= V_ThinStringWidth(string, option) * FRACUNIT;
|
||||
V_DrawThinStringAtFixed(x, y, option, string);
|
||||
}
|
||||
|
||||
void V_DrawCenteredGamemodeString(INT32 x, INT32 y, INT32 option, const UINT8 *colormap, const char *string)
|
||||
{
|
||||
x -= V_GamemodeStringWidth(string, option)/2;
|
||||
|
|
|
|||
|
|
@ -292,6 +292,9 @@ void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *st
|
|||
#define V_DrawThinStringAtFixed( x,y,option,string ) \
|
||||
V__DrawOneScaleString (x,y,FRACUNIT,option,NULL,TINY_FONT,string)
|
||||
|
||||
void V_DrawCenteredThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
|
||||
|
||||
// Draws a titlecard font string.
|
||||
// timer: when the letters start appearing (leave to 0 to disable)
|
||||
// threshold: when the letters start disappearing (leave to 0 to disable) (both are INT32 in case you supply negative values...)
|
||||
|
|
|
|||
23
src/w_wad.c
23
src/w_wad.c
|
|
@ -69,6 +69,8 @@
|
|||
#include "m_misc.h" // M_MapNumber
|
||||
#include "g_game.h" // G_SetGameModified
|
||||
|
||||
#include "k_terrain.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
#include "hardware/hw_glob.h"
|
||||
|
|
@ -354,6 +356,7 @@ static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const
|
|||
lumpinfo->size = ftell(handle);
|
||||
fseek(handle, 0, SEEK_SET);
|
||||
strcpy(lumpinfo->name, lumpname);
|
||||
lumpinfo->hash = quickncasehash(lumpname, 8);
|
||||
|
||||
// Allocate the lump's long name.
|
||||
lumpinfo->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
|
|
@ -451,6 +454,7 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
|
|||
lump_p->compression = CM_NOCOMPRESSION;
|
||||
memset(lump_p->name, 0x00, 9);
|
||||
strncpy(lump_p->name, fileinfo->name, 8);
|
||||
lump_p->hash = quickncasehash(lump_p->name, 8);
|
||||
|
||||
// Allocate the lump's long name.
|
||||
lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
|
|
@ -625,6 +629,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
|
|||
|
||||
memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
|
||||
strncpy(lump_p->name, trimname, min(8, dotpos - trimname));
|
||||
lump_p->hash = quickncasehash(lump_p->name, 8);
|
||||
|
||||
lump_p->longname = Z_Calloc(dotpos - trimname + 1, PU_STATIC, NULL);
|
||||
strlcpy(lump_p->longname, trimname, dotpos - trimname + 1);
|
||||
|
|
@ -866,6 +871,8 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
|
|||
break;
|
||||
}
|
||||
|
||||
K_InitTerrain(numwadfiles - 1);
|
||||
|
||||
if (refreshdirmenu & REFRESHDIR_GAMEDATA)
|
||||
G_LoadGameData();
|
||||
DEH_UpdateMaxFreeslots();
|
||||
|
|
@ -974,12 +981,14 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
|||
{
|
||||
UINT16 i;
|
||||
static char uname[8 + 1];
|
||||
UINT32 hash;
|
||||
|
||||
if (!TestValidLump(wad,0))
|
||||
return INT16_MAX;
|
||||
|
||||
strlcpy(uname, name, sizeof uname);
|
||||
strupr(uname);
|
||||
hash = quickncasehash(uname, 8);
|
||||
|
||||
//
|
||||
// scan forward
|
||||
|
|
@ -990,7 +999,7 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
|||
{
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
if (!strncmp(lump_p->name, uname, sizeof(uname) - 1))
|
||||
if (lump_p->hash == hash && !strncmp(lump_p->name, uname, sizeof(uname) - 1))
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
@ -1193,15 +1202,20 @@ lumpnum_t W_CheckNumForLongName(const char *name)
|
|||
// TODO: Make it search through cache first, maybe...?
|
||||
lumpnum_t W_CheckNumForMap(const char *name)
|
||||
{
|
||||
UINT32 hash = quickncasehash(name, 8);
|
||||
UINT16 lumpNum, end;
|
||||
UINT32 i;
|
||||
lumpinfo_t *p;
|
||||
for (i = numwadfiles - 1; i < numwadfiles; i--)
|
||||
{
|
||||
if (wadfiles[i]->type == RET_WAD)
|
||||
{
|
||||
for (lumpNum = 0; lumpNum < wadfiles[i]->numlumps; lumpNum++)
|
||||
if (!strncmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8))
|
||||
{
|
||||
p = wadfiles[i]->lumpinfo + lumpNum;
|
||||
if (p->hash == hash && !strncmp(name, p->name, 8))
|
||||
return (i<<16) + lumpNum;
|
||||
}
|
||||
}
|
||||
else if (wadfiles[i]->type == RET_PK3)
|
||||
{
|
||||
|
|
@ -1212,8 +1226,11 @@ lumpnum_t W_CheckNumForMap(const char *name)
|
|||
continue;
|
||||
// Now look for the specified map.
|
||||
for (; lumpNum < end; lumpNum++)
|
||||
if (!strnicmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8))
|
||||
{
|
||||
p = wadfiles[i]->lumpinfo + lumpNum;
|
||||
if (p->hash == hash && !strnicmp(name, p->name, 8))
|
||||
return (i<<16) + lumpNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
return LUMPERROR;
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ typedef struct
|
|||
unsigned long position; // filelump_t filepos
|
||||
unsigned long disksize; // filelump_t size
|
||||
char name[9]; // filelump_t name[] e.g. "LongEntr"
|
||||
UINT32 hash;
|
||||
char *longname; // e.g. "LongEntryName"
|
||||
char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension"
|
||||
size_t size; // real (uncompressed) size
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue