Merge branch 'master' of https://git.do.srb2.org/KartKrew/Kart.git into votefree

This commit is contained in:
toaster 2022-01-23 22:46:11 +00:00
commit 2df53dd5a5
29 changed files with 825 additions and 155 deletions

View file

@ -113,3 +113,4 @@ k_grandprix.c
k_hud.c
k_terrain.c
k_brightmap.c
k_director.c

View file

@ -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];
@ -741,6 +744,8 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_showping);
CV_RegisterVar(&cv_showviewpointtext);
CV_RegisterVar(&cv_director);
CV_RegisterVar(&cv_dummyconsvar);
#ifdef USE_STUN
@ -935,6 +940,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]);
@ -1636,10 +1642,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);
}
@ -1647,11 +1656,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;
}

View file

@ -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];

View file

@ -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
{
@ -436,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

View file

@ -5809,6 +5809,7 @@ const char *const MOBJFLAG_LIST[] = {
"DONTENCOREMAP",
"PICKUPFROMBELOW",
"NOSQUISH",
"NOHITLAGFORME",
NULL
};
@ -5912,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.
};
@ -6555,6 +6560,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},

View file

@ -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);

View file

@ -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] = {
@ -1183,22 +1190,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);
}
@ -2164,7 +2171,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)
@ -2235,7 +2242,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);

View file

@ -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];

View file

@ -181,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;
@ -3795,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;
@ -3925,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++)
{
@ -3945,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;
}
@ -3963,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;
}
@ -4279,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)
@ -4300,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)

View file

@ -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

View file

@ -1324,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)
@ -1333,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);
}

View file

@ -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
},

View file

@ -48,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);
}
@ -143,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;
@ -492,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;
}
@ -507,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;
}
@ -522,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;
}
@ -540,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;
}
}
@ -558,7 +558,7 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
{
if (t2->player->rings <= 0)
{
P_DamageMobj(t2, t1, t1, 1, DMG_STING);
P_DamageMobj(t2, t1, t1, 1, DMG_STING|DMG_WOMBO);
stungT2 = true;
}
@ -569,7 +569,7 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
{
if (t1->player->rings <= 0)
{
P_DamageMobj(t1, t2, t2, 1, DMG_STING);
P_DamageMobj(t1, t2, t2, 1, DMG_STING|DMG_WOMBO);
stungT1 = true;
}

294
src/k_director.c Normal file
View 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
View 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);

View file

@ -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"
@ -4504,6 +4505,7 @@ void K_drawKartHUD(void)
}
K_DrawWaypointDebugger();
K_DrawDirectorDebugger();
if (gametype == GT_BATTLE)
{

View file

@ -34,6 +34,7 @@
#include "k_bot.h"
#include "k_hud.h"
#include "k_terrain.h"
#include "k_director.h"
// SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H:
// gamespeed is cc (0 for easy, 1 for normal, 2 for hard)
@ -250,7 +251,6 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartdebugitem);
CV_RegisterVar(&cv_kartdebugamount);
CV_RegisterVar(&cv_kartdebugshrink);
CV_RegisterVar(&cv_kartallowgiveitem);
CV_RegisterVar(&cv_kartdebugdistribution);
CV_RegisterVar(&cv_kartdebughuddrop);
@ -260,6 +260,7 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartdebugcheckpoint);
CV_RegisterVar(&cv_kartdebugnodes);
CV_RegisterVar(&cv_kartdebugcolorize);
CV_RegisterVar(&cv_kartdebugdirector);
}
//}
@ -2903,6 +2904,28 @@ static void K_GetKartBoostPower(player_t *player)
player->numboosts = numboosts;
}
fixed_t K_GrowShrinkSpeedMul(player_t *player)
{
fixed_t scaleDiff = player->mo->scale - mapobjectscale;
fixed_t playerScale = FixedDiv(player->mo->scale, mapobjectscale);
fixed_t speedMul = FRACUNIT;
if (scaleDiff > 0)
{
// Grown
// Change x2 speed into x1.5
speedMul = FixedDiv(FixedMul(playerScale, GROW_PHYSICS_SCALE), GROW_SCALE);
}
else if (scaleDiff < 0)
{
// Shrunk
// Change x0.5 speed into x0.75
speedMul = FixedDiv(FixedMul(playerScale, SHRINK_PHYSICS_SCALE), SHRINK_SCALE);
}
return speedMul;
}
// Returns kart speed from a stat. Boost power and scale are NOT taken into account, no player or object is necessary.
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed)
{
@ -2919,9 +2942,8 @@ fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed)
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower)
{
fixed_t finalspeed;
finalspeed = K_GetKartSpeedFromStat(player->kartspeed);
const boolean mobjValid = (player->mo != NULL && P_MobjWasRemoved(player->mo) == false);
fixed_t finalspeed = K_GetKartSpeedFromStat(player->kartspeed);
if (player->spheres > 0)
{
@ -2942,17 +2964,22 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower)
}
}
if (player->mo && !P_MobjWasRemoved(player->mo))
finalspeed = FixedMul(finalspeed, player->mo->scale);
finalspeed = FixedMul(finalspeed, mapobjectscale);
if (doboostpower)
if (doboostpower == true)
{
if (mobjValid == true)
{
// Scale with the player.
finalspeed = FixedMul(finalspeed, K_GrowShrinkSpeedMul(player));
}
if (K_PlayerUsesBotMovement(player))
{
finalspeed = FixedMul(finalspeed, K_BotTopSpeedRubberband(player));
}
return FixedMul(finalspeed, player->boostpower+player->speedboost);
finalspeed = FixedMul(finalspeed, player->boostpower + player->speedboost);
}
return finalspeed;
@ -2992,6 +3019,34 @@ UINT16 K_GetKartFlashing(player_t *player)
return tics;
}
boolean K_PlayerShrinkCheat(player_t *player)
{
return (
(player->pflags & PF_SHRINKACTIVE)
&& (player->bot == false)
&& (modeattacking == false) // Anyone want to make another record attack category?
);
}
void K_UpdateShrinkCheat(player_t *player)
{
const boolean mobjValid = (player->mo != NULL && P_MobjWasRemoved(player->mo) == false);
if (player->pflags & PF_SHRINKME)
{
player->pflags |= PF_SHRINKACTIVE;
}
else
{
player->pflags &= ~PF_SHRINKACTIVE;
}
if (mobjValid == true && K_PlayerShrinkCheat(player) == true)
{
player->mo->destscale = FixedMul(mapobjectscale, SHRINK_SCALE);
}
}
boolean K_KartKickstart(player_t *player)
{
return ((player->pflags & PF_KICKSTARTACCEL)
@ -3098,7 +3153,7 @@ angle_t K_MomentumAngle(mobj_t *mo)
void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage)
{
if (mo == NULL || P_MobjWasRemoved(mo))
if (mo == NULL || P_MobjWasRemoved(mo) || (mo->flags & MF_NOHITLAGFORME && mo->type != MT_PLAYER))
{
return;
}
@ -3234,6 +3289,8 @@ void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 typ
(void)inflictor;
(void)source;
K_DirectorFollowAttack(player, inflictor, source);
player->spinouttype = type;
if (( player->spinouttype & KSPIN_THRUST ))
@ -3262,8 +3319,11 @@ static void K_RemoveGrowShrink(player_t *player)
player->mo->scalespeed = mapobjectscale/TICRATE;
player->mo->destscale = mapobjectscale;
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
player->mo->destscale = (6*player->mo->destscale)/8;
if (K_PlayerShrinkCheat(player) == true)
{
player->mo->destscale = FixedMul(player->mo->destscale, SHRINK_SCALE);
}
}
player->growshrinktimer = 0;
@ -3276,6 +3336,8 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source)
fixed_t gravityadjust;
(void)source;
K_DirectorFollowAttack(player, inflictor, source);
player->tumbleBounces = 1;
if (player->tripWireState == TRIP_PASSED)
@ -3412,6 +3474,8 @@ INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A
(void)source;
K_DirectorFollowAttack(player, inflictor, source);
player->mo->momz = 18*mapobjectscale*P_MobjFlip(player->mo); // please stop forgetting mobjflip checks!!!!
player->mo->momx = player->mo->momy = 0;
@ -3787,24 +3851,56 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
#undef MINEQUAKEDIST
fixed_t K_ItemScaleForPlayer(player_t *player)
{
switch (player->itemscale)
{
case ITEMSCALE_GROW:
return FixedMul(GROW_SCALE, mapobjectscale);
case ITEMSCALE_SHRINK:
return FixedMul(SHRINK_SCALE, mapobjectscale);
default:
return mapobjectscale;
}
}
static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, INT32 flags2, fixed_t speed)
{
mobj_t *th;
fixed_t x, y, z;
fixed_t finalspeed = speed;
fixed_t finalscale = mapobjectscale;
mobj_t *throwmo;
if (source->player && source->player->speed > K_GetKartSpeed(source->player, false))
if (source->player != NULL)
{
angle_t input = source->angle - an;
boolean invert = (input > ANGLE_180);
if (invert)
input = InvAngle(input);
if (source->player->itemscale == ITEMSCALE_SHRINK)
{
// Nerf the base item speed a bit.
finalspeed = FixedMul(finalspeed, SHRINK_PHYSICS_SCALE);
}
finalspeed = max(speed, FixedMul(speed, FixedMul(
FixedDiv(source->player->speed, K_GetKartSpeed(source->player, false)), // Multiply speed to be proportional to your own, boosted maxspeed.
(((180<<FRACBITS) - AngleFixed(input)) / 180) // multiply speed based on angle diff... i.e: don't do this for firing backward :V
)));
if (source->player->speed > K_GetKartSpeed(source->player, false))
{
angle_t input = source->angle - an;
boolean invert = (input > ANGLE_180);
if (invert)
input = InvAngle(input);
finalspeed = max(speed, FixedMul(speed, FixedMul(
FixedDiv(source->player->speed, K_GetKartSpeed(source->player, false)), // Multiply speed to be proportional to your own, boosted maxspeed.
(((180<<FRACBITS) - AngleFixed(input)) / 180) // multiply speed based on angle diff... i.e: don't do this for firing backward :V
)));
}
finalscale = K_ItemScaleForPlayer(source->player);
}
if (type == MT_BUBBLESHIELDTRAP)
{
finalscale = source->scale;
}
x = source->x + source->momx + FixedMul(finalspeed, FINECOSINE(an>>ANGLETOFINESHIFT));
@ -3823,8 +3919,8 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
P_SetTarget(&th->target, source);
P_SetScale(th, source->scale);
th->destscale = source->destscale;
P_SetScale(th, finalscale);
th->destscale = finalscale;
if (P_IsObjectOnGround(source))
{
@ -3850,6 +3946,11 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
th->momy = FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT));
th->momz = source->momz;
if (source->player != NULL)
{
th->cusval = source->player->itemscale;
}
switch (type)
{
case MT_ORBINAUT:
@ -4744,13 +4845,15 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
}
else
{
fixed_t finalscale = K_ItemScaleForPlayer(player);
player->bananadrag = 0; // RESET timer, for multiple bananas
if (dir > 0)
{
// Shoot forward
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, mapthing);
//K_FlipFromObject(mo, player->mo);
// These are really weird so let's make it a very specific case to make SURE it works...
if (player->mo->eflags & MFE_VERTICALFLIP)
{
@ -4777,6 +4880,9 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
if (mo->eflags & MFE_UNDERWATER)
mo->momz = (117 * mo->momz) / 200;
P_SetScale(mo, finalscale);
mo->destscale = finalscale;
}
// this is the small graphic effect that plops in you when you throw an item:
@ -4791,6 +4897,9 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
}
throwmo->movecount = 0; // above player
P_SetScale(throwmo, finalscale);
throwmo->destscale = finalscale;
}
else
{
@ -4828,8 +4937,8 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
mo->threshold = 10;
P_SetTarget(&mo->target, player->mo);
P_SetScale(mo, player->mo->scale);
mo->destscale = player->mo->destscale;
P_SetScale(mo, finalscale);
mo->destscale = finalscale;
if (P_IsObjectOnGround(player->mo))
{
@ -4899,6 +5008,10 @@ void K_PuntMine(mobj_t *origMine, mobj_t *punter)
mine->floorz = origMine->floorz;
mine->ceilingz = origMine->ceilingz;
P_SetScale(mine, origMine->scale);
mine->destscale = origMine->destscale;
mine->scalespeed = origMine->scalespeed;
// Copy interp data
mine->old_angle = origMine->old_angle;
mine->old_x = origMine->old_x;
@ -4907,8 +5020,7 @@ void K_PuntMine(mobj_t *origMine, mobj_t *punter)
// Since we aren't using P_KillMobj, we need to clean up the hnext reference
P_SetTarget(&mineOwner->hnext, NULL);
mineOwner->player->bananadrag = 0;
mineOwner->player->pflags &= ~PF_ITEMOUT;
K_UnsetItemOut(mineOwner->player);
if (mineOwner->player->itemamount)
{
@ -5065,7 +5177,7 @@ static void K_DoHyudoroSteal(player_t *player)
player->itemtype = KITEM_KITCHENSINK;
player->itemamount = 1;
player->pflags &= ~PF_ITEMOUT;
K_UnsetItemOut(player);
return;
}
else if ((gametype == GT_RACE && player->position == 1) || numplayers == 0) // No-one can be stolen from? Oh well...
@ -5091,11 +5203,11 @@ static void K_DoHyudoroSteal(player_t *player)
player->itemtype = players[stealplayer].itemtype;
player->itemamount = players[stealplayer].itemamount;
player->pflags &= ~PF_ITEMOUT;
K_UnsetItemOut(player);
players[stealplayer].itemtype = KITEM_NONE;
players[stealplayer].itemamount = 0;
players[stealplayer].pflags &= ~PF_ITEMOUT;
K_UnsetItemOut(&players[stealplayer]);
if (P_IsDisplayPlayer(&players[stealplayer]) && !r_splitscreen)
S_StartSound(NULL, sfx_s3k92);
@ -5201,9 +5313,13 @@ static void K_DoShrink(player_t *user)
if (players[i].mo && !P_MobjWasRemoved(players[i].mo))
{
players[i].mo->scalespeed = mapobjectscale/TICRATE;
players[i].mo->destscale = (6*mapobjectscale)/8;
if (cv_kartdebugshrink.value && !modeattacking && !players[i].bot)
players[i].mo->destscale = (6*players[i].mo->destscale)/8;
players[i].mo->destscale = FixedMul(mapobjectscale, SHRINK_SCALE);
if (K_PlayerShrinkCheat(&players[i]) == true)
{
players[i].mo->destscale = FixedMul(players[i].mo->destscale, SHRINK_SCALE);
}
S_StartSound(players[i].mo, sfx_kc59);
}
}
@ -5414,7 +5530,7 @@ void K_DropHnextList(player_t *player, boolean keepshields)
player->curshield = KSHIELD_NONE;
player->itemtype = KITEM_NONE;
player->itemamount = 0;
player->pflags &= ~PF_ITEMOUT;
K_UnsetItemOut(player);
}
nextwork = work->hnext;
@ -5463,6 +5579,10 @@ void K_DropHnextList(player_t *player, boolean keepshields)
dropwork->angle = work->angle;
P_SetScale(dropwork, work->scale);
dropwork->destscale = work->destscale;
dropwork->scalespeed = work->scalespeed;
dropwork->flags |= MF_NOCLIPTHING;
dropwork->flags2 = work->flags2;
dropwork->eflags = work->eflags;
@ -5552,7 +5672,7 @@ void K_DropHnextList(player_t *player, boolean keepshields)
&& (dropall || (--player->itemamount <= 0)))
{
player->itemamount = 0;
player->pflags &= ~PF_ITEMOUT;
K_UnsetItemOut(player);
player->itemtype = KITEM_NONE;
}
}
@ -5927,6 +6047,8 @@ static void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z
// Move the hnext chain!
static void K_MoveHeldObjects(player_t *player)
{
fixed_t finalscale = INT32_MAX;
if (!player->mo)
return;
@ -5938,7 +6060,7 @@ static void K_MoveHeldObjects(player_t *player)
else if (player->pflags & PF_ITEMOUT)
{
player->itemamount = 0;
player->pflags &= ~PF_ITEMOUT;
K_UnsetItemOut(player);
player->itemtype = KITEM_NONE;
}
return;
@ -5954,12 +6076,14 @@ static void K_MoveHeldObjects(player_t *player)
else if (player->pflags & PF_ITEMOUT)
{
player->itemamount = 0;
player->pflags &= ~PF_ITEMOUT;
K_UnsetItemOut(player);
player->itemtype = KITEM_NONE;
}
return;
}
finalscale = K_ItemScaleForPlayer(player);
switch (player->mo->hnext->type)
{
case MT_ORBINAUT_SHIELD: // Kart orbit items
@ -5998,7 +6122,7 @@ static void K_MoveHeldObjects(player_t *player)
cur->eflags &= ~MFE_VERTICALFLIP;
// Shrink your items if the player shrunk too.
P_SetScale(cur, (cur->destscale = FixedMul(FixedDiv(cur->extravalue1, radius), player->mo->scale)));
P_SetScale(cur, (cur->destscale = FixedMul(FixedDiv(cur->extravalue1, radius), finalscale)));
if (P_MobjFlip(cur) > 0)
z = player->mo->z;
@ -6029,7 +6153,7 @@ static void K_MoveHeldObjects(player_t *player)
}
// Center it during the scale up animation
z += (FixedMul(mobjinfo[cur->type].height, player->mo->scale - cur->scale)>>1) * P_MobjFlip(cur);
z += (FixedMul(mobjinfo[cur->type].height, finalscale - cur->scale)>>1) * P_MobjFlip(cur);
cur->z = z;
cur->momx = cur->momy = 0;
@ -6091,7 +6215,7 @@ static void K_MoveHeldObjects(player_t *player)
continue;
// Shrink your items if the player shrunk too.
P_SetScale(cur, (cur->destscale = FixedMul(FixedDiv(cur->extravalue1, radius), player->mo->scale)));
P_SetScale(cur, (cur->destscale = FixedMul(FixedDiv(cur->extravalue1, radius), finalscale)));
ang = targ->angle;
targx = targ->x + P_ReturnThrustX(cur, ang + ANGLE_180, dist);
@ -8682,6 +8806,31 @@ static void K_trickPanelTimingVisual(player_t *player, fixed_t momz)
#undef RADIUSSCALING
#undef MINRADIUS
void K_SetItemOut(player_t *player)
{
player->pflags |= PF_ITEMOUT;
if (player->mo->scale >= FixedMul(GROW_PHYSICS_SCALE, mapobjectscale))
{
player->itemscale = ITEMSCALE_GROW;
}
else if (player->mo->scale <= FixedMul(SHRINK_PHYSICS_SCALE, mapobjectscale))
{
player->itemscale = ITEMSCALE_SHRINK;
}
else
{
player->itemscale = ITEMSCALE_NORMAL;
}
}
void K_UnsetItemOut(player_t *player)
{
player->pflags &= ~PF_ITEMOUT;
player->itemscale = ITEMSCALE_NORMAL;
player->bananadrag = 0;
}
//
// K_MoveKartPlayer
//
@ -8782,7 +8931,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
}
else if (player->itemamount == 0)
{
player->pflags &= ~PF_ITEMOUT;
K_UnsetItemOut(player);
}
else
{
@ -8857,7 +9006,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
mobj_t *prev = player->mo;
//K_PlayAttackTaunt(player->mo);
player->pflags |= PF_ITEMOUT;
K_SetItemOut(player);
S_StartSound(player->mo, sfx_s254);
for (moloop = 0; moloop < player->itemamount; moloop++)
@ -8872,6 +9021,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
mo->threshold = 10;
mo->movecount = player->itemamount;
mo->movedir = moloop+1;
mo->cusval = player->itemscale;
P_SetTarget(&mo->target, player->mo);
P_SetTarget(&mo->hprev, prev);
P_SetTarget(&prev->hnext, mo);
@ -8901,6 +9051,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
mo->threshold = 10;
mo->movecount = 1;
mo->movedir = 1;
mo->cusval = player->itemscale;
P_SetTarget(&mo->target, player->mo);
P_SetTarget(&player->mo->hnext, mo);
}
@ -8915,7 +9066,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
mobj_t *prev = player->mo;
//K_PlayAttackTaunt(player->mo);
player->pflags |= PF_ITEMOUT;
K_SetItemOut(player);
S_StartSound(player->mo, sfx_s3k3a);
for (moloop = 0; moloop < player->itemamount; moloop++)
@ -8933,6 +9084,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
mo->movecount = player->itemamount;
mo->movedir = mo->lastlook = moloop+1;
mo->color = player->skincolor;
mo->cusval = player->itemscale;
P_SetTarget(&mo->target, player->mo);
P_SetTarget(&mo->hprev, prev);
P_SetTarget(&prev->hnext, mo);
@ -8956,7 +9108,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
mobj_t *prev = player->mo;
//K_PlayAttackTaunt(player->mo);
player->pflags |= PF_ITEMOUT;
K_SetItemOut(player);
S_StartSound(player->mo, sfx_s3k3a);
for (moloop = 0; moloop < player->itemamount; moloop++)
@ -8973,6 +9125,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
mo->threshold = 10;
mo->movecount = player->itemamount;
mo->movedir = mo->lastlook = moloop+1;
mo->cusval = player->itemscale;
P_SetTarget(&mo->target, player->mo);
P_SetTarget(&mo->hprev, prev);
P_SetTarget(&prev->hnext, mo);
@ -8994,7 +9147,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
{
mobj_t *mo;
player->pflags |= PF_ITEMOUT;
K_SetItemOut(player);
S_StartSound(player->mo, sfx_s254);
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SSMINE_SHIELD);
if (mo)
@ -9003,6 +9156,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
mo->threshold = 10;
mo->movecount = 1;
mo->movedir = 1;
mo->cusval = player->itemscale;
P_SetTarget(&mo->target, player->mo);
P_SetTarget(&player->mo->hnext, mo);
}
@ -9043,23 +9197,39 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
case KITEM_GROW:
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
{
if (player->growshrinktimer < 0) // If you're shrunk, then "grow" will just make you normal again.
if (player->growshrinktimer < 0)
{
// If you're shrunk, then "grow" will just make you normal again.
K_RemoveGrowShrink(player);
}
else
{
K_PlayPowerGloatSound(player->mo);
player->mo->scalespeed = mapobjectscale/TICRATE;
player->mo->destscale = (3*mapobjectscale)/2;
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
player->mo->destscale = (6*player->mo->destscale)/8;
player->mo->destscale = FixedMul(mapobjectscale, GROW_SCALE);
if (K_PlayerShrinkCheat(player) == true)
{
player->mo->destscale = FixedMul(player->mo->destscale, SHRINK_SCALE);
}
player->growshrinktimer = itemtime+(4*TICRATE); // 12 seconds
if (P_IsLocalPlayer(player))
if (P_IsLocalPlayer(player) == true)
{
S_ChangeMusicSpecial("kgrow");
if (! P_IsDisplayPlayer(player))
}
if (P_IsDisplayPlayer(player) == false)
{
S_StartSound(player->mo, (cv_kartinvinsfx.value ? sfx_alarmg : sfx_kgrow));
}
P_RestoreMusic(player);
S_StartSound(player->mo, sfx_kc5a);
}
player->itemamount--;
}
break;
@ -9236,7 +9406,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
{
mobj_t *mo;
player->pflags |= PF_ITEMOUT;
K_SetItemOut(player);
S_StartSound(player->mo, sfx_s254);
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SINK_SHIELD);
if (mo)
@ -9245,6 +9415,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
mo->threshold = 10;
mo->movecount = 1;
mo->movedir = 1;
mo->cusval = player->itemscale;
P_SetTarget(&mo->target, player->mo);
P_SetTarget(&player->mo->hnext, mo);
}

View file

@ -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);
@ -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__

View file

@ -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);
}
}

View file

@ -14107,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;

View file

@ -1929,7 +1929,18 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (combo == false)
{
if (player->mo->hitlag == 0 && 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);

View file

@ -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
@ -486,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

View file

@ -782,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

View file

@ -10874,9 +10874,12 @@ void P_SpawnPlayer(INT32 playernum)
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

View file

@ -161,7 +161,9 @@ typedef enum
MF_PICKUPFROMBELOW = 1<<29,
// Disable momentum-based squash and stretch.
MF_NOSQUISH = 1<<30,
// free: to and including 1<<31
// 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

View file

@ -93,6 +93,7 @@
#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)
@ -1939,6 +1940,70 @@ 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;
@ -1946,16 +2011,14 @@ static void P_ProcessLinedefsAfterSidedefs(void)
for (; i--; ld++)
{
INT32 midtexture = sides[ld->sidenum[0]].midtexture;
terrain_t *terrain = K_GetTerrainForTextureNum(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 (terrain != NULL && (terrain->flags & TRF_TRIPWIRE))
{
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)
{
@ -3465,6 +3528,7 @@ static void P_InitLevelSettings(void)
players[i].lives = 3;
G_PlayerReborn(i, true);
K_UpdateShrinkCheat(&players[i]);
}
racecountdown = exitcountdown = exitfadestarted = 0;
@ -4142,6 +4206,8 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
memset(localaiming, 0, sizeof(localaiming));
}
K_InitDirector();
wantedcalcdelay = wantedfrequency*2;
indirectitemcooldown = 0;
hyubgone = 0;

View file

@ -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++)
{

View file

@ -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);
}

View file

@ -861,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;