Merge branch 'blentran-update' of git.do.srb2.org:STJr/SRB2 into blentran-update

This commit is contained in:
MascaraSnake 2022-01-04 19:35:10 +01:00
commit ee7fc9853d
18 changed files with 240 additions and 205 deletions

View file

@ -29,11 +29,16 @@ void B_UpdateBotleader(player_t *player)
{
if (players[i].bot || players[i].playerstate != PST_LIVE || players[i].spectator || !players[i].mo)
continue;
if (!player->mo) //Can't do distance calculations if there's no player object, so we'll just take the first we find
if (!player->botleader)
{
player->botleader = &players[i];
player->botleader = &players[i]; // set default
return;
}
if (!player->mo)
return;
//Update best candidate based on nearest distance
dist = R_PointToDist2(player->mo->x, player->mo->y, players[i].mo->x, players[i].mo->y);
if (neardist > dist)

View file

@ -3763,7 +3763,7 @@ static void Command_ListWADS_f(void)
nameonly(tempname = va("%s", wadfiles[i]->filename));
if (!i)
CONS_Printf("\x82 IWAD\x80: %s\n", tempname);
else if (i <= mainwads)
else if (i < mainwads)
CONS_Printf("\x82 * %.2d\x80: %s\n", i, tempname);
else if (!wadfiles[i]->important)
CONS_Printf("\x86 %.2d: %s\n", i, tempname);

View file

@ -5099,6 +5099,7 @@ struct int_const_s const INT_CONST[] = {
{"PAL_MIXUP",PAL_MIXUP},
{"PAL_RECYCLE",PAL_RECYCLE},
{"PAL_NUKE",PAL_NUKE},
{"PAL_INVERT",PAL_INVERT},
// for P_DamageMobj
//// Damage types
{"DMG_WATER",DMG_WATER},

View file

@ -3300,7 +3300,7 @@ boolean G_EnoughPlayersFinished(void)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator || players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN)
if (!playeringame[i] || players[i].spectator || players[i].bot)
continue;
if (players[i].quittime > 30 * TICRATE)
continue;

View file

@ -2476,7 +2476,7 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
if (!players[tab[i].num].quittime || (leveltime / (TICRATE/2) & 1))
V_DrawString(x + 10, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| (greycheck ? 0 : V_TRANSLUCENT)
| (greycheck ? V_TRANSLUCENT : 0)
| V_ALLOWLOWERCASE, name);
if (gametyperules & GTR_TEAMFLAGS)
@ -2737,12 +2737,12 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
if (circuitmap)
{
if (players[tab[i].num].exiting)
V_DrawRightAlignedThinString(x+146, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime)));
V_DrawRightAlignedThinString(x+100, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime)));
else
V_DrawRightAlignedThinString(x+146, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count));
V_DrawRightAlignedThinString(x+100, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count));
}
else
V_DrawRightAlignedThinString(x+146, y, (greycheck ? V_TRANSLUCENT : 0), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
V_DrawRightAlignedThinString(x+100, y, (greycheck ? V_TRANSLUCENT : 0), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
}
else
V_DrawRightAlignedThinString(x+100, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count));
@ -2790,7 +2790,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
if (!players[tab[i].num].quittime || (leveltime / (TICRATE/2) & 1))
V_DrawString(x + 10, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| (greycheck ? 0 : V_TRANSLUCENT)
| (greycheck ? V_TRANSLUCENT : 0)
| V_ALLOWLOWERCASE, name);
if (G_GametypeUsesLives()) //show lives
@ -2850,13 +2850,13 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
if (players[tab[i].num].exiting)
V_DrawRightAlignedThinString(x+128, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime)));
else
V_DrawRightAlignedThinString(x+128, y, (greycheck ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
V_DrawRightAlignedThinString(x+128, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count));
}
else
V_DrawRightAlignedThinString(x+128, y, (greycheck ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
V_DrawRightAlignedThinString(x+128, y, (greycheck ? V_TRANSLUCENT : 0), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
}
else
V_DrawRightAlignedThinString(x+128, y, (greycheck ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
V_DrawRightAlignedThinString(x+128, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count));
y += 9;
if (i == 16)
@ -3095,7 +3095,7 @@ static void HU_DrawRankings(void)
HU_DrawTeamTabRankings(tab, whiteplayer);
else if (scorelines <= 9 && !cv_compactscoreboard.value)
HU_DrawTabRankings(40, 32, tab, scorelines, whiteplayer);
else if (scorelines <= 20 && !cv_compactscoreboard.value)
else if (scorelines <= 18 && !cv_compactscoreboard.value)
HU_DrawDualTabRankings(32, 32, tab, scorelines, whiteplayer);
else
HU_Draw32TabRankings(14, 28, tab, scorelines, whiteplayer);

View file

@ -5198,11 +5198,11 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // speed
24*FRACUNIT, // radius
34*FRACUNIT, // height
0, // display offset
1, // display offset
DMG_FIRE, // mass
0, // damage
sfx_None, // activesound
MF_NOGRAVITY|MF_NOBLOCKMAP|MF_FIRE|MF_PAIN, // flags
MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_FIRE|MF_PAIN, // flags
S_NULL // raisestate
},
@ -7977,7 +7977,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
MF_SOLID|MF_SCENERY, // flags
S_NULL // raisestate
},
@ -8004,7 +8004,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY|MF_NOCLIPHEIGHT|MF_PAPERCOLLISION, // flags
MF_SOLID|MF_NOGRAVITY|MF_SCENERY|MF_PAPERCOLLISION, // flags
S_NULL // raisestate
},
@ -8031,7 +8031,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_SCENERY|MF_NOCLIP|MF_NOCLIPTHING, // flags
S_NULL // raisestate
},

View file

@ -1117,7 +1117,7 @@ int LUA_HookMusicChange(const char *oldname, struct MusicChange *param)
lua_pushstring(gL, oldname);/* the only constant value */
lua_pushstring(gL, param->newname);/* semi constant */
for (k = 0; k <= map->numHooks; ++k)
for (k = 0; k < map->numHooks; ++k)
{
get_hook(&hook, map->ids, k);

View file

@ -88,6 +88,12 @@ static int lib_finetangent(lua_State *L)
return 1;
}
static int lib_fixedasin(lua_State *L)
{
lua_pushangle(L, -FixedAcos(luaL_checkfixed(L, 1)) + ANGLE_90);
return 1;
}
static int lib_fixedacos(lua_State *L)
{
lua_pushangle(L, FixedAcos(luaL_checkfixed(L, 1)));
@ -199,6 +205,7 @@ static luaL_Reg lib_math[] = {
{"sin", lib_finesine},
{"cos", lib_finecosine},
{"tan", lib_finetangent},
{"asin", lib_fixedasin},
{"acos", lib_fixedacos},
{"FixedAngle", lib_fixedangle},
{"fixangle" , lib_fixedangle},

View file

@ -11588,9 +11588,7 @@ static void M_ServerOptions(INT32 choice)
OP_ServerOptionsMenu[ 2].status = IT_STRING | IT_CVAR;
OP_ServerOptionsMenu[ 3].status = IT_STRING | IT_CVAR;
OP_ServerOptionsMenu[ 4].status = IT_STRING | IT_CVAR;
OP_ServerOptionsMenu[36].status = (netgame
? IT_GRAYEDOUT
: (IT_STRING | IT_CVAR | IT_CV_STRING));
OP_ServerOptionsMenu[36].status = IT_STRING | IT_CVAR | IT_CV_STRING;
OP_ServerOptionsMenu[37].status = IT_STRING | IT_CVAR;
OP_ServerOptionsMenu[38].status = IT_STRING | IT_CVAR;
}

View file

@ -1516,8 +1516,8 @@ void T_EachTimeThinker(eachtime_t *eachtime)
{
for (i = 0; i < MAXPLAYERS; i++)
{
if (P_IsPlayerValid(i) && playersArea[i])
continue;
if (P_IsPlayerValid(i) && !playersArea[i])
return;
}
}

View file

@ -349,6 +349,7 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration);
#define PAL_MIXUP 2
#define PAL_RECYCLE 3
#define PAL_NUKE 4
#define PAL_INVERT 5
//
// P_ENEMY

View file

@ -1152,9 +1152,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; // underneath
if (tmthing->eflags & MFE_VERTICALFLIP)
thing->z = tmthing->z - thing->height - FixedMul(FRACUNIT, tmthing->scale);
P_TeleportMove(thing, thing->x, thing->y, tmthing->z - thing->height - FixedMul(FRACUNIT, tmthing->scale));
else
thing->z = tmthing->z + tmthing->height + FixedMul(FRACUNIT, tmthing->scale);
P_TeleportMove(thing, thing->x, thing->y, tmthing->z + tmthing->height + FixedMul(FRACUNIT, tmthing->scale));
if (thing->flags & MF_SHOOTABLE)
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE);
return true;
@ -1465,86 +1465,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true;
}
// Sprite Spikes!
// Do not return because solidity code comes below.
if (tmthing->type == MT_SPIKE && tmthing->flags & MF_SOLID && thing->player) // moving spike rams into player?!
{
if (tmthing->eflags & MFE_VERTICALFLIP)
{
if (thing->z + thing->height <= tmthing->z + FixedMul(FRACUNIT, tmthing->scale)
&& thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz
&& !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && thing->eflags & MFE_VERTICALFLIP))
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE);
}
else if (thing->z >= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale)
&& thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz
&& !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && !(thing->eflags & MFE_VERTICALFLIP)))
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE);
}
else if (thing->type == MT_SPIKE && thing->flags & MF_SOLID && tmthing->player) // unfortunate player falls into spike?!
{
if (thing->eflags & MFE_VERTICALFLIP)
{
if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale)
&& tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale)
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && tmthing->eflags & MFE_VERTICALFLIP))
P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE);
}
else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
&& tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && !(tmthing->eflags & MFE_VERTICALFLIP)))
P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE);
}
if (tmthing->type == MT_WALLSPIKE && tmthing->flags & MF_SOLID && thing->player) // wall spike impales player
{
fixed_t bottomz, topz;
bottomz = tmthing->z;
topz = tmthing->z + tmthing->height;
if (tmthing->eflags & MFE_VERTICALFLIP)
bottomz -= FixedMul(FRACUNIT, tmthing->scale);
else
topz += FixedMul(FRACUNIT, tmthing->scale);
if (thing->z + thing->height > bottomz // above bottom
&& thing->z < topz) // below top
// don't check angle, the player was clearly in the way in this case
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE);
}
else if (thing->type == MT_WALLSPIKE && thing->flags & MF_SOLID && tmthing->player)
{
fixed_t bottomz, topz;
angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y);
if (P_PlayerInPain(tmthing->player) && (tmthing->momx || tmthing->momy))
{
angle_t playerangle = R_PointToAngle2(0, 0, tmthing->momx, tmthing->momy) - touchangle;
if (playerangle > ANGLE_180)
playerangle = InvAngle(playerangle);
if (playerangle < ANGLE_90)
return true; // Yes, this is intentionally outside the z-height check. No standing on spikes whilst moving away from them.
}
bottomz = thing->z;
topz = thing->z + thing->height;
if (thing->eflags & MFE_VERTICALFLIP)
bottomz -= FixedMul(FRACUNIT, thing->scale);
else
topz += FixedMul(FRACUNIT, thing->scale);
if (tmthing->z + tmthing->height > bottomz // above bottom
&& tmthing->z < topz // below top
&& !P_MobjWasRemoved(thing->tracer)) // this probably wouldn't work if we didn't have a tracer
{ // use base as a reference point to determine what angle you touched the spike at
touchangle = thing->angle - touchangle;
if (touchangle > ANGLE_180)
touchangle = InvAngle(touchangle);
if (touchangle <= ANGLE_22h) // if you touched it at this close an angle, you get poked!
P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE);
}
}
if (thing->flags & MF_PUSHABLE)
{
if (tmthing->type == MT_FAN || tmthing->type == MT_STEAM)
@ -1623,6 +1543,22 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->player)
{
if (tmthing->type == MT_WALLSPIKE && (tmthing->flags & MF_SOLID)) // wall spike impales player
{
fixed_t bottomz, topz;
bottomz = tmthing->z;
topz = tmthing->z + tmthing->height;
if (tmthing->eflags & MFE_VERTICALFLIP)
bottomz -= FixedMul(FRACUNIT, tmthing->scale);
else
topz += FixedMul(FRACUNIT, tmthing->scale);
if (thing->z + thing->height > bottomz // above bottom
&& thing->z < topz) // below top
// don't check angle, the player was clearly in the way in this case
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE);
}
// Doesn't matter what gravity player's following! Just do your stuff in YOUR direction only
if (tmthing->eflags & MFE_VERTICALFLIP
&& (tmthing->z + tmthing->height + tmthing->momz < thing->z
@ -1657,6 +1593,55 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (!tmthing->health)
return true;
if (thing->type == MT_SPIKE && (thing->flags & MF_SOLID)) // unfortunate player falls into spike?!
{
if (thing->eflags & MFE_VERTICALFLIP)
{
if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale)
&& tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale)
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && tmthing->eflags & MFE_VERTICALFLIP))
P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE);
}
else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
&& tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && !(tmthing->eflags & MFE_VERTICALFLIP)))
P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE);
}
if (thing->type == MT_WALLSPIKE && (thing->flags & MF_SOLID))
{
fixed_t bottomz, topz;
angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y);
if (P_PlayerInPain(tmthing->player) && (tmthing->momx || tmthing->momy))
{
angle_t playerangle = R_PointToAngle2(0, 0, tmthing->momx, tmthing->momy) - touchangle;
if (playerangle > ANGLE_180)
playerangle = InvAngle(playerangle);
if (playerangle < ANGLE_90)
return true; // Yes, this is intentionally outside the z-height check. No standing on spikes whilst moving away from them.
}
bottomz = thing->z;
topz = thing->z + thing->height;
if (thing->eflags & MFE_VERTICALFLIP)
bottomz -= FixedMul(FRACUNIT, thing->scale);
else
topz += FixedMul(FRACUNIT, thing->scale);
if (tmthing->z + tmthing->height > bottomz // above bottom
&& tmthing->z < topz // below top
&& !P_MobjWasRemoved(thing->tracer)) // this probably wouldn't work if we didn't have a tracer
{ // use base as a reference point to determine what angle you touched the spike at
touchangle = thing->angle - touchangle;
if (touchangle > ANGLE_180)
touchangle = InvAngle(touchangle);
if (touchangle <= ANGLE_22h) // if you touched it at this close an angle, you get poked!
P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE);
}
}
if (thing->type == MT_FAN || thing->type == MT_STEAM)
P_DoFanAndGasJet(thing, tmthing);
else if (thing->flags & MF_SPRING && tmthing->player->powers[pw_carry] != CR_MINECART)
@ -1721,8 +1706,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
}
}
if ((tmthing->flags & MF_SPRING || tmthing->type == MT_STEAM || tmthing->type == MT_SPIKE || tmthing->type == MT_WALLSPIKE) && (thing->player))
; // springs, gas jets and springs should never be able to step up onto a player
if ((thing->player) && (tmthing->flags & MF_SPRING || tmthing->type == MT_STEAM))
; // springs and gas jets should never be able to step up onto a player
// z checking at last
// Treat noclip things as non-solid!
else if ((thing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID
@ -1730,6 +1715,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
fixed_t topz, tmtopz;
if (tmthing->type == MT_SPIKE || tmthing->type == MT_WALLSPIKE) // do not run height checks if you are a spike
return true;
if (tmthing->eflags & MFE_VERTICALFLIP)
{
// pass under
@ -2727,6 +2715,16 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
&& P_MobjFlip(thing)*thing->momz > FixedMul(FRACUNIT, thing->scale))
maxstep = 0;
}
else if (thing->flags & MF_PUSHABLE)
{
// If using type Section1:13, double the maxstep.
if (GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 13)
maxstep <<= 1;
// If using type Section1:14, no maxstep.
if (GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14)
maxstep = 0;
}
if (thing->type == MT_SKIM)
maxstep = 0;

View file

@ -395,13 +395,13 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
if (skin)
{
UINT16 stateframe = st->frame;
// Add/Remove FF_SPR2SUPER based on certain conditions
if (player->charflags & SF_NOSUPERSPRITES)
stateframe = stateframe & ~FF_SPR2SUPER;
else if (player->powers[pw_super])
stateframe = stateframe | FF_SPR2SUPER;
if (stateframe & FF_SPR2SUPER)
{
if (mobj->eflags & MFE_FORCENOSUPER)
@ -409,11 +409,11 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
}
else if (mobj->eflags & MFE_FORCESUPER)
stateframe = stateframe | FF_SPR2SUPER;
// Get the sprite2 and frame number
spr2 = P_GetSkinSprite2(skin, (stateframe & FF_FRAMEMASK), mobj->player);
numframes = skin->sprites[spr2].numframes;
if (state == S_PLAY_STND && (spr2 & FF_SPR2SUPER) && skin->sprites[SPR2_WAIT|FF_SPR2SUPER].numframes == 0)
mobj->tics = -1; // If no super wait, don't wait at all
}
@ -541,7 +541,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
if (skin)
{
UINT16 stateframe = st->frame;
// Add/Remove FF_SPR2SUPER based on certain conditions
if (stateframe & FF_SPR2SUPER)
{
@ -550,11 +550,11 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
}
else if (mobj->eflags & MFE_FORCESUPER)
stateframe = stateframe | FF_SPR2SUPER;
// Get the sprite2 and frame number
spr2 = P_GetSkinSprite2(skin, (stateframe & FF_FRAMEMASK), NULL);
numframes = skin->sprites[spr2].numframes;
if (state == S_PLAY_STND && (spr2 & FF_SPR2SUPER) && skin->sprites[SPR2_WAIT|FF_SPR2SUPER].numframes == 0)
mobj->tics = -1; // If no super wait, don't wait at all
}
@ -1872,7 +1872,7 @@ void P_XYMovement(mobj_t *mo)
// blocked move
moved = false;
if (player)
if (player)
B_MoveBlocked(player);
if (LUA_HookMobjMoveBlocked(mo, tmhitthing, blockingline))
@ -2522,7 +2522,7 @@ boolean P_ZMovement(mobj_t *mo)
{
P_KillMobj(mo, NULL, NULL, 0);
}
return false;
return !P_MobjWasRemoved(mo); // allows explosion states to run
}
else
{
@ -3323,7 +3323,7 @@ void P_MobjCheckWater(mobj_t *mobj)
{ // Water removes electric and non-water fire shields...
if (electric)
P_FlashPal(p, PAL_WHITE, 1);
p->powers[pw_shield] = p->powers[pw_shield] & SH_STACK;
}
}
@ -7059,6 +7059,8 @@ static void P_PyreFlyBurn(mobj_t *mobj, fixed_t hoffs, INT16 vrange, mobjtype_t
fixed_t zoffs = P_RandomRange(-vrange, vrange)*FRACUNIT;
mobj_t *particle = P_SpawnMobjFromMobj(mobj, xoffs, yoffs, zoffs, mobjtype);
particle->momz = momz;
particle->flags2 |= MF2_LINKDRAW;
P_SetTarget(&particle->tracer, mobj);
}
static void P_MobjScaleThink(mobj_t *mobj)
@ -7842,6 +7844,48 @@ static void P_MobjSceneryThink(mobj_t *mobj)
if (P_MobjFlip(mobj)*mobj->momz < mobj->info->speed)
mobj->momz = P_MobjFlip(mobj)*mobj->info->speed;
break;
case MT_SPIKE:
if (mobj->fuse)
{
mobj->fuse--;
break;
}
P_SetMobjState(mobj, mobj->state->nextstate);
mobj->fuse = mobj->info->speed;
if (mobj->spawnpoint)
mobj->fuse += mobj->spawnpoint->angle;
break;
case MT_WALLSPIKE:
if (mobj->fuse)
{
mobj->fuse--;
break;
}
P_SetMobjState(mobj, mobj->state->nextstate);
mobj->fuse = mobj->info->speed;
if (mobj->spawnpoint)
mobj->fuse += (mobj->spawnpoint->angle / 360);
break;
case MT_WALLSPIKEBASE:
if (!mobj->target)
{
P_RemoveMobj(mobj);
return;
}
mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|(mobj->target->frame & FF_FRAMEMASK);
#if 0
if (mobj->angle != mobj->target->angle + ANGLE_90) // reposition if not the correct angle
{
mobj_t* target = mobj->target; // shortcut
const fixed_t baseradius = target->radius - (target->scale/2); //FixedMul(FRACUNIT/2, target->scale);
P_UnsetThingPosition(mobj);
mobj->x = target->x - P_ReturnThrustX(target, target->angle, baseradius);
mobj->y = target->y - P_ReturnThrustY(target, target->angle, baseradius);
P_SetThingPosition(mobj);
mobj->angle = target->angle + ANGLE_90;
}
#endif
break;
case MT_ROCKCRUMBLE1:
case MT_ROCKCRUMBLE2:
case MT_ROCKCRUMBLE3:
@ -9238,25 +9282,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
switch (mobj->type)
{
case MT_WALLSPIKEBASE:
if (!mobj->target) {
P_RemoveMobj(mobj);
return false;
}
mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|(mobj->target->frame & FF_FRAMEMASK);
#if 0
if (mobj->angle != mobj->target->angle + ANGLE_90) // reposition if not the correct angle
{
mobj_t* target = mobj->target; // shortcut
const fixed_t baseradius = target->radius - (target->scale/2); //FixedMul(FRACUNIT/2, target->scale);
P_UnsetThingPosition(mobj);
mobj->x = target->x - P_ReturnThrustX(target, target->angle, baseradius);
mobj->y = target->y - P_ReturnThrustY(target, target->angle, baseradius);
P_SetThingPosition(mobj);
mobj->angle = target->angle + ANGLE_90;
}
#endif
break;
case MT_FALLINGROCK:
// Despawn rocks here in case zmovement code can't do so (blame slopes)
if (!mobj->momx && !mobj->momy && !mobj->momz
@ -9942,18 +9967,6 @@ static boolean P_FuseThink(mobj_t *mobj)
break;
case MT_METALSONIC_BATTLE:
break; // don't remove
case MT_SPIKE:
P_SetMobjState(mobj, mobj->state->nextstate);
mobj->fuse = mobj->info->speed;
if (mobj->spawnpoint)
mobj->fuse += mobj->spawnpoint->angle;
break;
case MT_WALLSPIKE:
P_SetMobjState(mobj, mobj->state->nextstate);
mobj->fuse = mobj->info->speed;
if (mobj->spawnpoint)
mobj->fuse += (mobj->spawnpoint->angle / 360);
break;
case MT_NIGHTSCORE:
P_RemoveMobj(mobj);
return false;
@ -10422,7 +10435,7 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing)
case MT_RING:
case MT_FLINGRING:
case MT_COIN:
case MT_FLINGCOIN:
@ -12956,17 +12969,18 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
// Pop up spikes!
if (mthing->options & MTF_OBJECTSPECIAL)
{
mobj->flags &= ~MF_SCENERY;
mobj->fuse = (16 - mthing->extrainfo)*(mthing->angle + mobj->info->speed)/16;
if (mthing->options & MTF_EXTRA)
P_SetMobjState(mobj, mobj->info->meleestate);
}
// Use per-thing collision for spikes if the deaf flag isn't checked.
if (!(mthing->options & MTF_AMBUSH) && !metalrecording)
else
mobj->flags |= MF_NOTHINK;
// no collision for spikes if the ambush flag is checked
if ((mthing->options & MTF_AMBUSH) || metalrecording)
{
P_UnsetThingPosition(mobj);
mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT);
mobj->flags |= MF_SOLID;
mobj->flags |= (MF_NOBLOCKMAP|MF_NOCLIPHEIGHT);
mobj->flags &= ~MF_SOLID;
P_SetThingPosition(mobj);
}
break;
@ -12974,20 +12988,20 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
// Pop up spikes!
if (mthing->options & MTF_OBJECTSPECIAL)
{
mobj->flags &= ~MF_SCENERY;
mobj->fuse = (16 - mthing->extrainfo)*((mthing->angle/360) + mobj->info->speed)/16;
if (mthing->options & MTF_EXTRA)
P_SetMobjState(mobj, mobj->info->meleestate);
}
// Use per-thing collision for spikes if the deaf flag isn't checked.
if (!(mthing->options & MTF_AMBUSH) && !metalrecording)
else
mobj->flags |= MF_NOTHINK;
// no collision for spikes if the ambush flag is checked
if ((mthing->options & MTF_AMBUSH) || metalrecording)
{
P_UnsetThingPosition(mobj);
mobj->flags &= ~(MF_NOBLOCKMAP | MF_NOCLIPHEIGHT);
mobj->flags |= MF_SOLID;
mobj->flags |= (MF_NOBLOCKMAP|MF_NOCLIPHEIGHT);
mobj->flags &= ~MF_SOLID;
P_SetThingPosition(mobj);
}
// spawn base
{
const angle_t mobjangle = FixedAngle(mthing->angle << FRACBITS); // the mobj's own angle hasn't been set quite yet so...
@ -13001,6 +13015,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
P_SetScale(base, mobj->scale);
P_SetTarget(&base->target, mobj);
P_SetTarget(&mobj->tracer, base);
if (!(mthing->options & MTF_OBJECTSPECIAL))
base->flags |= MF_NOTHINK;
}
break;
case MT_RING_BOX:

View file

@ -1603,7 +1603,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 = 0;
// not the default but the most probable
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0)
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0 || mobj->pmomz !=0)
diff |= MD_MOM;
if (mobj->radius != mobj->info->radius)
diff |= MD_RADIUS;
@ -1778,6 +1778,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEFIXED(save_p, mobj->momx);
WRITEFIXED(save_p, mobj->momy);
WRITEFIXED(save_p, mobj->momz);
WRITEFIXED(save_p, mobj->pmomz);
}
if (diff & MD_RADIUS)
WRITEFIXED(save_p, mobj->radius);
@ -2776,6 +2777,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->momx = READFIXED(save_p);
mobj->momy = READFIXED(save_p);
mobj->momz = READFIXED(save_p);
mobj->pmomz = READFIXED(save_p);
} // otherwise they're zero, and the memset took care of it
if (diff & MD_RADIUS)

View file

@ -3064,48 +3064,55 @@ static void P_AddBinaryMapTags(void)
{
size_t i;
for (i = 0; i < numlines; i++)
{
// 96: Apply Tag to Tagged Sectors
for (i = 0; i < numlines; i++) {
// 97: Apply Tag to Front Sector
// 98: Apply Tag to Back Sector
// 99: Apply Tag to Front and Back Sectors
if (lines[i].special == 96) {
size_t j;
mtag_t tag = Tag_FGet(&lines[i].frontsector->tags);
mtag_t target_tag = Tag_FGet(&lines[i].tags);
mtag_t offset_tags[4];
memset(offset_tags, 0, sizeof(mtag_t)*4);
if (lines[i].flags & ML_EFFECT6) {
offset_tags[0] = (INT32)sides[lines[i].sidenum[0]].textureoffset / FRACUNIT;
offset_tags[1] = (INT32)sides[lines[i].sidenum[0]].rowoffset / FRACUNIT;
}
if (lines[i].flags & ML_TFERLINE) {
offset_tags[2] = (INT32)sides[lines[i].sidenum[1]].textureoffset / FRACUNIT;
offset_tags[3] = (INT32)sides[lines[i].sidenum[1]].rowoffset / FRACUNIT;
}
if (lines[i].special == 97 || lines[i].special == 99)
P_AddBinaryMapTagsFromLine(lines[i].frontsector, &lines[i]);
if (lines[i].special == 98 || lines[i].special == 99)
P_AddBinaryMapTagsFromLine(lines[i].backsector, &lines[i]);
}
for (j = 0; j < numsectors; j++) {
boolean matches_target_tag = target_tag && Tag_Find(&sectors[j].tags, target_tag);
size_t k; for (k = 0; k < 4; k++) {
if (lines[i].flags & ML_EFFECT5) {
if (matches_target_tag || (offset_tags[k] && Tag_Find(&sectors[j].tags, offset_tags[k]))) {
Tag_Add(&sectors[j].tags, tag);
break;
}
} else if (matches_target_tag) {
if (k == 0)
Tag_Add(&sectors[j].tags, tag);
if (offset_tags[k])
Tag_Add(&sectors[j].tags, offset_tags[k]);
// Run this loop after the 97-99 loop to ensure that 96 can search through all of the
// 97-99-applied tags.
for (i = 0; i < numlines; i++) {
size_t j;
mtag_t tag, target_tag;
mtag_t offset_tags[4];
// 96: Apply Tag to Tagged Sectors
if (lines[i].special != 96)
continue;
tag = Tag_FGet(&lines[i].frontsector->tags);
target_tag = Tag_FGet(&lines[i].tags);
memset(offset_tags, 0, sizeof(mtag_t)*4);
if (lines[i].flags & ML_EFFECT6) {
offset_tags[0] = (INT32)sides[lines[i].sidenum[0]].textureoffset / FRACUNIT;
offset_tags[1] = (INT32)sides[lines[i].sidenum[0]].rowoffset / FRACUNIT;
}
if (lines[i].flags & ML_TFERLINE) {
offset_tags[2] = (INT32)sides[lines[i].sidenum[1]].textureoffset / FRACUNIT;
offset_tags[3] = (INT32)sides[lines[i].sidenum[1]].rowoffset / FRACUNIT;
}
for (j = 0; j < numsectors; j++) {
boolean matches_target_tag = target_tag && Tag_Find(&sectors[j].tags, target_tag);
size_t k;
for (k = 0; k < 4; k++) {
if (lines[i].flags & ML_EFFECT5) {
if (matches_target_tag || (offset_tags[k] && Tag_Find(&sectors[j].tags, offset_tags[k]))) {
Tag_Add(&sectors[j].tags, tag);
break;
}
} else if (matches_target_tag) {
if (k == 0)
Tag_Add(&sectors[j].tags, tag);
if (offset_tags[k])
Tag_Add(&sectors[j].tags, offset_tags[k]);
}
}
} else {
if (lines[i].special == 97 || lines[i].special == 99)
P_AddBinaryMapTagsFromLine(lines[i].frontsector, &lines[i]);
if (lines[i].special == 98 || lines[i].special == 99)
P_AddBinaryMapTagsFromLine(lines[i].backsector, &lines[i]);
}
}
}

View file

@ -11588,7 +11588,7 @@ void P_PlayerThink(player_t *player)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator || players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN)
if (!playeringame[i] || players[i].spectator || players[i].bot)
continue;
if (players[i].lives <= 0)
continue;
@ -11620,7 +11620,7 @@ void P_PlayerThink(player_t *player)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator || players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN)
if (!playeringame[i] || players[i].spectator || players[i].bot)
continue;
if (players[i].quittime > 30 * TICRATE)
continue;
@ -12206,7 +12206,7 @@ void P_PlayerThink(player_t *player)
player->losstime--;
// Flash player after being hit.
if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1))
if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1) && player->playerstate == PST_LIVE)
player->mo->flags2 |= MF2_DONTDRAW;
else
player->mo->flags2 &= ~MF2_DONTDRAW;
@ -12744,12 +12744,12 @@ void P_PlayerAfterThink(player_t *player)
if (!ptera->movefactor)
goto dropoff;
if (ptera->cusval >= 50)
if (ptera->cusval >= 30)
{
player->powers[pw_carry] = CR_NONE;
P_SetTarget(&player->mo->tracer, NULL);
P_KillMobj(ptera, player->mo, player->mo, 0);
player->mo->momz = 9*FRACUNIT;
P_SetObjectMomZ(player->mo, 12*FRACUNIT, false);
player->pflags |= PF_APPLYAUTOBRAKE|PF_JUMPED|PF_THOKKED;
P_SetMobjState(player->mo, S_PLAY_ROLL);
break;

View file

@ -2291,7 +2291,7 @@ static void ST_drawTextHUD(void)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
if (!playeringame[i] || players[i].spectator || players[i].bot)
continue;
if (players[i].lives <= 0)
continue;

View file

@ -2023,7 +2023,7 @@ static void Y_AwardCoopBonuses(void)
for (i = 0; i < MAXPLAYERS; ++i)
{
if (!playeringame[i] || players[i].lives < 1) // not active or game over
if (!playeringame[i] || players[i].lives < 1 || players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN) // not active, game over or tails bot
bonusnum = 0; // all null
else
bonusnum = mapheaderinfo[prevmap]->bonustype + 1; // -1 is none
@ -2073,7 +2073,7 @@ static void Y_AwardSpecialStageBonus(void)
{
oldscore = players[i].score;
if (!playeringame[i] || players[i].lives < 1) // not active or game over
if (!playeringame[i] || players[i].lives < 1 || players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN) // not active, game over or tails bot
{
Y_SetNullBonus(&players[i], &localbonuses[0]);
Y_SetNullBonus(&players[i], &localbonuses[1]);