Merge branch 'master' into 'director-cam'

# Conflicts:
#   src/d_netcmd.h
This commit is contained in:
AJ Martinez 2022-01-23 15:38:14 -06:00
commit ef6ff846d3
30 changed files with 551 additions and 160 deletions

View file

@ -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}};
@ -940,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]);
@ -1641,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);
}
@ -1652,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,7 +86,7 @@ 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_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;

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

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

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, kickstart, shrinkme;
UINT8 slots[MAXPLAYERS], kartspeed[MAXPLAYERS], kartweight[MAXPLAYERS], numslots = 0;
#if defined(SKIPERRORS) && !defined(DEVELOP)
@ -2943,9 +2960,13 @@ void G_DoPlayDemo(char *defdemoname)
while (p != 0xFF)
{
if ((spectator = !!(p & DEMO_SPECTATOR)))
UINT8 flags = READUINT8(demo_p);
spectator = kickstart = shrinkme = false;
if ((spectator = !!(flags & DEMO_SPECTATOR)) == true)
{
p &= ~DEMO_SPECTATOR;
flags &= ~DEMO_SPECTATOR;
if (modeattacking)
{
@ -2960,10 +2981,14 @@ void G_DoPlayDemo(char *defdemoname)
}
}
if ((kickstart = (p & DEMO_KICKSTART)))
p &= ~DEMO_KICKSTART;
if ((kickstart = !!(flags & DEMO_KICKSTART)) == true)
flags &= ~DEMO_KICKSTART;
slots[numslots] = p; numslots++;
if ((shrinkme = !!(flags & DEMO_SHRINKME)) == true)
flags &= ~DEMO_SHRINKME;
slots[numslots] = p;
numslots++;
if (modeattacking && numslots > 1)
{
@ -2982,11 +3007,19 @@ void G_DoPlayDemo(char *defdemoname)
playeringame[p] = true;
players[p].spectator = spectator;
if (kickstart)
players[p].pflags |= PF_KICKSTARTACCEL;
else
players[p].pflags &= ~PF_KICKSTARTACCEL;
if (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 +3278,7 @@ void G_AddGhost(char *defdemoname)
return;
}
if ((READUINT8(p) & ~DEMO_KICKSTART) != 0)
if ((READUINT8(p) & ~(DEMO_KICKSTART|DEMO_SHRINKME)) != 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;
}

View file

@ -251,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);
@ -2905,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)
{
@ -2921,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)
{
@ -2944,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;
@ -2994,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)
@ -3100,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;
}
@ -3266,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;
@ -3795,31 +3851,63 @@ 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));
y = source->y + source->momy + FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT));
z = source->z; // spawn on the ground please
th = P_SpawnMobj(x, y, z, type);
th = P_SpawnMobj(x, y, z, type); // this will never return null because collision isn't processed here
K_FlipFromObject(th, source);
@ -3831,14 +3919,17 @@ 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))
{
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
// This should set it for FOFs
P_SetOrigin(th, th->x, th->y, th->z);
P_SetOrigin(th, th->x, th->y, th->z); // however, THIS can fuck up your day. just absolutely ruin you.
if (P_MobjWasRemoved(th))
return NULL;
// spawn on the ground if the player is on the ground
if (P_MobjFlip(source) < 0)
{
@ -3855,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:
@ -3906,7 +4002,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
P_SetTarget(&throwmo->target, source);
}
return NULL;
return th;
}
UINT16 K_DriftSparkColor(player_t *player, INT32 charge)
@ -4713,10 +4809,11 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
{
if (mapthing == MT_BALLHOG) // Messy
{
mo = NULL; // can't return multiple projectiles
if (dir == -1)
{
// Shoot backward
mo = K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) - 0x06000000, 0, PROJSPEED/8);
K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) - 0x06000000, 0, PROJSPEED/8);
K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) - 0x03000000, 0, PROJSPEED/8);
K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180, 0, PROJSPEED/8);
K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) + 0x03000000, 0, PROJSPEED/8);
@ -4725,7 +4822,7 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
else
{
// Shoot forward
mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle - 0x06000000, 0, PROJSPEED);
K_SpawnKartMissile(player->mo, mapthing, player->mo->angle - 0x06000000, 0, PROJSPEED);
K_SpawnKartMissile(player->mo, mapthing, player->mo->angle - 0x03000000, 0, PROJSPEED);
K_SpawnKartMissile(player->mo, mapthing, player->mo->angle, 0, PROJSPEED);
K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + 0x03000000, 0, PROJSPEED);
@ -4748,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)
{
@ -4781,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:
@ -4795,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
{
@ -4832,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))
{
@ -4903,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;
@ -4911,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)
{
@ -5069,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...
@ -5095,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);
@ -5205,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);
}
}
@ -5337,6 +5449,9 @@ void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source)
mobj_t *cachenext;
killnext:
if (P_MobjWasRemoved(banana))
return;
cachenext = banana->hnext;
if (banana->health)
@ -5415,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;
@ -5464,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;
@ -5553,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;
}
}
@ -5928,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;
@ -5939,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;
@ -5955,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
@ -5999,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;
@ -6030,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;
@ -6092,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);
@ -8683,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
//
@ -8783,7 +8931,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
}
else if (player->itemamount == 0)
{
player->pflags &= ~PF_ITEMOUT;
K_UnsetItemOut(player);
}
else
{
@ -8858,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++)
@ -8873,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);
@ -8902,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);
}
@ -8916,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++)
@ -8934,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);
@ -8957,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++)
@ -8974,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);
@ -8995,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)
@ -9004,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);
}
@ -9044,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;
@ -9237,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)
@ -9246,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
@ -3496,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.

View file

@ -1689,6 +1689,8 @@ void P_XYMovement(mobj_t *mo)
if (mo->flags & MF_SLIDEME)
{
P_SlideMove(mo);
if (P_MobjWasRemoved(mo))
return;
xmove = ymove = 0;
}
else
@ -10872,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

@ -1940,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;
@ -1947,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)
{
@ -3466,6 +3528,7 @@ static void P_InitLevelSettings(void)
players[i].lives = 3;
G_PlayerReborn(i, true);
K_UpdateShrinkCheat(&players[i]);
}
racecountdown = exitcountdown = exitfadestarted = 0;

View file

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

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

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

View file

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

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;

View file

@ -356,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);
@ -453,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);
@ -627,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);
@ -978,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
@ -994,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;
}
@ -1197,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)
{
@ -1216,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;

View file

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