diff --git a/src/b_bot.c b/src/b_bot.c index cdd74fc0757522ac2a7c30dfe3dec50237c446ea..bf2dbbb68586aab8390557568622d2e9e6f89e0a 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -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) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index cca3102d085aac427b5a3469dd00f3085a3fee3d..fe7e7678fe447cfc186b9eaf4134cb6eeeb6db27 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -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); diff --git a/src/deh_tables.c b/src/deh_tables.c index e07d44453b24a1f7315c32dd33f10d916dd445fa..cfc98f631e9d475f403e104425eae189949157bf 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -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}, diff --git a/src/g_game.c b/src/g_game.c index 3955834b2170fa203222a5c76f8f9ead60e74fa6..e671eb2d757196466abd0edfe14a8d4b363061f8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -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; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 12972458581e5d3162a02c586b3e65018308f1ea..cf7118fbe0694c206a2d26497196f2cc81d5787f 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -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); diff --git a/src/info.c b/src/info.c index f56e5d78e3e786b33806a1a596f0051a182144fd..331e114b6381cf2161fb83d121ec2b77c9b7853b 100644 --- a/src/info.c +++ b/src/info.c @@ -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 }, diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index a72b22b5a62b953bbccde13f271c76fb6e24cad1..287a185bc36b06b5d04cc18d5667b9e869047452 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -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); diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index e6f8c98c1371e81295a64d8d14a4039239bc4522..bd9218a3d54bc076093c8596ae502c0075464602 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -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}, diff --git a/src/m_menu.c b/src/m_menu.c index 30772ab8fdc69ae81519d5c854ce1777f1305052..85d093b943e22a50add4bb3aa111b72fc7a8ef1f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -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; } diff --git a/src/p_floor.c b/src/p_floor.c index 263644f702bb7a8a26f66c6989b57deb2b225ccc..dd9331e73ffdc671252d10d4fbf0b196dc38aa37 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -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; } } diff --git a/src/p_local.h b/src/p_local.h index 1fcd3050d92fde6fd1056f86d81137be89b93902..28a77afe5c9a5022a5e5f92641df34806f32b91d 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -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 diff --git a/src/p_map.c b/src/p_map.c index 836e75c4e8bb08937e79fadf5f572125c9841b90..329224d0bd353c8a345f5483ffd5142695b9f0e3 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -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; diff --git a/src/p_mobj.c b/src/p_mobj.c index 83f9ebf3c7a5f27d18a65416900be70df38e911b..39c6731b81ab41b378f748eb42fe28762642c350 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -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: diff --git a/src/p_saveg.c b/src/p_saveg.c index 1270064c01f1494abc582fc7a61c8a80791f4635..722340f41f6c4fe86f2a70ebfd597bb0a142c290 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -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) diff --git a/src/p_setup.c b/src/p_setup.c index 6f06abf1b2fabd75bfb1815ba0d042bbb2ae21d3..4f21922a0c57b77bd9870814c8160cf8c46171d0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -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(§ors[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(§ors[j].tags, offset_tags[k]))) { - Tag_Add(§ors[j].tags, tag); - break; - } - } else if (matches_target_tag) { - if (k == 0) - Tag_Add(§ors[j].tags, tag); - if (offset_tags[k]) - Tag_Add(§ors[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(§ors[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(§ors[j].tags, offset_tags[k]))) { + Tag_Add(§ors[j].tags, tag); + break; } + } else if (matches_target_tag) { + if (k == 0) + Tag_Add(§ors[j].tags, tag); + if (offset_tags[k]) + Tag_Add(§ors[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]); } } } diff --git a/src/p_user.c b/src/p_user.c index f21118a81fb2f4f088758a9b92ac52444d289e77..9b48442fe2bf76c5adf9dffa84e262380a0dbe6b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -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; diff --git a/src/st_stuff.c b/src/st_stuff.c index a328d669e51169ba18d8ae8d046774d3b298eed3..ebf188a06f78978e2039ff1ef053c65be38a72c9 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -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; diff --git a/src/y_inter.c b/src/y_inter.c index f24436d4082e645fbbd9fe103a7ed33e741a18b7..288a821e6f33209408ce708b1666bc93aabee93d 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -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]);