From f9ea6833129ccf884ab2f0b3d9fb3d9d0e37d44f Mon Sep 17 00:00:00 2001 From: James Date: Tue, 22 Oct 2019 08:45:38 -0400 Subject: [PATCH 01/19] P_PlayerTouchingSectorSpecial turned into P_MobjTouchingSectorSpecial --- src/k_kart.c | 27 ++++++---------------- src/lua_baselib.c | 12 +++++----- src/p_floor.c | 2 +- src/p_inter.c | 2 +- src/p_map.c | 32 ++++++------------------- src/p_mobj.c | 26 +++++---------------- src/p_spec.c | 59 +++++++++++++++++++++++++---------------------- src/p_spec.h | 2 +- 8 files changed, 61 insertions(+), 101 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 230662d2a..6c268269d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1533,20 +1533,16 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) \return boolean */ -static UINT8 K_CheckOffroadCollide(mobj_t *mo, sector_t *sec) +static UINT8 K_CheckOffroadCollide(mobj_t *mo) { UINT8 i; - sector_t *sec2; I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); - sec2 = P_ThingOnSpecial3DFloor(mo); - for (i = 2; i < 5; i++) { - if ((sec2 && GETSECSPECIAL(sec2->special, 1) == i) - || (P_IsObjectOnRealGround(mo, sec) && GETSECSPECIAL(sec->special, 1) == i)) + if (P_MobjTouchingSectorSpecial(mo, 1, i)) return i-1; } @@ -1561,25 +1557,16 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo, sector_t *sec) */ static void K_UpdateOffroad(player_t *player) { - fixed_t offroad; - sector_t *nextsector = R_PointInSubsector( - player->mo->x + player->mo->momx*2, player->mo->y + player->mo->momy*2)->sector; - UINT8 offroadstrength = K_CheckOffroadCollide(player->mo, nextsector); + fixed_t offroadstrength = (K_CheckOffroadCollide(player->mo) << FRACBITS); // If you are in offroad, a timer starts. if (offroadstrength) { - if (K_CheckOffroadCollide(player->mo, player->mo->subsector->sector) && player->kartstuff[k_offroad] == 0) - player->kartstuff[k_offroad] = TICRATE; + if (player->kartstuff[k_offroad] < offroadstrength) + player->kartstuff[k_offroad] += offroadstrength / TICRATE; - if (player->kartstuff[k_offroad] > 0) - { - offroad = (offroadstrength << FRACBITS) / TICRATE; - player->kartstuff[k_offroad] += offroad; - } - - if (player->kartstuff[k_offroad] > (offroadstrength << FRACBITS)) - player->kartstuff[k_offroad] = (offroadstrength << FRACBITS); + if (player->kartstuff[k_offroad] > offroadstrength) + player->kartstuff[k_offroad] = offroadstrength; } else player->kartstuff[k_offroad] = 0; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 7464743c3..3d836dad2 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1313,15 +1313,15 @@ static int lib_pExplodeMissile(lua_State *L) return 0; } -static int lib_pPlayerTouchingSectorSpecial(lua_State *L) +static int lib_pMobjTouchingSectorSpecial(lua_State *L) { - player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); INT32 section = (INT32)luaL_checkinteger(L, 2); INT32 number = (INT32)luaL_checkinteger(L, 3); //HUDSAFE - if (!player) - return LUA_ErrInvalid(L, "player_t"); - LUA_PushUserdata(L, P_PlayerTouchingSectorSpecial(player, section, number), META_SECTOR); + if (!mo) + return LUA_ErrInvalid(L, "mobj_t"); + LUA_PushUserdata(L, P_MobjTouchingSectorSpecial(mo, section, number), META_SECTOR); return 1; } @@ -2736,7 +2736,7 @@ static luaL_Reg lib[] = { {"P_SetMobjStateNF",lib_pSetMobjStateNF}, {"P_DoSuperTransformation",lib_pDoSuperTransformation}, {"P_ExplodeMissile",lib_pExplodeMissile}, - {"P_PlayerTouchingSectorSpecial",lib_pPlayerTouchingSectorSpecial}, + {"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial}, {"P_FindSpecialLineFromTag",lib_pFindSpecialLineFromTag}, {"P_SwitchWeather",lib_pSwitchWeather}, {"P_LinedefExecute",lib_pLinedefExecute}, diff --git a/src/p_floor.c b/src/p_floor.c index ccbfd6eae..a4e4f2747 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2275,7 +2275,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) continue; if (!(players[i].mo->subsector->sector == sec - || P_PlayerTouchingSectorSpecial(&players[i], 2, (GETSECSPECIAL(sec->special, 2))) == sec)) + || P_MobjTouchingSectorSpecial(players[i].mo, 2, (GETSECSPECIAL(sec->special, 2))) == sec)) continue; if (floortouch == true && P_IsObjectOnRealGround(players[i].mo, sec)) diff --git a/src/p_inter.c b/src/p_inter.c index 7a975951c..a1a44c998 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -925,7 +925,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->fuse = 1; special->flags2 |= MF2_JUSTATTACKED; - if (!P_PlayerTouchingSectorSpecial(player, 4, 2 + flagteam)) + if (!P_MobjTouchingSectorSpecial(player->mo, 4, 2 + flagteam)) { CONS_Printf(M_GetText("%s returned the %c%s%c to base.\n"), plname, flagcolor, flagtext, 0x80); diff --git a/src/p_map.c b/src/p_map.c index d4f2a94fa..22e624311 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2789,25 +2789,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) //All things are affected by their scale. fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale); - if (thing->player) - { - // If using type Section1:13, double the maxstep. - if (P_PlayerTouchingSectorSpecial(thing->player, 1, 13) - || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 13) - maxstep <<= 1; - // If using type Section1:12, no maxstep. For ledges you don't want the player to climb! (see: Egg Zeppelin & SMK port walls) - else if (P_PlayerTouchingSectorSpecial(thing->player, 1, 12) - || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 12) - maxstep = 0; - - // Don't 'step up' while springing, - // Only step up "if needed". - /* // SRB2kart - don't need - if (thing->state == &states[S_PLAY_SPRING] - && P_MobjFlip(thing)*thing->momz > FixedMul(FRACUNIT, thing->scale)) - maxstep = 0; - */ - } + // If using type Section1:13, double the maxstep. + if (P_MobjTouchingSectorSpecial(thing, 1, 13)) + maxstep <<= 1; + // If using type Section1:12, no maxstep. For short walls, like Egg Zeppelin + else if (P_MobjTouchingSectorSpecial(thing, 1, 12)) + maxstep = 0; if (thing->type == MT_SKIM) maxstep = 0; @@ -2830,12 +2817,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) return false; // mobj must lower itself to fit // Ramp test - if (maxstep > 0 && !( - thing->player && ( - P_PlayerTouchingSectorSpecial(thing->player, 1, 14) - || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14) - ) - ) + if ((maxstep > 0) && !(P_MobjTouchingSectorSpecial(thing, 1, 14))) { // If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS // step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more. diff --git a/src/p_mobj.c b/src/p_mobj.c index f54eca41e..1fd846ff1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8355,14 +8355,8 @@ void P_MobjThinker(mobj_t *mobj) P_Thrust(mobj, mobj->angle, thrustamount); - if (grounded) - { - sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) - || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) - && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) - K_DoPogoSpring(mobj, 0, 1); - } + if (P_MobjTouchingSectorSpecial(mobj, 3, 1)) + K_DoPogoSpring(mobj, 0, 1); if (mobj->threshold > 0) mobj->threshold--; @@ -8374,7 +8368,6 @@ void P_MobjThinker(mobj_t *mobj) } case MT_JAWZ: { - sector_t *sec2; mobj_t *ghost = P_SpawnGhostMobj(mobj); if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player) @@ -8392,10 +8385,7 @@ void P_MobjThinker(mobj_t *mobj) K_DriftDustHandling(mobj); - sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) - || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) - && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) + if (P_MobjTouchingSectorSpecial(mobj, 3, 1)) K_DoPogoSpring(mobj, 0, 1); break; @@ -9602,13 +9592,9 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_BLUEFLAG: case MT_REDFLAG: - { - sector_t *sec2; - sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 4) == 2) || (GETSECSPECIAL(mobj->subsector->sector->special, 4) == 2)) - mobj->fuse = 1; // Return to base. - break; - } + if (P_MobjTouchingSectorSpecial(mobj, 4, 2)) + mobj->fuse = 1; // Return to base. + break; case MT_CANNONBALL: #ifdef FLOORSPLATS R_AddFloorSplat(mobj->tracer->subsector, mobj->tracer, "TARGET", mobj->tracer->x, diff --git a/src/p_spec.c b/src/p_spec.c index 93e88e2ce..7786329ec 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3361,7 +3361,7 @@ boolean P_IsFlagAtBase(mobjtype_t flag) } // -// P_PlayerTouchingSectorSpecial +// P_MobjTouchingSectorSpecial // // Replaces the old player->specialsector. // This allows a player to touch more than @@ -3371,20 +3371,23 @@ boolean P_IsFlagAtBase(mobjtype_t flag) // the particular type that it finds. // Returns NULL if it doesn't find it. // -sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number) +// Sal: There was absolutely no reason for +// this to be a player_t only function. +// +sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number) { msecnode_t *node; ffloor_t *rover; - if (!player->mo) + if (!mo) return NULL; // Check default case first - if (GETSECSPECIAL(player->mo->subsector->sector->special, section) == number) - return player->mo->subsector->sector; + if (GETSECSPECIAL(mo->subsector->sector->special, section) == number) + return mo->subsector->sector; // Hmm.. maybe there's a FOF that has it... - for (rover = player->mo->subsector->sector->ffloors; rover; rover = rover->next) + for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) { fixed_t topheight, bottomheight; @@ -3394,37 +3397,38 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n if (!(rover->flags & FF_EXISTS)) continue; - topheight = P_GetSpecialTopZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector); - bottomheight = P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector); + topheight = P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector); + bottomheight = P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector); // Check the 3D floor's type... - if (rover->flags & FF_BLOCKPLAYER) + if (((rover->flags & FF_BLOCKPLAYER) && mo->player) + || ((rover->flags & FF_BLOCKOTHERS) && !mo->player)) { // Thing must be on top of the floor to be affected... if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) { - if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight) + if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != topheight) continue; } else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) { - if (!(player->mo->eflags & MFE_VERTICALFLIP) - || player->mo->z + player->mo->height != bottomheight) + if (!(mo->eflags & MFE_VERTICALFLIP) + || mo->z + mo->height != bottomheight) continue; } else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) { - if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == bottomheight) - || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == topheight))) + if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottomheight) + || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == topheight))) continue; } } else { // Water and DEATH FOG!!! heh - if (player->mo->z > topheight || (player->mo->z + player->mo->height) < bottomheight) + if (mo->z > topheight || (mo->z + mo->height) < bottomheight) continue; } @@ -3432,13 +3436,13 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n return rover->master->frontsector; } - for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) { if (GETSECSPECIAL(node->m_sector->special, section) == number) { // This sector has the special we're looking for, but // are we allowed to touch it? - if (node->m_sector == player->mo->subsector->sector + if (node->m_sector == mo->subsector->sector || (node->m_sector->flags & SF_TRIGGERSPECIAL_TOUCH)) return node->m_sector; } @@ -3454,42 +3458,43 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n if (!(rover->flags & FF_EXISTS)) continue; - topheight = P_GetSpecialTopZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector); - bottomheight = P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector); + topheight = P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector); + bottomheight = P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector); // Check the 3D floor's type... - if (rover->flags & FF_BLOCKPLAYER) + if (((rover->flags & FF_BLOCKPLAYER) && mo->player) + || ((rover->flags & FF_BLOCKOTHERS) && !mo->player)) { // Thing must be on top of the floor to be affected... if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) { - if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight) + if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != topheight) continue; } else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) { - if (!(player->mo->eflags & MFE_VERTICALFLIP) - || player->mo->z + player->mo->height != bottomheight) + if (!(mo->eflags & MFE_VERTICALFLIP) + || mo->z + mo->height != bottomheight) continue; } else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) { - if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == bottomheight) - || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == topheight))) + if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottomheight) + || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == topheight))) continue; } } else { // Water and DEATH FOG!!! heh - if (player->mo->z > topheight || (player->mo->z + player->mo->height) < bottomheight) + if (mo->z > topheight || (mo->z + mo->height) < bottomheight) continue; } // This FOF has the special we're looking for, but are we allowed to touch it? - if (node->m_sector == player->mo->subsector->sector + if (node->m_sector == mo->subsector->sector || (rover->master->frontsector->flags & SF_TRIGGERSPECIAL_TOUCH)) return rover->master->frontsector; } diff --git a/src/p_spec.h b/src/p_spec.h index b604ac951..8431fcc75 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -37,7 +37,7 @@ void P_SpawnSpecials(INT32 fromnetsave); // every tic void P_UpdateSpecials(void); -sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number); +sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number); void P_PlayerInSpecialSector(player_t *player); void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector); From 522959e762711247098764f784f92078f35b5485 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 26 Oct 2019 23:11:19 -0400 Subject: [PATCH 02/19] Disable charging drift sparks in bounce pad state --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 230662d2a..8db2b0d81 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6609,7 +6609,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } } - K_KartDrift(player, onground); + K_KartDrift(player, P_IsObjectOnGround(player->mo)); // Not using onground, since we don't want this affected by spring pads // Quick Turning // You can't turn your kart when you're not moving. From 88cb623c2a7f719d21c09436eacd8d1f4c69262a Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 8 Nov 2019 23:25:46 -0500 Subject: [PATCH 03/19] 3D signpost --- src/dehacked.c | 27 +++-------- src/info.c | 58 ++++++++++++++---------- src/info.h | 27 +++-------- src/p_enemy.c | 33 -------------- src/p_mobj.c | 118 +++++++++++++++++++++++++++++++++++++++---------- src/p_spec.c | 97 +++++++++++++++++++++++++++++++--------- 6 files changed, 213 insertions(+), 147 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 5f9249d89..7687803d3 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1774,7 +1774,6 @@ static actionpointer_t actionpointers[] = {{A_GrenadeRing}, "A_GRENADERING"}, // SRB2kart {{A_SetSolidSteam}, "A_SETSOLIDSTEAM"}, {{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"}, - {{A_SignPlayer}, "A_SIGNPLAYER"}, {{A_OverlayThink}, "A_OVERLAYTHINK"}, {{A_JetChase}, "A_JETCHASE"}, {{A_JetbThink}, "A_JETBTHINK"}, @@ -4887,27 +4886,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BUBBLES2", // Level End Sign - "S_SIGN1", - "S_SIGN2", - "S_SIGN3", - "S_SIGN4", - "S_SIGN5", - "S_SIGN6", - "S_SIGN7", - "S_SIGN8", - "S_SIGN9", - "S_SIGN10", - "S_SIGN11", - "S_SIGN12", - "S_SIGN13", - "S_SIGN14", - "S_SIGN15", - "S_SIGN16", - "S_SIGN17", - "S_SIGN18", - "S_SIGN19", - "S_SIGN20", - "S_SIGN_END", + "S_SIGN_POLE", + "S_SIGN_BACK", + "S_SIGN_SIDE", + "S_SIGN_FACE", // Steam Riser "S_STEAM1", @@ -7363,6 +7345,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Interactive Objects "MT_BUBBLES", // Bubble source "MT_SIGN", // Level end sign + "MT_SIGN_PIECE", "MT_SPIKEBALL", // Spike Ball "MT_SPECIALSPIKEBALL", "MT_SPINFIRE", diff --git a/src/info.c b/src/info.c index 4f448cc00..7476a9344 100644 --- a/src/info.c +++ b/src/info.c @@ -193,7 +193,7 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, 18, {NULL}, 0, 4, S_NULL}, // S_PLAY_ICON3 // Level end sign (uses player sprite) - {SPR_PLAY, 18, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN S + {SPR_PLAY, 18|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_PLAY_SIGN}, // S_PLAY_SIGN // Blue Crawla {SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND @@ -1063,27 +1063,10 @@ state_t states[NUMSTATES] = {SPR_BUBL, 1, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES2 // Level End Sign - {SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN2}, // S_SIGN1 - {SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN3}, // S_SIGN2 - {SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN4}, // S_SIGN3 - {SPR_SIGN, 3, 1, {NULL}, 0, 0, S_SIGN5}, // S_SIGN4 - {SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN6}, // S_SIGN5 - {SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN7}, // S_SIGN6 - {SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN8}, // S_SIGN7 - {SPR_SIGN, 4, 1, {NULL}, 0, 0, S_SIGN9}, // S_SIGN8 - {SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN10}, // S_SIGN9 - {SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN11}, // S_SIGN10 - {SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN12}, // S_SIGN11 - {SPR_SIGN, 5, 1, {NULL}, 0, 0, S_SIGN13}, // S_SIGN12 - {SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN14}, // S_SIGN13 - {SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN15}, // S_SIGN14 - {SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN16}, // S_SIGN15 - {SPR_SIGN, 6, 1, {NULL}, 0, 0, S_SIGN17}, // S_SIGN16 - {SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN18}, // S_SIGN17 - {SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN19}, // S_SIGN18 - {SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN20}, // S_SIGN19 - {SPR_SIGN, 7, 1, {NULL}, 0, 0, S_SIGN1}, // S_SIGN20 - {SPR_SIGN, 8, -1, {A_SignPlayer}, 0, 0, S_NULL}, // S_SIGN_END + {SPR_SIGN, 0, -1, {NULL}, 0, 0, S_SIGN_POLE}, // S_SIGN_POLE + {SPR_SIGN, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_SIGN_BACK}, // S_SIGN_BACK + {SPR_SIGN, 2|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_SIGN_SIDE}, // S_SIGN_SIDE + {SPR_SIGN, 3|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_SIGN_FACE}, // S_SIGN_FACE // Steam Riser {SPR_STEM, 0, 2, {A_SetSolidSteam}, 0, 0, S_STEAM2}, // S_STEAM1 @@ -6434,7 +6417,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 501, // doomednum S_INVISIBLE, // spawnstate 1000, // spawnhealth - S_PLAY_SIGN, // seestate + S_NULL, // seestate sfx_s3kb8, // seesound 8, // reactiontime sfx_s3k7e, // attacksound @@ -6448,7 +6431,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 8, // speed 8*FRACUNIT, // radius - 32*FRACUNIT, // height + 48*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -6457,6 +6440,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SIGN_PIECE + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NOTHINK|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_SPIKEBALL -1, // doomednum S_SPIKEBALL1, // spawnstate diff --git a/src/info.h b/src/info.h index 27488d916..f3450ff11 100644 --- a/src/info.h +++ b/src/info.h @@ -63,7 +63,6 @@ void A_ThrownRing(); // Sparkle trail for red ring void A_GrenadeRing(); // SRB2kart void A_SetSolidSteam(); void A_UnsetSolidSteam(); -void A_SignPlayer(); void A_OverlayThink(); void A_JetChase(); void A_JetbThink(); // Jetty-Syn Bomber Thinker @@ -1776,27 +1775,10 @@ typedef enum state S_BUBBLES2, // Level End Sign - S_SIGN1, - S_SIGN2, - S_SIGN3, - S_SIGN4, - S_SIGN5, - S_SIGN6, - S_SIGN7, - S_SIGN8, - S_SIGN9, - S_SIGN10, - S_SIGN11, - S_SIGN12, - S_SIGN13, - S_SIGN14, - S_SIGN15, - S_SIGN16, - S_SIGN17, - S_SIGN18, - S_SIGN19, - S_SIGN20, - S_SIGN_END, + S_SIGN_POLE, + S_SIGN_BACK, + S_SIGN_SIDE, + S_SIGN_FACE, // Steam Riser S_STEAM1, @@ -4284,6 +4266,7 @@ typedef enum mobj_type // Interactive Objects MT_BUBBLES, // Bubble source MT_SIGN, // Level end sign + MT_SIGN_PIECE, MT_SPIKEBALL, // Spike Ball MT_SPECIALSPIKEBALL, MT_SPINFIRE, diff --git a/src/p_enemy.c b/src/p_enemy.c index 76f6b3159..64a3ee12e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -117,7 +117,6 @@ void A_ThrownRing(mobj_t *actor); void A_GrenadeRing(mobj_t *actor); void A_SetSolidSteam(mobj_t *actor); void A_UnsetSolidSteam(mobj_t *actor); -void A_SignPlayer(mobj_t *actor); void A_OverlayThink(mobj_t *actor); void A_JetChase(mobj_t *actor); void A_JetbThink(mobj_t *actor); @@ -4180,38 +4179,6 @@ void A_UnsetSolidSteam(mobj_t *actor) actor->flags |= MF_NOCLIP; } -// Function: A_SignPlayer -// -// Description: Changes the state of a level end sign to reflect the player that hit it. -// -// var1 = unused -// var2 = unused -// -void A_SignPlayer(mobj_t *actor) -{ - mobj_t *ov; -#ifdef HAVE_BLUA - if (LUA_CallAction("A_SignPlayer", actor)) - return; -#endif - if (!actor->target) - return; - - if (!actor->target->player) - return; - - // Set the sign to be an appropriate background color for this player's skincolor. - actor->color = KartColor_Opposite[actor->target->player->skincolor*2]; - actor->frame += KartColor_Opposite[actor->target->player->skincolor*2+1]; - - // spawn an overlay of the player's face. - ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY); - P_SetTarget(&ov->target, actor); - ov->color = actor->target->player->skincolor; - ov->skin = &skins[actor->target->player->skin]; - P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN -} - // Function: A_OverlayThink // // Description: Moves the overlay to the position of its target. diff --git a/src/p_mobj.c b/src/p_mobj.c index b220ff4e6..ffdbebf4a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1329,9 +1329,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_JAWZ_DUD: gravityadd = (5*gravityadd)/2; break; - case MT_SIGN: - gravityadd /= 8; - break; case MT_KARMAFIREWORK: gravityadd /= 3; break; @@ -8957,31 +8954,104 @@ void P_MobjThinker(mobj_t *mobj) } break; case MT_SIGN: // Kart's unique sign behavior - if (mobj->movecount) + if (mobj->movecount != 0) { - if (mobj->z <= mobj->movefactor) + mobj_t *cur = mobj->hnext; + SINT8 newskin = -1; + UINT8 newcolor = SKINCOLOR_NONE; + angle_t endangle = FixedAngle(mobj->extravalue1 << FRACBITS); + + if (mobj->movecount == 1) { - P_SetMobjState(mobj, S_SIGN_END); - if (mobj->info->attacksound) - S_StartSound(mobj, mobj->info->attacksound); - mobj->flags |= MF_NOGRAVITY; // ? - mobj->flags &= ~MF_NOCLIPHEIGHT; - mobj->z = mobj->movefactor; - mobj->movecount = 0; - } - else - { - P_SpawnMobj(mobj->x + (P_RandomRange(-48,48)*mobj->scale), - mobj->y + (P_RandomRange(-48,48)*mobj->scale), - mobj->z + (24*mobj->scale) + (P_RandomRange(-8,8)*mobj->scale), - MT_SIGNSPARKLE); - mobj->flags &= ~MF_NOGRAVITY; - if (abs(mobj->z - mobj->movefactor) <= (512*mobj->scale) && !mobj->cvmem) + if (mobj->z + mobj->momz <= mobj->movefactor) { - if (mobj->info->seesound) - S_StartSound(mobj, mobj->info->seesound); - mobj->cvmem = 1; + if (mobj->info->attacksound) + S_StartSound(mobj, mobj->info->attacksound); + + mobj->z = mobj->movefactor; + mobj->momz = 0; + mobj->movecount = 2; + + newskin = ((skin_t*)mobj->target->skin)-skins; + newcolor = mobj->target->player->skincolor; } + else + { + fixed_t g = (6*mobj->scale); + UINT16 ticstilimpact = abs(mobj->z - mobj->movefactor) / g; + + P_SpawnMobj( + mobj->x + FixedMul(48*mobj->scale, FINECOSINE(mobj->angle >> ANGLETOFINESHIFT)), + mobj->y + FixedMul(48*mobj->scale, FINESINE(mobj->angle >> ANGLETOFINESHIFT)), + mobj->z + ((24 + ((leveltime % 4) * 8)) * mobj->scale), + MT_SIGNSPARKLE + ); + + if (ticstilimpact == (3*TICRATE/2)) + { + if (mobj->info->seesound) + S_StartSound(mobj, mobj->info->seesound); + } + + mobj->angle += ANGLE_45; + mobj->momz = -g; + + if (mobj->angle == endangle + ANGLE_180) + { + if (ticstilimpact <= 8) + { + newskin = ((skin_t*)mobj->target->skin)-skins; + newcolor = mobj->target->player->skincolor; + } + else + { + newskin = leveltime % numskins; + newcolor = skins[newskin].prefcolor; + } + } + } + } + else if (mobj->movecount == 2) + { + if (mobj->angle != endangle) + mobj->angle += ANGLE_11hh; + } + + while (cur && !P_MobjWasRemoved(cur)) + { + fixed_t amt = cur->extravalue1 * mobj->scale; + angle_t dir = mobj->angle + (cur->extravalue2 * ANGLE_90); + fixed_t z = mobj->z + (23*mobj->scale); + + if (cur->state == &states[S_SIGN_FACE]) + { + if (newcolor != SKINCOLOR_NONE) + { + cur->color = KartColor_Opposite[newcolor*2]; + cur->frame = states[S_SIGN_FACE].frame + KartColor_Opposite[newcolor*2+1]; + } + } + else if (cur->state == &states[S_PLAY_SIGN]) + { + z += (5*mobj->scale); + amt += 1; + + if (newskin != -1) + cur->skin = &skins[newskin]; + + if (newcolor != SKINCOLOR_NONE) + cur->color = newcolor; + } + + P_TeleportMove( + cur, + mobj->x + FixedMul(amt, FINECOSINE(dir >> ANGLETOFINESHIFT)), + mobj->y + FixedMul(amt, FINESINE(dir >> ANGLETOFINESHIFT)), + z + ); + cur->angle = dir + ANGLE_90; + + cur = cur->hnext; } } break; diff --git a/src/p_spec.c b/src/p_spec.c index 93e88e2ce..0eb618c45 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3232,6 +3232,76 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } } +static void P_SetupSignObject(mobj_t *sign, mobj_t *pmo) +{ + mobj_t *cur = sign, *prev = NULL; + + // Setup the sign itself + P_SetTarget(&sign->target, pmo); + P_SetMobjState(sign, S_SIGN_POLE); + + sign->movefactor = sign->z; + sign->z += (768*sign->scale) * P_MobjFlip(sign); + sign->movecount = 1; + sign->extravalue1 = AngleFixed(sign->angle) >> FRACBITS; + + // Setup the overlay pieces + // Front + cur->hnext = P_SpawnMobj(sign->x, sign->y, sign->z, MT_SIGN_PIECE); + P_SetTarget(&cur->hnext->target, sign); + P_SetMobjState(cur->hnext, S_SIGN_FACE); + cur->hnext->extravalue1 = 6; + cur->hnext->extravalue2 = 2; + + prev = cur; + cur = cur->hnext; + cur->hprev = prev; + + // Player icon + cur->hnext = P_SpawnMobj(sign->x, sign->y, sign->z, MT_SIGN_PIECE); + P_SetTarget(&cur->hnext->target, sign); + cur->hnext->skin = pmo->skin; + P_SetMobjState(cur->hnext, S_PLAY_SIGN); + cur->hnext->extravalue1 = 7; + cur->hnext->extravalue2 = 2; + + prev = cur; + cur = cur->hnext; + cur->hprev = prev; + + // Back + cur->hnext = P_SpawnMobj(sign->x, sign->y, sign->z, MT_SIGN_PIECE); + P_SetTarget(&cur->hnext->target, sign); + P_SetMobjState(cur->hnext, S_SIGN_BACK); + cur->hnext->extravalue1 = 6; + cur->hnext->extravalue2 = 0; + + prev = cur; + cur = cur->hnext; + cur->hprev = prev; + + // Sides + cur->hnext = P_SpawnMobj(sign->x, sign->y, sign->z, MT_SIGN_PIECE); + P_SetTarget(&cur->hnext->target, sign); + P_SetMobjState(cur->hnext, S_SIGN_SIDE); + cur->hnext->extravalue1 = 30; + cur->hnext->extravalue2 = 1; + + prev = cur; + cur = cur->hnext; + cur->hprev = prev; + + cur->hnext = P_SpawnMobj(sign->x, sign->y, sign->z, MT_SIGN_PIECE); + P_SetTarget(&cur->hnext->target, sign); + P_SetMobjState(cur->hnext, S_SIGN_SIDE); + cur->hnext->extravalue1 = 30; + cur->hnext->extravalue2 = 3; + + prev = cur; + cur = cur->hnext; + cur->hprev = prev; +} + // // P_SetupSignExit // @@ -3257,13 +3327,7 @@ void P_SetupSignExit(player_t *player) if (thing->state != &states[thing->info->spawnstate]) continue; - P_SetTarget(&thing->target, player->mo); - P_SetMobjState(thing, S_SIGN1); - - // SRB2Kart: Set sign spinning variables - thing->movefactor = thing->z; - thing->z += (768*thing->scale) * P_MobjFlip(thing); - thing->movecount = 1; + P_SetupSignObject(thing, player->mo); ++numfound; } @@ -3285,14 +3349,7 @@ void P_SetupSignExit(player_t *player) if (thing->state != &states[thing->info->spawnstate]) continue; - P_SetTarget(&thing->target, player->mo); - P_SetMobjState(thing, S_SIGN1); - - // SRB2Kart: Set sign spinning variables - thing->movefactor = thing->z; - thing->z += (768*thing->scale) * P_MobjFlip(thing); - thing->movecount = 1; - + P_SetupSignObject(thing, player->mo); ++numfound; } @@ -3300,14 +3357,10 @@ void P_SetupSignExit(player_t *player) return; // SRB2Kart: FINALLY, add in an alternative if no place is found - if (player->mo) + if (player->mo && !P_MobjWasRemoved(player->mo)) { - mobj_t *sign = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + (768*mapobjectscale), MT_SIGN); - - P_SetTarget(&sign->target, player->mo); - P_SetMobjState(sign, S_SIGN1); - sign->movefactor = player->mo->floorz; - sign->movecount = 1; + thing = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->floorz, MT_SIGN); + P_SetupSignObject(thing, player->mo); } } From bba8861d2f0c37defca40d2f5289869ddd23c15a Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 8 Nov 2019 23:33:59 -0500 Subject: [PATCH 04/19] Set angle for ties --- src/p_spec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_spec.c b/src/p_spec.c index 0eb618c45..9f8bc6f4b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3360,6 +3360,7 @@ void P_SetupSignExit(player_t *player) if (player->mo && !P_MobjWasRemoved(player->mo)) { thing = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->floorz, MT_SIGN); + thing->angle = player->mo->angle; P_SetupSignObject(thing, player->mo); } } From 80bb59031c4bbf360fd45b875f5c85728feae466 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 14 Nov 2019 04:26:41 -0500 Subject: [PATCH 05/19] Blizzard weather option + much more sane workflow for adding new precipitation options "precipprops" lets you create a new precipitation type by picking a mobj type to use, how many random states it has, and flags for effects such as thunder/lightning. Seesound on the mobj type sets an ambient sound (like rain drops) and mass sets the sound's frequency in tics. This could open up the possibility for SOC/Lua Weather options later. --- src/dehacked.c | 12 ++- src/doomstat.h | 35 +++++-- src/g_game.c | 15 ++- src/hardware/hw_main.c | 5 +- src/info.c | 74 ++++++++++---- src/info.h | 7 ++ src/p_floor.c | 1 + src/p_mobj.c | 224 ++++++++++++++++++++--------------------- src/p_mobj.h | 31 +++--- src/p_spec.c | 221 +++++++++------------------------------- src/p_spec.h | 2 +- src/p_tick.c | 10 -- src/r_things.c | 6 +- 13 files changed, 283 insertions(+), 360 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 5f9249d89..af1ee934e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5690,6 +5690,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SNOW2", "S_SNOW3", + // Blizzard Snowball + "S_BLIZZARDSNOW1", + "S_BLIZZARDSNOW2", + "S_BLIZZARDSNOW3", + // Water Splish "S_SPLISH1", "S_SPLISH2", @@ -7589,6 +7594,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Environmental Effects "MT_RAIN", // Rain "MT_SNOWFLAKE", // Snowflake + "MT_BLIZZARDSNOW", // Blizzard Snowball "MT_SPLISH", // Water splish! "MT_SMOKE", "MT_SMALLBUBBLE", // small bubble @@ -8700,10 +8706,10 @@ struct { // Precipitation {"PRECIP_NONE",PRECIP_NONE}, - {"PRECIP_STORM",PRECIP_STORM}, - {"PRECIP_SNOW",PRECIP_SNOW}, {"PRECIP_RAIN",PRECIP_RAIN}, - {"PRECIP_BLANK",PRECIP_BLANK}, + {"PRECIP_SNOW",PRECIP_SNOW}, + {"PRECIP_BLIZZARD",PRECIP_BLIZZARD}, + {"PRECIP_STORM",PRECIP_STORM}, {"PRECIP_STORM_NORAIN",PRECIP_STORM_NORAIN}, {"PRECIP_STORM_NOSTRIKES",PRECIP_STORM_NOSTRIKES}, diff --git a/src/doomstat.h b/src/doomstat.h index 59e2bd5c4..cdc09cf86 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -41,18 +41,37 @@ extern UINT32 mapmusposition; extern INT16 maptol; extern UINT8 globalweather; -extern INT32 curWeather; +extern UINT8 curWeather; extern INT32 cursaveslot; extern INT16 lastmapsaved; extern boolean gamecomplete; -#define PRECIP_NONE 0 -#define PRECIP_STORM 1 -#define PRECIP_SNOW 2 -#define PRECIP_RAIN 3 -#define PRECIP_BLANK 4 -#define PRECIP_STORM_NORAIN 5 -#define PRECIP_STORM_NOSTRIKES 6 +typedef enum +{ + PRECIP_NONE = 0, + PRECIP_RAIN, + PRECIP_SNOW, + PRECIP_BLIZZARD, + PRECIP_STORM, + PRECIP_STORM_NORAIN, + PRECIP_STORM_NOSTRIKES, + MAXPRECIP +} preciptype_t; + +typedef enum +{ + PRECIPFX_THUNDER = 1, + PRECIPFX_LIGHTNING = 1<<1 +} precipeffect_t; + +typedef struct +{ + mobjtype_t type; + precipeffect_t effects; + UINT8 randomstates; +} precipprops_t; + +extern precipprops_t precipprops[MAXPRECIP]; // Set if homebrew PWAD stuff has been added. extern boolean modifiedgame; diff --git a/src/g_game.c b/src/g_game.c index d4d48f7c2..e15968b3e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -83,8 +83,21 @@ UINT32 mapmusposition; // Position to jump to INT16 gamemap = 1; INT16 maptol; + UINT8 globalweather = 0; -INT32 curWeather = PRECIP_NONE; +UINT8 curWeather = PRECIP_NONE; + +precipprops_t precipprops[MAXPRECIP] = +{ + {MT_NULL, 0, 0}, // PRECIP_NONE + {MT_RAIN, 0, 0}, // PRECIP_RAIN + {MT_SNOWFLAKE, 0, 2}, // PRECIP_SNOW + {MT_BLIZZARDSNOW, 0, 2}, // PRECIP_BLIZZARD + {MT_RAIN, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING, 0}, // PRECIP_STORM + {MT_NULL, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING, 0}, // PRECIP_STORM_NORAIN + {MT_RAIN, PRECIPFX_THUNDER, 0} // PRECIP_STORM_NOSTRIKES +}; + INT32 cursaveslot = -1; // Auto-save 1p savegame slot INT16 lastmapsaved = 0; // Last map we auto-saved at boolean gamecomplete = false; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 659af386d..31461283c 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5882,10 +5882,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) // okay, we can't return now... this is a hack, but weather isn't networked, so it should be ok if (!(thing->precipflags & PCF_THUNK)) { - if (thing->precipflags & PCF_RAIN) - P_RainThinker(thing); - else - P_SnowThinker(thing); + P_PrecipThinker(thing); thing->precipflags |= PCF_THUNK; } diff --git a/src/info.c b/src/info.c index 4f448cc00..4542e6c3a 100644 --- a/src/info.c +++ b/src/info.c @@ -44,17 +44,17 @@ char sprnames[NUMSPRITES + 1][5] = "BSZ7","BSZ8","STLG","DBAL","RCRY","ARMA","ARMF","ARMB","WIND","MAGN", "ELEM","FORC","PITY","IVSP","SSPK","GOAL","BIRD","BUNY","MOUS","CHIC", "COWZ","RBRD","SPVY","SPVR","SPVB","SPVG","SPDY","SPDR","SPDB","SPDG", - "SPHY","SPHR","SPHB","SPHG","RAIN","SNO1","SPLH","SPLA","SMOK","BUBP", - "BUBO","BUBN","BUBM","POPP","TFOG","SEED","PRTL","SCOR","DRWN","TTAG", - "GFLG","RRNG","RNGB","RNGR","RNGI","RNGA","RNGE","RNGS","RNGG","PIKB", - "PIKR","PIKA","PIKE","PIKS","PIKG","TAUT","TGRE","TSCR","COIN","CPRK", - "GOOM","BGOM","FFWR","FBLL","SHLL","PUMA","HAMM","KOOP","BFLM","MAXE", - "MUS1","MUS2","TOAD","NDRN","SUPE","SUPZ","NDRL","NSPK","NBMP","HOOP", - "NSCR","NPRU","CAPS","SUPT","SPRK","BOM1","BOM2","BOM3","BOM4","ROIA", - "ROIB","ROIC","ROID","ROIE","ROIF","ROIG","ROIH","ROII","ROIJ","ROIK", - "ROIL","ROIM","ROIN","ROIO","ROIP","BBAL","GWLG","GWLR","SRBA","SRBB", - "SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI","SRBJ","SRBK","SRBL", - "SRBM","SRBN","SRBO", + "SPHY","SPHR","SPHB","SPHG","RAIN","SNO1","SNO2","SPLH","SPLA","SMOK", + "BUBP","BUBO","BUBN","BUBM","POPP","TFOG","SEED","PRTL","SCOR","DRWN", + "TTAG","GFLG","RRNG","RNGB","RNGR","RNGI","RNGA","RNGE","RNGS","RNGG", + "PIKB","PIKR","PIKA","PIKE","PIKS","PIKG","TAUT","TGRE","TSCR","COIN", + "CPRK","GOOM","BGOM","FFWR","FBLL","SHLL","PUMA","HAMM","KOOP","BFLM", + "MAXE","MUS1","MUS2","TOAD","NDRN","SUPE","SUPZ","NDRL","NSPK","NBMP", + "HOOP","NSCR","NPRU","CAPS","SUPT","SPRK","BOM1","BOM2","BOM3","BOM4", + "ROIA","ROIB","ROIC","ROID","ROIE","ROIF","ROIG","ROIH","ROII","ROIJ", + "ROIK","ROIL","ROIM","ROIN","ROIO","ROIP","BBAL","GWLG","GWLR","SRBA", + "SRBB","SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI","SRBJ","SRBK", + "SRBL","SRBM","SRBN","SRBO", //SRB2kart Sprites "RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE","KINV","KINF", "WIPD","DRIF","BDRF","DUST","RSHE","FITM","BANA","ORBN","JAWZ","SSMN", @@ -1869,13 +1869,18 @@ state_t states[NUMSTATES] = // Rain {SPR_RAIN, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1 - {SPR_RAIN, FF_TRANS50, 1, {NULL}, 0, 0, S_RAIN1}, // S_RAINRETURN + {SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_RAINRETURN // Snowflake {SPR_SNO1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SNOW1 {SPR_SNO1, 1, -1, {NULL}, 0, 0, S_NULL}, // S_SNOW2 {SPR_SNO1, 2, -1, {NULL}, 0, 0, S_NULL}, // S_SNOW3 + // Blizzard Snowball + {SPR_SNO2, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLIZZARDSNOW1 + {SPR_SNO2, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BLIZZARDSNOW2 + {SPR_SNO2, 2, -1, {NULL}, 0, 0, S_NULL}, // S_BLIZZARDSNOW3 + // Water Splish {SPR_SPLH, FF_TRANS50 , 2, {NULL}, 0, 0, S_SPLISH2}, // S_SPLISH1 {SPR_SPLH, FF_TRANS50|1, 2, {NULL}, 0, 0, S_SPLISH3}, // S_SPLISH2 @@ -1888,9 +1893,9 @@ state_t states[NUMSTATES] = {SPR_SPLH, FF_TRANS50|8, 2, {NULL}, 0, 0, S_NULL}, // S_SPLISH9 // Water Splash - {SPR_SPLA, FF_TRANS50 , 3, {NULL}, 0, 0, S_SPLASH2}, // S_SPLASH1 - {SPR_SPLA, FF_TRANS70|1, 3, {NULL}, 0, 0, S_SPLASH3}, // S_SPLASH2 - {SPR_SPLA, FF_TRANS90|2, 3, {NULL}, 0, 0, S_RAINRETURN}, // S_SPLASH3 + {SPR_SPLA, FF_TRANS50 , 3, {NULL}, 0, 0, S_SPLASH2}, // S_SPLASH1 + {SPR_SPLA, FF_TRANS70|1, 3, {NULL}, 0, 0, S_SPLASH3}, // S_SPLASH2 + {SPR_SPLA, FF_TRANS90|2, 3, {NULL}, 0, 0, S_NULL}, // S_SPLASH3 // Smoke {SPR_SMOK, FF_TRANS50 , 4, {NULL}, 0, 0, S_SMOKE2}, // S_SMOKE1 @@ -11438,22 +11443,22 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_RAIN1, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime + sfx_rainin, // seesound + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_SPLASH1, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound -72*FRACUNIT, // speed -- -24*FRACUNIT originally, srb2kart x3 (nya) 1*FRACUNIT, // radius 8*FRACUNIT, // height 0, // display offset - 4, // mass + 80, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags @@ -11466,7 +11471,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -11480,7 +11485,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 4*FRACUNIT, // radius 4*FRACUNIT, // height 0, // display offset - 4, // mass + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP, // flags + S_NULL // raisestate + }, + + { // MT_BLIZZARDSNOW + -1, // doomednum + S_BLIZZARDSNOW1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + -24*FRACUNIT, // speed + 4*FRACUNIT, // radius + 4*FRACUNIT, // height + 0, // display offset + 0, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags diff --git a/src/info.h b/src/info.h index 27488d916..cb520252c 100644 --- a/src/info.h +++ b/src/info.h @@ -475,6 +475,7 @@ typedef enum sprite // Environmental Effects SPR_RAIN, // Rain SPR_SNO1, // Snowflake + SPR_SNO2, // Blizzard Snowball SPR_SPLH, // Water Splish SPR_SPLA, // Water Splash SPR_SMOK, @@ -2579,6 +2580,11 @@ typedef enum state S_SNOW2, S_SNOW3, + // Blizzard Snowball + S_BLIZZARDSNOW1, + S_BLIZZARDSNOW2, + S_BLIZZARDSNOW3, + // Water Splish S_SPLISH1, S_SPLISH2, @@ -4510,6 +4516,7 @@ typedef enum mobj_type // Environmental Effects MT_RAIN, // Rain MT_SNOWFLAKE, // Snowflake + MT_BLIZZARDSNOW, // Blizzard Snowball MT_SPLISH, // Water splish! MT_SMOKE, MT_SMALLBUBBLE, // small bubble diff --git a/src/p_floor.c b/src/p_floor.c index ccbfd6eae..666656958 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1769,6 +1769,7 @@ static mobj_t *SearchMarioNode(msecnode_t *node) case MT_SUPERSPARK: case MT_RAIN: case MT_SNOWFLAKE: + case MT_BLIZZARDSNOW: case MT_SPLISH: case MT_SMOKE: case MT_SMALLBUBBLE: diff --git a/src/p_mobj.c b/src/p_mobj.c index b220ff4e6..87fb7a186 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3928,51 +3928,60 @@ void P_NullPrecipThinker(precipmobj_t *mobj) mobj->precipflags &= ~PCF_THUNK; } -void P_SnowThinker(precipmobj_t *mobj) +void P_PrecipThinker(precipmobj_t *mobj) { P_CycleStateAnimation((mobj_t *)mobj); - // adjust height - if ((mobj->z += mobj->momz) <= mobj->floorz) - mobj->z = mobj->ceilingz; -} - -void P_RainThinker(precipmobj_t *mobj) -{ - P_CycleStateAnimation((mobj_t *)mobj); - - if (mobj->state != &states[S_RAIN1]) + if (mobj->state == &states[S_RAINRETURN]) { - // cycle through states, - // calling action functions at transitions - if (mobj->tics <= 0) - return; - - if (--mobj->tics) - return; - - if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate)) - return; - - if (mobj->state != &states[S_RAINRETURN]) - return; - + // Reset to ceiling! + P_SetPrecipMobjState(mobj, mobj->info->spawnstate); mobj->z = mobj->ceilingz; - P_SetPrecipMobjState(mobj, S_RAIN1); - - return; + mobj->momz = mobj->info->speed; + mobj->precipflags &= ~PCF_SPLASH; } + if (mobj->tics != -1) + { + if (mobj->tics) + { + mobj->tics--; + } + + if (mobj->tics == 0) + { + if ((mobj->precipflags & PCF_SPLASH) && (mobj->state->nextstate == S_NULL)) + { + // HACK: sprite changes are 1 tic late, so you would see splashes on the ceiling if not for this state. + // We need to use the settings from the previous state, since some of those are NOT 1 tic late. + INT32 frame = (mobj->frame & ~FF_FRAMEMASK); + P_SetPrecipMobjState(mobj, S_RAINRETURN); + mobj->frame = frame; + return; + } + else + { + if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate)) + return; + } + } + } + + if (mobj->precipflags & PCF_SPLASH) + return; + // adjust height if ((mobj->z += mobj->momz) <= mobj->floorz) { - // no splashes on sky or bottomless pits - if (mobj->precipflags & PCF_PIT) + if ((mobj->info->deathstate == S_NULL) || (mobj->precipflags & PCF_PIT)) // no splashes on sky or bottomless pits + { mobj->z = mobj->ceilingz; + } else { + P_SetPrecipMobjState(mobj, mobj->info->deathstate); mobj->z = mobj->floorz; - P_SetPrecipMobjState(mobj, S_SPLASH1); + mobj->precipflags |= PCF_SPLASH; } } } @@ -6354,9 +6363,8 @@ fixed_t P_CalculateShadowFloor(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fi } } -#if 0 mobj->standingslope = slope; -#endif + #ifdef HWRENDER mobj->modeltilt = slope; #endif @@ -10754,17 +10762,21 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster) static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) { + const mobjinfo_t *info = &mobjinfo[type]; state_t *st; precipmobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); fixed_t starting_floorz; + mobj->type = type; + mobj->info = info; + mobj->x = x; mobj->y = y; - mobj->flags = mobjinfo[type].flags; + mobj->flags = info->flags; // do not set the state with P_SetMobjState, // because action routines can not be called yet - st = &states[mobjinfo[type].spawnstate]; + st = &states[info->spawnstate]; mobj->state = st; mobj->tics = st->tics; @@ -10787,7 +10799,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype mobj->subsector->sector->ceilingheight; mobj->z = z; - mobj->momz = mobjinfo[type].speed; + mobj->momz = info->speed; mobj->thinker.function.acp1 = (actionf_p1)P_NullPrecipThinker; P_AddThinker(&mobj->thinker); @@ -10804,21 +10816,6 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype return mobj; } -static inline precipmobj_t *P_SpawnRainMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) -{ - precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type); - mo->precipflags |= PCF_RAIN; - //mo->thinker.function.acp1 = (actionf_p1)P_RainThinker; - return mo; -} - -static inline precipmobj_t *P_SpawnSnowMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) -{ - precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type); - //mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker; - return mo; -} - // // P_RemoveMobj // @@ -11007,8 +11004,8 @@ consvar_t cv_suddendeath = {"suddendeath", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHE void P_SpawnPrecipitation(void) { - INT32 i, mrand; - fixed_t basex, basey, x, y, height; + INT32 i, j, k; + fixed_t basex, basey, x, y, z, height; subsector_t *precipsector = NULL; precipmobj_t *rainmo = NULL; @@ -11021,8 +11018,9 @@ void P_SpawnPrecipitation(void) basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE; basey = bmaporgy + (i / bmapwidth) * MAPBLOCKSIZE; - //for (j = 0; j < cv_precipdensity.value; ++j) -- density is 1 for kart always { + UINT16 numparticles = 0; + x = basex + ((M_RandomKey(MAPBLOCKUNITS<<3)<>3); y = basey + ((M_RandomKey(MAPBLOCKUNITS<<3)<>3); @@ -11037,40 +11035,43 @@ void P_SpawnPrecipitation(void) if (precipsector->sector->ceilingpic != skyflatnum) continue; + height = abs(precipsector->sector->ceilingheight - precipsector->sector->floorheight); + // Exists, but is too small for reasonable precipitation. - if (!(precipsector->sector->floorheight <= precipsector->sector->ceilingheight - (32<sector->ceilingheight; + // Hack around a quirk of this entire system, where taller sectors look like they get less precipitation. + numparticles = 1 + (height / (MAPBLOCKUNITS<<4<sector->ceilingheight; + + for (j = 0; j < numparticles; j++) { - rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE); - mrand = M_RandomByte(); - if (mrand < 64) - P_SetPrecipMobjState(rainmo, S_SNOW3); - else if (mrand < 144) - P_SetPrecipMobjState(rainmo, S_SNOW2); + rainmo = P_SpawnPrecipMobj(x, y, z, precipprops[curWeather].type); + + if (precipprops[curWeather].randomstates > 0) + { + UINT8 mrand = M_RandomByte(); + UINT8 threshold = UINT8_MAX / (precipprops[curWeather].randomstates + 1); + statenum_t st = mobjinfo[precipprops[curWeather].type].spawnstate; + + for (k = 0; k < precipprops[curWeather].randomstates; k++) + { + if (mrand < (threshold * (k+1))) + { + P_SetPrecipMobjState(rainmo, st+k+1); + break; + } + } + } + + // Randomly assign a height, now that floorz is set. + rainmo->z = M_RandomRange(rainmo->floorz>>FRACBITS, rainmo->ceilingz>>FRACBITS)<z = M_RandomRange(rainmo->floorz>>FRACBITS, rainmo->ceilingz>>FRACBITS)< 255) volume = 255; - if (sounds_rain && (!leveltime || leveltime % 80 == 1)) - S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_rainin, volume); + if (rainsfx != sfx_None && (!leveltime || leveltime % rainfreq == 1)) + S_StartSoundAtVolume(players[displayplayers[0]].mo, rainsfx, volume); if (!sounds_thunder) return; diff --git a/src/p_mobj.h b/src/p_mobj.h index aec2ed951..da3ba88e6 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -253,25 +253,23 @@ typedef enum // PRECIPITATION flags ?! ?! ?! // typedef enum { - // Don't draw. - PCF_INVISIBLE = 1, - // Above pit. - PCF_PIT = 2, - // Above FOF. - PCF_FOF = 4, - // Above MOVING FOF (this means we need to keep floorz up to date...) - PCF_MOVINGFOF = 8, - // Is rain. - PCF_RAIN = 16, - // Ran the thinker this tic. - PCF_THUNK = 32, + PCF_INVISIBLE = 1, // Don't draw. + PCF_PIT = 1<<1, // Above pit. + PCF_FOF = 1<<2, // Above FOF. + PCF_MOVINGFOF = 1<<3, // Above MOVING FOF (this means we need to keep floorz up to date...) + PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over + PCF_THUNK = 1<<5, // Ran the thinker this tic. } precipflag_t; + // Map Object definition. typedef struct mobj_s { // List: thinker links. thinker_t thinker; + mobjtype_t type; + const mobjinfo_t *info; // &mobjinfo[mobj->type] + // Info for drawing: position. fixed_t x, y, z; @@ -321,9 +319,6 @@ typedef struct mobj_s struct mobj_s *hnext; struct mobj_s *hprev; - mobjtype_t type; - const mobjinfo_t *info; // &mobjinfo[mobj->type] - INT32 health; // for player this is rings + 1 // Movement direction, movement generation (zig-zagging). @@ -392,6 +387,9 @@ typedef struct precipmobj_s // List: thinker links. thinker_t thinker; + mobjtype_t type; + const mobjinfo_t *info; // &mobjinfo[mobj->type] + // Info for drawing: position. fixed_t x, y, z; @@ -459,8 +457,7 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb boolean P_BossTargetPlayer(mobj_t *actor, boolean closest); boolean P_SupermanLook4Players(mobj_t *actor); void P_DestroyRobots(void); -void P_SnowThinker(precipmobj_t *mobj); -void P_RainThinker(precipmobj_t *mobj); +void P_PrecipThinker(precipmobj_t *mobj); void P_NullPrecipThinker(precipmobj_t *mobj); void P_RemovePrecipMobj(precipmobj_t *mobj); void P_SetScale(mobj_t *mobj, fixed_t newscale); diff --git a/src/p_spec.c b/src/p_spec.c index 93e88e2ce..d92fb2f3b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2003,57 +2003,28 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller) // // Switches the weather! // -void P_SwitchWeather(INT32 weathernum) +void P_SwitchWeather(UINT8 newWeather) { boolean purge = false; - INT32 swap = 0; + mobjtype_t swap = MT_NULL; - switch (weathernum) + if (precipprops[newWeather].type == MT_NULL) { - case PRECIP_NONE: // None - if (curWeather == PRECIP_NONE) - return; // Nothing to do. - purge = true; - break; - case PRECIP_STORM: // Storm - case PRECIP_STORM_NOSTRIKES: // Storm w/ no lightning - case PRECIP_RAIN: // Rain - if (curWeather == PRECIP_SNOW || curWeather == PRECIP_BLANK || curWeather == PRECIP_STORM_NORAIN) - swap = PRECIP_RAIN; - break; - case PRECIP_SNOW: // Snow - if (curWeather == PRECIP_SNOW) - return; // Nothing to do. - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES || curWeather == PRECIP_BLANK || curWeather == PRECIP_STORM_NORAIN) - swap = PRECIP_SNOW; // Need to delete the other precips. - break; - case PRECIP_STORM_NORAIN: // Storm w/o rain - if (curWeather == PRECIP_SNOW - || curWeather == PRECIP_STORM - || curWeather == PRECIP_STORM_NOSTRIKES - || curWeather == PRECIP_RAIN - || curWeather == PRECIP_BLANK) - swap = PRECIP_STORM_NORAIN; - else if (curWeather == PRECIP_STORM_NORAIN) - return; - break; - case PRECIP_BLANK: - if (curWeather == PRECIP_SNOW - || curWeather == PRECIP_STORM - || curWeather == PRECIP_STORM_NOSTRIKES - || curWeather == PRECIP_RAIN) - swap = PRECIP_BLANK; - else if (curWeather == PRECIP_STORM_NORAIN) - swap = PRECIP_BLANK; - else if (curWeather == PRECIP_BLANK) - return; - break; - default: - CONS_Debug(DBG_GAMELOGIC, "P_SwitchWeather: Unknown weather type %d.\n", weathernum); - break; + // New type is null, we want to purge the weather. + if (precipprops[curWeather].type == MT_NULL) + return; // Nothing to do. + purge = true; + } + else + { + if (precipprops[curWeather].type != MT_NULL) + { + // There are already existing weather particles to reuse. + swap = precipprops[newWeather].type; + } } - if (purge) + if (purge == true) { thinker_t *think; precipmobj_t *precipmobj; @@ -2068,136 +2039,53 @@ void P_SwitchWeather(INT32 weathernum) P_RemovePrecipMobj(precipmobj); } } - else if (swap && !((swap == PRECIP_BLANK && curWeather == PRECIP_STORM_NORAIN) || (swap == PRECIP_STORM_NORAIN && curWeather == PRECIP_BLANK))) // Rather than respawn all that crap, reuse it! + else if (swap != MT_NULL) // Rather than respawn all that crap, reuse it! { thinker_t *think; precipmobj_t *precipmobj; - state_t *st; + statenum_t st; for (think = thinkercap.next; think != &thinkercap; think = think->next) { if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker) continue; // not a precipmobj thinker + precipmobj = (precipmobj_t *)think; - if (swap == PRECIP_RAIN) // Snow To Rain + precipmobj->flags = mobjinfo[swap].flags; + + st = mobjinfo[swap].spawnstate; + + if (precipprops[curWeather].randomstates > 0) { - precipmobj->flags = mobjinfo[MT_RAIN].flags; - st = &states[mobjinfo[MT_RAIN].spawnstate]; - precipmobj->state = st; - precipmobj->tics = st->tics; - precipmobj->sprite = st->sprite; - precipmobj->frame = st->frame; - precipmobj->momz = mobjinfo[MT_RAIN].speed; + UINT8 mrand = M_RandomByte(); + UINT8 threshold = UINT8_MAX / (precipprops[curWeather].randomstates + 1); + UINT8 i; - precipmobj->precipflags &= ~PCF_INVISIBLE; - - precipmobj->precipflags |= PCF_RAIN; - //think->function.acp1 = (actionf_p1)P_RainThinker; + for (i = 0; i < precipprops[curWeather].randomstates; i++) + { + if (mrand < (threshold * (i+1))) + { + st += i+1; + break; + } + } } - else if (swap == PRECIP_SNOW) // Rain To Snow - { - INT32 z; - precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags; - z = M_RandomByte(); + precipmobj->state = &states[st]; + precipmobj->tics = precipmobj->state->tics; + precipmobj->sprite = precipmobj->state->sprite; + precipmobj->frame = precipmobj->state->frame; - if (z < 64) - z = 2; - else if (z < 144) - z = 1; - else - z = 0; - - st = &states[mobjinfo[MT_SNOWFLAKE].spawnstate+z]; - precipmobj->state = st; - precipmobj->tics = st->tics; - precipmobj->sprite = st->sprite; - precipmobj->frame = st->frame; - precipmobj->momz = mobjinfo[MT_SNOWFLAKE].speed; - - precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_RAIN); - - //think->function.acp1 = (actionf_p1)P_SnowThinker; - } - else if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse. - { - //think->function.acp1 = (actionf_p1)P_NullPrecipThinker; - - precipmobj->precipflags |= PCF_INVISIBLE; - } + precipmobj->momz = mobjinfo[swap].speed; + precipmobj->precipflags &= ~PCF_INVISIBLE; } } - switch (weathernum) - { - case PRECIP_SNOW: // snow - curWeather = PRECIP_SNOW; + curWeather = newWeather; - if (!swap) - P_SpawnPrecipitation(); - - break; - case PRECIP_RAIN: // rain - { - boolean dontspawn = false; - - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES) - dontspawn = true; - - curWeather = PRECIP_RAIN; - - if (!dontspawn && !swap) - P_SpawnPrecipitation(); - - break; - } - case PRECIP_STORM: // storm - { - boolean dontspawn = false; - - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES) - dontspawn = true; - - curWeather = PRECIP_STORM; - - if (!dontspawn && !swap) - P_SpawnPrecipitation(); - - break; - } - case PRECIP_STORM_NOSTRIKES: // storm w/o lightning - { - boolean dontspawn = false; - - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES) - dontspawn = true; - - curWeather = PRECIP_STORM_NOSTRIKES; - - if (!dontspawn && !swap) - P_SpawnPrecipitation(); - - break; - } - case PRECIP_STORM_NORAIN: // storm w/o rain - curWeather = PRECIP_STORM_NORAIN; - - if (!swap) - P_SpawnPrecipitation(); - - break; - case PRECIP_BLANK: - curWeather = PRECIP_BLANK; - - if (!swap) - P_SpawnPrecipitation(); - - break; - default: - curWeather = PRECIP_NONE; - break; - } + if (swap == MT_NULL && precipprops[newWeather].type != MT_NULL) + P_SpawnPrecipitation(); } /** Gets an object. @@ -5672,25 +5560,10 @@ void P_InitSpecials(void) CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false; - // Set curWeather - switch (mapheaderinfo[gamemap-1]->weather) - { - case PRECIP_SNOW: // snow - case PRECIP_RAIN: // rain - case PRECIP_STORM: // storm - case PRECIP_STORM_NORAIN: // storm w/o rain - case PRECIP_STORM_NOSTRIKES: // storm w/o lightning - curWeather = mapheaderinfo[gamemap-1]->weather; - break; - default: // blank/none - curWeather = PRECIP_NONE; - break; - } + // Set weather + curWeather = globalweather = mapheaderinfo[gamemap-1]->weather; - // Set globalweather - globalweather = mapheaderinfo[gamemap-1]->weather; - - P_InitTagLists(); // Create xref tables for tags + P_InitTagLists(); // Create xref tables for tags } /** After the map has loaded, scans for specials that spawn 3Dfloors and diff --git a/src/p_spec.h b/src/p_spec.h index b604ac951..1aca41155 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -59,7 +59,7 @@ INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max); void P_SetupSignExit(player_t *player); boolean P_IsFlagAtBase(mobjtype_t flag); -void P_SwitchWeather(INT32 weathernum); +void P_SwitchWeather(UINT8 newWeather); boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller); void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller); diff --git a/src/p_tick.c b/src/p_tick.c index b285c35d0..9e4de8e33 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -58,8 +58,6 @@ void Command_Numthinkers_f(void) CONS_Printf(M_GetText("numthinkers <#>: Count number of thinkers\n")); CONS_Printf( "\t1: P_MobjThinker\n" - /*"\t2: P_RainThinker\n" - "\t3: P_SnowThinker\n"*/ "\t2: P_NullPrecipThinker\n" "\t3: T_Friction\n" "\t4: T_Pusher\n" @@ -75,14 +73,6 @@ void Command_Numthinkers_f(void) action = (actionf_p1)P_MobjThinker; CONS_Printf(M_GetText("Number of %s: "), "P_MobjThinker"); break; - /*case 2: - action = (actionf_p1)P_RainThinker; - CONS_Printf(M_GetText("Number of %s: "), "P_RainThinker"); - break; - case 3: - action = (actionf_p1)P_SnowThinker; - CONS_Printf(M_GetText("Number of %s: "), "P_SnowThinker"); - break;*/ case 2: action = (actionf_p1)P_NullPrecipThinker; CONS_Printf(M_GetText("Number of %s: "), "P_NullPrecipThinker"); diff --git a/src/r_things.c b/src/r_things.c index 1afbb125c..847f011ec 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1639,14 +1639,10 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) // okay, we can't return now except for vertical clipping... this is a hack, but weather isn't networked, so it should be ok if (!(thing->precipflags & PCF_THUNK)) { - if (thing->precipflags & PCF_RAIN) - P_RainThinker(thing); - else - P_SnowThinker(thing); + P_PrecipThinker(thing); thing->precipflags |= PCF_THUNK; } - //SoM: 3/17/2000: Disregard sprites that are out of view.. gzt = thing->z + spritecachedinfo[lump].topoffset; gz = gzt - spritecachedinfo[lump].height; From 100a67f8f0c048585b5d45993429b68b33af4bc3 Mon Sep 17 00:00:00 2001 From: James Date: Sat, 16 Nov 2019 16:14:54 -0500 Subject: [PATCH 06/19] Prevent LF2_EXISTSHACK from ever getting removed --- src/p_setup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 5acc72746..b51dabdd0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -181,6 +181,8 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg) static void P_ClearSingleMapHeaderInfo(INT16 i) { const INT16 num = (INT16)(i-1); + INT32 exists = (mapheaderinfo[num]->menuflags & LF2_EXISTSHACK); + DEH_WriteUndoline("LEVELNAME", mapheaderinfo[num]->lvlttl, UNDO_NONE); mapheaderinfo[num]->lvlttl[0] = '\0'; DEH_WriteUndoline("SUBTITLE", mapheaderinfo[num]->subttl, UNDO_NONE); @@ -246,7 +248,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) DEH_WriteUndoline("LEVELFLAGS", va("%d", mapheaderinfo[num]->levelflags), UNDO_NONE); mapheaderinfo[num]->levelflags = 0; DEH_WriteUndoline("MENUFLAGS", va("%d", mapheaderinfo[num]->menuflags), UNDO_NONE); - mapheaderinfo[num]->menuflags = (mainwads ? 0 : LF2_EXISTSHACK); // see p_setup.c - prevents replacing maps in addons with easier versions + mapheaderinfo[num]->menuflags = exists; // see p_setup.c - prevents replacing maps in addons with easier versions // TODO grades support for delfile (pfft yeah right) P_DeleteGrades(num); // SRB2Kart From 5f26312a0a390ccff6cf6bdca6135da2d52c37f4 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 22 Feb 2020 18:30:20 -0800 Subject: [PATCH 07/19] Drop frames as the host according to the lowest ping among clients --- src/d_clisrv.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1dacabd9f..7851e1b62 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4960,6 +4960,28 @@ static void CL_SendClientCmd(void) size_t packetsize = 0; boolean mis = false; + int fastest; + int lag; + int i; + + fastest = 0; + + if (server) + { + for (i = 0; i < MAXPLAYERS; ++i) + { + if (playernode[i] > 0 && playeringame[i]) + { + lag = GetLag(playernode[i]); + if (! fastest || lag < fastest) + fastest = lag; + } + } + } + + if (fastest && ( gametic % fastest )) + return; + netbuffer->packettype = PT_CLIENTCMD; if (cl_packetmissed) From 56f6b058d039dfbd64c6fa5e3747342a2aa3bd5f Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 22 Feb 2020 18:33:31 -0800 Subject: [PATCH 08/19] Make host lag optional with "lagless", lag by default (lagless off) --- src/d_clisrv.c | 2 +- src/d_netcmd.c | 3 +++ src/d_netcmd.h | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7851e1b62..1f5e1f1ae 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4966,7 +4966,7 @@ static void CL_SendClientCmd(void) fastest = 0; - if (server) + if (server && ! cv_lagless.value) { for (i = 0; i < MAXPLAYERS; ++i) { diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 70dff2fcf..ede7558ad 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -447,6 +447,8 @@ consvar_t cv_jointimeout = {"jointimeout", "105", CV_CALL|CV_SAVE, nettimeout_co static CV_PossibleValue_t maxping_cons_t[] = {{0, "MIN"}, {1000, "MAX"}, {0, NULL}}; consvar_t cv_maxping = {"maxping", "800", CV_SAVE, maxping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_lagless = {"lagless", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + static CV_PossibleValue_t pingtimeout_cons_t[] = {{8, "MIN"}, {120, "MAX"}, {0, NULL}}; consvar_t cv_pingtimeout = {"pingtimeout", "10", CV_SAVE, pingtimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -711,6 +713,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_skipmapcheck); CV_RegisterVar(&cv_sleep); CV_RegisterVar(&cv_maxping); + CV_RegisterVar(&cv_lagless); CV_RegisterVar(&cv_pingtimeout); CV_RegisterVar(&cv_showping); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index d1f28665c..7a11a809d 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -144,6 +144,7 @@ extern consvar_t cv_ringslinger, cv_soundtest; extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionboxes; extern consvar_t cv_maxping; +extern consvar_t cv_lagless; extern consvar_t cv_pingtimeout; extern consvar_t cv_showping; From 6484a5cd93179581b4e07c52931adc9c52752c66 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 22 Feb 2020 18:38:36 -0800 Subject: [PATCH 09/19] Show LAGLESS on the scores if the host is being dishonest --- src/k_kart.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 230662d2a..2000c3765 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7085,6 +7085,9 @@ static patch_t *kp_lapanim_hand[3]; static patch_t *kp_yougotem; static patch_t *kp_itemminimap; +static patch_t *kp_alagles[10]; +static patch_t *kp_blagles[6]; + void K_LoadKartHUDGraphics(void) { INT32 i, j; @@ -7385,6 +7388,20 @@ void K_LoadKartHUDGraphics(void) kp_yougotem = (patch_t *) W_CachePatchName("YOUGOTEM", PU_HUDGFX); kp_itemminimap = (patch_t *) W_CachePatchName("MMAPITEM", PU_HUDGFX); + + sprintf(buffer, "ALAGLESx"); + for (i = 0; i < 10; ++i) + { + buffer[7] = '0'+i; + kp_alagles[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + } + + sprintf(buffer, "BLAGLESx"); + for (i = 0; i < 6; ++i) + { + buffer[7] = '0'+i; + kp_blagles[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + } } // For the item toggle menu @@ -8357,9 +8374,11 @@ static boolean K_drawKartPositionFaces(void) // void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol) { + static tic_t alagles_timer = 9; INT32 i, rightoffset = 240; const UINT8 *colormap; INT32 dupadjust = (vid.width/vid.dupx), duptweak = (dupadjust - BASEVIDWIDTH)/2; + int y2; //this function is designed for 9 or less score lines only //I_Assert(scorelines <= 9); -- not today bitch, kart fixed it up @@ -8385,10 +8404,34 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I STRBUFCPY(strtime, tab[i].name); + y2 = y; + + if (tab[i].num == 0 && cv_lagless.value) + { + y2 = ( y - 4 ); + + V_DrawScaledPatch(x + 20, y2, 0, kp_blagles[(leveltime / 3) % 6]); + // every 70 tics + if (( leveltime % 70 ) == 0) + { + alagles_timer = 9; + } + if (alagles_timer > 0) + { + V_DrawScaledPatch(x + 20, y2, 0, kp_alagles[alagles_timer]); + if (( leveltime % 2 ) == 0) + alagles_timer--; + } + else + V_DrawScaledPatch(x + 20, y2, 0, kp_alagles[0]); + + y2 += SHORT (kp_alagles[0]->height) + 1; + } + if (scorelines > 8) - V_DrawThinString(x + 20, y, ((tab[i].num == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime); + V_DrawThinString(x + 20, y2, ((tab[i].num == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime); else - V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime); + V_DrawString(x + 20, y2, ((tab[i].num == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime); if (players[tab[i].num].mo->color) { From 352d576979585e1f04b5d0b6d06a7b05cbc1305a Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 22 Feb 2020 19:08:03 -0800 Subject: [PATCH 10/19] Don't turn off lagless at map start; draw LAGLESS in intermission --- src/d_clisrv.c | 3 ++- src/d_clisrv.h | 2 ++ src/d_netcmd.c | 12 +++++++++++- src/g_game.c | 2 ++ src/k_kart.c | 2 +- src/y_inter.c | 36 ++++++++++++++++++++++++++++++++++-- 6 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1f5e1f1ae..e520c8155 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -97,6 +97,7 @@ UINT16 pingmeasurecount = 1; UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. tic_t servermaxping = 800; // server's max ping. Defaults to 800 +boolean server_lagless; SINT8 nodetoplayer[MAXNETNODES]; SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) SINT8 nodetoplayer3[MAXNETNODES]; // say the numplayer for this node if any (splitscreen == 2) @@ -4966,7 +4967,7 @@ static void CL_SendClientCmd(void) fastest = 0; - if (server && ! cv_lagless.value) + if (server && ! server_lagless) { for (i = 0; i < MAXPLAYERS; ++i) { diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 0bd85b614..a33d06a2c 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -543,6 +543,8 @@ extern UINT32 realpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS]; extern tic_t servermaxping; +extern boolean server_lagless; + extern consvar_t #ifdef VANILLAJOINNEXTROUND cv_joinnextround, diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ede7558ad..6b196d10d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -93,6 +93,8 @@ static void TeamScramble_OnChange(void); static void NetTimeout_OnChange(void); static void JoinTimeout_OnChange(void); +static void Lagless_OnChange (void); + static void Ringslinger_OnChange(void); static void Gravity_OnChange(void); static void ForceSkin_OnChange(void); @@ -447,7 +449,7 @@ consvar_t cv_jointimeout = {"jointimeout", "105", CV_CALL|CV_SAVE, nettimeout_co static CV_PossibleValue_t maxping_cons_t[] = {{0, "MIN"}, {1000, "MAX"}, {0, NULL}}; consvar_t cv_maxping = {"maxping", "800", CV_SAVE, maxping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_lagless = {"lagless", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_lagless = {"lagless", "Off", CV_SAVE|CV_NETVAR|CV_CALL, CV_OnOff, Lagless_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t pingtimeout_cons_t[] = {{8, "MIN"}, {120, "MAX"}, {0, NULL}}; consvar_t cv_pingtimeout = {"pingtimeout", "10", CV_SAVE, pingtimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -4772,6 +4774,14 @@ static void JoinTimeout_OnChange(void) jointimeout = (tic_t)cv_jointimeout.value; } +static void +Lagless_OnChange (void) +{ + /* don't back out of dishonesty, or go lagless after playing honestly */ + if (cv_lagless.value && gamestate == GS_LEVEL) + server_lagless = true; +} + UINT32 timelimitintics = 0; /** Deals with a timelimit change by printing the change to the console. diff --git a/src/g_game.c b/src/g_game.c index d4d48f7c2..af32050de 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1781,6 +1781,8 @@ void G_DoLoadLevel(boolean resetplayer) // clear hud messages remains (usually from game startup) CON_ClearHUD(); + + server_lagless = cv_lagless.value; } static INT32 pausedelay = 0; diff --git a/src/k_kart.c b/src/k_kart.c index 2000c3765..4016b7ced 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8406,7 +8406,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I y2 = y; - if (tab[i].num == 0 && cv_lagless.value) + if (tab[i].num == 0 && server_lagless) { y2 = ( y - 4 ); diff --git a/src/y_inter.c b/src/y_inter.c index f5380d565..ff168070c 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -435,6 +435,7 @@ void Y_IntermissionDrawer(void) INT32 y = 41, gutter = ((data.match.numplayers > NUMFORNEWCOLUMN) ? 0 : (BASEVIDWIDTH/2)); INT32 dupadjust = (vid.width/vid.dupx), duptweak = (dupadjust - BASEVIDWIDTH)/2; const char *timeheader; + int y2; if (data.match.rankingsmode) timeheader = "PWR.LV"; @@ -492,10 +493,41 @@ void Y_IntermissionDrawer(void) STRBUFCPY(strtime, data.match.name[i]); + y2 = y; + + if (data.match.num[i] == 0 && server_lagless) + { + static int alagles_timer = 0; + patch_t *alagles; + + y2 = ( y - 4 ); + + V_DrawScaledPatch(x + 36, y2, 0, W_CachePatchName(va("BLAGLES%d", (intertic / 3) % 6), PU_CACHE)); + // every 70 tics + if (( leveltime % 70 ) == 0) + { + alagles_timer = 9; + } + if (alagles_timer > 0) + { + alagles = W_CachePatchName(va("ALAGLES%d", alagles_timer), PU_CACHE); + V_DrawScaledPatch(x + 36, y2, 0, alagles); + if (( leveltime % 2 ) == 0) + alagles_timer--; + } + else + { + alagles = W_CachePatchName("ALAGLES0", PU_CACHE); + V_DrawScaledPatch(x + 36, y2, 0, alagles); + } + + y2 += SHORT (alagles->height) + 1; + } + if (data.match.numplayers > NUMFORNEWCOLUMN) - V_DrawThinString(x+36, y-1, ((data.match.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime); + V_DrawThinString(x+36, y2-1, ((data.match.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime); else - V_DrawString(x+36, y, ((data.match.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime); + V_DrawString(x+36, y2, ((data.match.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime); if (data.match.rankingsmode) { From a511d9358a81fb743a5b9b789c61d6f31c1b38c3 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 22 Feb 2020 19:38:36 -0800 Subject: [PATCH 11/19] Terrible code to show the ping counter for honest servers --- src/d_clisrv.c | 75 +++++++++++++++++++++++++++++++++-------------- src/sdl/i_video.c | 5 +++- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index e520c8155..28a519694 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -97,6 +97,7 @@ UINT16 pingmeasurecount = 1; UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. tic_t servermaxping = 800; // server's max ping. Defaults to 800 +static tic_t lowest_lag; boolean server_lagless; SINT8 nodetoplayer[MAXNETNODES]; SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) @@ -4961,26 +4962,7 @@ static void CL_SendClientCmd(void) size_t packetsize = 0; boolean mis = false; - int fastest; - int lag; - int i; - - fastest = 0; - - if (server && ! server_lagless) - { - for (i = 0; i < MAXPLAYERS; ++i) - { - if (playernode[i] > 0 && playeringame[i]) - { - lag = GetLag(playernode[i]); - if (! fastest || lag < fastest) - fastest = lag; - } - } - } - - if (fastest && ( gametic % fastest )) + if (lowest_lag && ( gametic % lowest_lag )) return; netbuffer->packettype = PT_CLIENTCMD; @@ -5451,16 +5433,65 @@ static tic_t gametime = 0; static void UpdatePingTable(void) { + int fastest; + tic_t lag; + INT32 i; + if (server) { if (netgame && !(gametime % 35)) // update once per second. PingUpdate(); + + fastest = 0; + // update node latency values so we can take an average later. for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]) - realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i])); + { + if (playeringame[i] && playernode[i] > 0) + { + if (! server_lagless && playernode[i] > 0) + { + lag = GetLag(playernode[i]); + realpingtable[i] += G_TicsToMilliseconds(lag); + + if (! fastest || lag < fastest) + fastest = lag; + } + else + realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i])); + } + } pingmeasurecount++; + + if (server_lagless) + lowest_lag = 0; + else + { + lowest_lag = fastest; + + if (fastest) + lag = fastest; + else + lag = GetLag(0); + + lag = ( realpingtable[0] + G_TicsToMilliseconds(lag) ); + + switch (playerpernode[0]) + { + case 4: + realpingtable[nodetoplayer4[0]] = lag; + /*FALLTHRU*/ + case 3: + realpingtable[nodetoplayer3[0]] = lag; + /*FALLTHRU*/ + case 2: + realpingtable[nodetoplayer2[0]] = lag; + /*FALLTHRU*/ + case 1: + realpingtable[nodetoplayer[0]] = lag; + } + } } } diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index e5f1c23fc..c900417ab 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1382,8 +1382,11 @@ void I_FinishUpdate(void) if (cv_ticrate.value) SCR_DisplayTicRate(); - if (cv_showping.value && netgame && consoleplayer != serverplayer) + if (cv_showping.value && netgame && + ( consoleplayer != serverplayer || ! server_lagless )) + { SCR_DisplayLocalPing(); + } } if (rendermode == render_soft && screens[0]) From 4f73e2666188df1d0b6b896cbe68f57152ff5b62 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 22 Feb 2020 19:44:16 -0800 Subject: [PATCH 12/19] Show server's ping on scores if not LAGLESS --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 4016b7ced..3c01f22ab 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8399,7 +8399,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I continue; //ignore them. if (netgame // don't draw it offline - && tab[i].num != serverplayer) + && ( tab[i].num != serverplayer || ! server_lagless )) HU_drawPing(x + ((i < 8) ? -17 : rightoffset + 11), y-4, playerpingtable[tab[i].num], 0); STRBUFCPY(strtime, tab[i].name); From a63157b937a347e60666bed1d1cde43838e2fc2f Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Tue, 25 Feb 2020 00:04:39 -0500 Subject: [PATCH 13/19] Flip facing direction --- src/p_spec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 9f8bc6f4b..2d8e355ed 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3251,7 +3251,7 @@ static void P_SetupSignObject(mobj_t *sign, mobj_t *pmo) P_SetTarget(&cur->hnext->target, sign); P_SetMobjState(cur->hnext, S_SIGN_FACE); cur->hnext->extravalue1 = 6; - cur->hnext->extravalue2 = 2; + cur->hnext->extravalue2 = 0; prev = cur; cur = cur->hnext; @@ -3263,7 +3263,7 @@ static void P_SetupSignObject(mobj_t *sign, mobj_t *pmo) cur->hnext->skin = pmo->skin; P_SetMobjState(cur->hnext, S_PLAY_SIGN); cur->hnext->extravalue1 = 7; - cur->hnext->extravalue2 = 2; + cur->hnext->extravalue2 = 0; prev = cur; cur = cur->hnext; @@ -3274,7 +3274,7 @@ static void P_SetupSignObject(mobj_t *sign, mobj_t *pmo) P_SetTarget(&cur->hnext->target, sign); P_SetMobjState(cur->hnext, S_SIGN_BACK); cur->hnext->extravalue1 = 6; - cur->hnext->extravalue2 = 0; + cur->hnext->extravalue2 = 2; prev = cur; cur = cur->hnext; From 6956e1d24ed96c3d8853e50d124fe450725094a6 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 1 Mar 2020 13:13:59 -0500 Subject: [PATCH 14/19] Store random states in mobjinfo instead of precipprops My reasoning is that it wouldn't make much sense to have a weather type that has snow, but doesn't randomize the sprite it uses, so we don't need to copy-paste the same "randomstates" for each weather type. --- src/doomstat.h | 1 - src/g_game.c | 14 +++++++------- src/info.c | 4 ++-- src/p_mobj.c | 12 +++++++----- src/p_spec.c | 7 ++++--- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index cdc09cf86..f4f7acfd0 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -68,7 +68,6 @@ typedef struct { mobjtype_t type; precipeffect_t effects; - UINT8 randomstates; } precipprops_t; extern precipprops_t precipprops[MAXPRECIP]; diff --git a/src/g_game.c b/src/g_game.c index e15968b3e..488f350a7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -89,13 +89,13 @@ UINT8 curWeather = PRECIP_NONE; precipprops_t precipprops[MAXPRECIP] = { - {MT_NULL, 0, 0}, // PRECIP_NONE - {MT_RAIN, 0, 0}, // PRECIP_RAIN - {MT_SNOWFLAKE, 0, 2}, // PRECIP_SNOW - {MT_BLIZZARDSNOW, 0, 2}, // PRECIP_BLIZZARD - {MT_RAIN, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING, 0}, // PRECIP_STORM - {MT_NULL, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING, 0}, // PRECIP_STORM_NORAIN - {MT_RAIN, PRECIPFX_THUNDER, 0} // PRECIP_STORM_NOSTRIKES + {MT_NULL, 0}, // PRECIP_NONE + {MT_RAIN, 0}, // PRECIP_RAIN + {MT_SNOWFLAKE, 0}, // PRECIP_SNOW + {MT_BLIZZARDSNOW, 0}, // PRECIP_BLIZZARD + {MT_RAIN, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM + {MT_NULL, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM_NORAIN + {MT_RAIN, PRECIPFX_THUNDER} // PRECIP_STORM_NOSTRIKES }; INT32 cursaveslot = -1; // Auto-save 1p savegame slot diff --git a/src/info.c b/src/info.c index 4542e6c3a..018d354f5 100644 --- a/src/info.c +++ b/src/info.c @@ -11486,7 +11486,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 4*FRACUNIT, // height 0, // display offset 0, // mass - 0, // damage + 2, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags S_NULL // raisestate @@ -11513,7 +11513,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 4*FRACUNIT, // height 0, // display offset 0, // mass - 0, // damage + 2, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags S_NULL // raisestate diff --git a/src/p_mobj.c b/src/p_mobj.c index 87fb7a186..2f514f526 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11005,6 +11005,8 @@ consvar_t cv_suddendeath = {"suddendeath", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHE void P_SpawnPrecipitation(void) { INT32 i, j, k; + mobjtype_t type = precipprops[curWeather].type; + INT32 randomstates = mobjinfo[type].damage; fixed_t basex, basey, x, y, z, height; subsector_t *precipsector = NULL; precipmobj_t *rainmo = NULL; @@ -11049,15 +11051,15 @@ void P_SpawnPrecipitation(void) for (j = 0; j < numparticles; j++) { - rainmo = P_SpawnPrecipMobj(x, y, z, precipprops[curWeather].type); + rainmo = P_SpawnPrecipMobj(x, y, z, type); - if (precipprops[curWeather].randomstates > 0) + if (randomstates > 0 && randomstates < UINT8_MAX) { UINT8 mrand = M_RandomByte(); - UINT8 threshold = UINT8_MAX / (precipprops[curWeather].randomstates + 1); - statenum_t st = mobjinfo[precipprops[curWeather].type].spawnstate; + UINT8 threshold = UINT8_MAX / (randomstates + 1); + statenum_t st = mobjinfo[type].spawnstate; - for (k = 0; k < precipprops[curWeather].randomstates; k++) + for (k = 0; k < randomstates; k++) { if (mrand < (threshold * (k+1))) { diff --git a/src/p_spec.c b/src/p_spec.c index d92fb2f3b..1cca2cd5e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2041,6 +2041,7 @@ void P_SwitchWeather(UINT8 newWeather) } else if (swap != MT_NULL) // Rather than respawn all that crap, reuse it! { + INT32 randomstates = mobjinfo[swap].damage; thinker_t *think; precipmobj_t *precipmobj; statenum_t st; @@ -2056,13 +2057,13 @@ void P_SwitchWeather(UINT8 newWeather) st = mobjinfo[swap].spawnstate; - if (precipprops[curWeather].randomstates > 0) + if (randomstates > 0 && randomstates < UINT8_MAX) { UINT8 mrand = M_RandomByte(); - UINT8 threshold = UINT8_MAX / (precipprops[curWeather].randomstates + 1); + UINT8 threshold = UINT8_MAX / (randomstates + 1); UINT8 i; - for (i = 0; i < precipprops[curWeather].randomstates; i++) + for (i = 0; i < randomstates; i++) { if (mrand < (threshold * (i+1))) { From 76e75d9756a9e07e66cdb17db84eeb6f76835948 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 1 Mar 2020 14:36:13 -0500 Subject: [PATCH 15/19] Fix offroad collision Adds an option to P_MobjTouchingSectorSpecial to only use non-FOF sectors' special if you're touching their floor/ceiling. --- src/k_kart.c | 2 +- src/lua_baselib.c | 3 ++- src/p_floor.c | 2 +- src/p_inter.c | 2 +- src/p_map.c | 6 ++--- src/p_mobj.c | 16 ++++--------- src/p_spec.c | 61 ++++++++++++++++++++++++++++++++++++++++------- src/p_spec.h | 2 +- 8 files changed, 66 insertions(+), 28 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 6c268269d..cb82dba93 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1542,7 +1542,7 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo) for (i = 2; i < 5; i++) { - if (P_MobjTouchingSectorSpecial(mo, 1, i)) + if (P_MobjTouchingSectorSpecial(mo, 1, i, true)) return i-1; } diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 3d836dad2..bb7d1111b 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1318,10 +1318,11 @@ static int lib_pMobjTouchingSectorSpecial(lua_State *L) mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); INT32 section = (INT32)luaL_checkinteger(L, 2); INT32 number = (INT32)luaL_checkinteger(L, 3); + boolean touchground = lua_optboolean(L, 4); //HUDSAFE if (!mo) return LUA_ErrInvalid(L, "mobj_t"); - LUA_PushUserdata(L, P_MobjTouchingSectorSpecial(mo, section, number), META_SECTOR); + LUA_PushUserdata(L, P_MobjTouchingSectorSpecial(mo, section, number, touchground), META_SECTOR); return 1; } diff --git a/src/p_floor.c b/src/p_floor.c index a4e4f2747..3621e0886 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2275,7 +2275,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) continue; if (!(players[i].mo->subsector->sector == sec - || P_MobjTouchingSectorSpecial(players[i].mo, 2, (GETSECSPECIAL(sec->special, 2))) == sec)) + || P_MobjTouchingSectorSpecial(players[i].mo, 2, (GETSECSPECIAL(sec->special, 2)), false) == sec)) continue; if (floortouch == true && P_IsObjectOnRealGround(players[i].mo, sec)) diff --git a/src/p_inter.c b/src/p_inter.c index a1a44c998..b81d3296d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -925,7 +925,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->fuse = 1; special->flags2 |= MF2_JUSTATTACKED; - if (!P_MobjTouchingSectorSpecial(player->mo, 4, 2 + flagteam)) + if (!P_MobjTouchingSectorSpecial(player->mo, 4, 2 + flagteam, false)) { CONS_Printf(M_GetText("%s returned the %c%s%c to base.\n"), plname, flagcolor, flagtext, 0x80); diff --git a/src/p_map.c b/src/p_map.c index 22e624311..19006fe49 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2790,10 +2790,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale); // If using type Section1:13, double the maxstep. - if (P_MobjTouchingSectorSpecial(thing, 1, 13)) + if (P_MobjTouchingSectorSpecial(thing, 1, 13, false)) maxstep <<= 1; // If using type Section1:12, no maxstep. For short walls, like Egg Zeppelin - else if (P_MobjTouchingSectorSpecial(thing, 1, 12)) + else if (P_MobjTouchingSectorSpecial(thing, 1, 12, false)) maxstep = 0; if (thing->type == MT_SKIM) @@ -2817,7 +2817,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) return false; // mobj must lower itself to fit // Ramp test - if ((maxstep > 0) && !(P_MobjTouchingSectorSpecial(thing, 1, 14))) + if ((maxstep > 0) && !(P_MobjTouchingSectorSpecial(thing, 1, 14, false))) { // If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS // step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more. diff --git a/src/p_mobj.c b/src/p_mobj.c index 1fd846ff1..2bb445e73 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8355,7 +8355,7 @@ void P_MobjThinker(mobj_t *mobj) P_Thrust(mobj, mobj->angle, thrustamount); - if (P_MobjTouchingSectorSpecial(mobj, 3, 1)) + if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) K_DoPogoSpring(mobj, 0, 1); if (mobj->threshold > 0) @@ -8385,7 +8385,7 @@ void P_MobjThinker(mobj_t *mobj) K_DriftDustHandling(mobj); - if (P_MobjTouchingSectorSpecial(mobj, 3, 1)) + if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) K_DoPogoSpring(mobj, 0, 1); break; @@ -8437,14 +8437,8 @@ void P_MobjThinker(mobj_t *mobj) mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); P_Thrust(mobj, mobj->angle, thrustamount); - if (grounded) - { - sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) - || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) - && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) - K_DoPogoSpring(mobj, 0, 1); - } + if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) + K_DoPogoSpring(mobj, 0, 1); if (mobj->threshold > 0) mobj->threshold--; @@ -9592,7 +9586,7 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_BLUEFLAG: case MT_REDFLAG: - if (P_MobjTouchingSectorSpecial(mobj, 4, 2)) + if (P_MobjTouchingSectorSpecial(mobj, 4, 2, false)) mobj->fuse = 1; // Return to base. break; case MT_CANNONBALL: diff --git a/src/p_spec.c b/src/p_spec.c index 7786329ec..9ce9c9faf 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3371,11 +3371,12 @@ boolean P_IsFlagAtBase(mobjtype_t flag) // the particular type that it finds. // Returns NULL if it doesn't find it. // -// Sal: There was absolutely no reason for -// this to be a player_t only function. +// Sal: Couldn't see a reason for this to +// be a player_t only function. // -sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number) +sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number, boolean touchground) { + fixed_t topheight, bottomheight; msecnode_t *node; ffloor_t *rover; @@ -3384,13 +3385,34 @@ sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number) // Check default case first if (GETSECSPECIAL(mo->subsector->sector->special, section) == number) - return mo->subsector->sector; + { + if (touchground) + { + topheight = P_GetSpecialTopZ(mo, mo->subsector->sector, mo->subsector->sector); + bottomheight = P_GetSpecialBottomZ(mo, mo->subsector->sector, mo->subsector->sector); + + // Thing must be on top of the floor to be affected... + if (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR) + { + if (!(mo->eflags & MFE_VERTICALFLIP) && mo->z <= bottomheight) + return mo->subsector->sector; + } + + if (mo->subsector->sector->flags & SF_FLIPSPECIAL_CEILING) + { + if ((mo->eflags & MFE_VERTICALFLIP) && mo->z + mo->height >= topheight) + return mo->subsector->sector; + } + } + else + { + return mo->subsector->sector; + } + } // Hmm.. maybe there's a FOF that has it... for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) { - fixed_t topheight, bottomheight; - if (GETSECSPECIAL(rover->master->frontsector->special, section) != number) continue; @@ -3444,14 +3466,35 @@ sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number) // are we allowed to touch it? if (node->m_sector == mo->subsector->sector || (node->m_sector->flags & SF_TRIGGERSPECIAL_TOUCH)) - return node->m_sector; + { + if (touchground) + { + topheight = P_GetSpecialTopZ(mo, node->m_sector, node->m_sector); + bottomheight = P_GetSpecialBottomZ(mo, node->m_sector, node->m_sector); + + // Thing must be on top of the floor to be affected... + if (node->m_sector->flags & SF_FLIPSPECIAL_FLOOR) + { + if (!(mo->eflags & MFE_VERTICALFLIP) && mo->z <= bottomheight) + return node->m_sector; + } + + if (node->m_sector->flags & SF_FLIPSPECIAL_CEILING) + { + if ((mo->eflags & MFE_VERTICALFLIP) && mo->z + mo->height >= topheight) + return node->m_sector; + } + } + else + { + return node->m_sector; + } + } } // Hmm.. maybe there's a FOF that has it... for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - fixed_t topheight, bottomheight; - if (GETSECSPECIAL(rover->master->frontsector->special, section) != number) continue; diff --git a/src/p_spec.h b/src/p_spec.h index 8431fcc75..eff7463ca 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -37,7 +37,7 @@ void P_SpawnSpecials(INT32 fromnetsave); // every tic void P_UpdateSpecials(void); -sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number); +sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number, boolean touchground); void P_PlayerInSpecialSector(player_t *player); void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector); From 0c1d0d8f5c74fb159a8935882375e481543c30c5 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 1 Mar 2020 14:56:16 -0500 Subject: [PATCH 16/19] Don't need abs here --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 2f514f526..1f2e5e3de 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11037,7 +11037,7 @@ void P_SpawnPrecipitation(void) if (precipsector->sector->ceilingpic != skyflatnum) continue; - height = abs(precipsector->sector->ceilingheight - precipsector->sector->floorheight); + height = precipsector->sector->ceilingheight - precipsector->sector->floorheight; // Exists, but is too small for reasonable precipitation. if (height < 64< Date: Tue, 3 Mar 2020 17:05:04 -0500 Subject: [PATCH 17/19] Fix unsigned/signed comparison --- src/p_mobj.c | 4 ++-- src/p_spec.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1f2e5e3de..7533e8fc5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11006,7 +11006,7 @@ void P_SpawnPrecipitation(void) { INT32 i, j, k; mobjtype_t type = precipprops[curWeather].type; - INT32 randomstates = mobjinfo[type].damage; + UINT8 randomstates = (UINT8)mobjinfo[type].damage; fixed_t basex, basey, x, y, z, height; subsector_t *precipsector = NULL; precipmobj_t *rainmo = NULL; @@ -11053,7 +11053,7 @@ void P_SpawnPrecipitation(void) { rainmo = P_SpawnPrecipMobj(x, y, z, type); - if (randomstates > 0 && randomstates < UINT8_MAX) + if (randomstates > 0) { UINT8 mrand = M_RandomByte(); UINT8 threshold = UINT8_MAX / (randomstates + 1); diff --git a/src/p_spec.c b/src/p_spec.c index 1cca2cd5e..953503f9d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2041,7 +2041,7 @@ void P_SwitchWeather(UINT8 newWeather) } else if (swap != MT_NULL) // Rather than respawn all that crap, reuse it! { - INT32 randomstates = mobjinfo[swap].damage; + UINT8 randomstates = (UINT8)mobjinfo[swap].damage; thinker_t *think; precipmobj_t *precipmobj; statenum_t st; @@ -2057,7 +2057,7 @@ void P_SwitchWeather(UINT8 newWeather) st = mobjinfo[swap].spawnstate; - if (randomstates > 0 && randomstates < UINT8_MAX) + if (randomstates > 0) { UINT8 mrand = M_RandomByte(); UINT8 threshold = UINT8_MAX / (randomstates + 1); From d459407866625e3c3d7fc102a5bcc330080a6a88 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Tue, 3 Mar 2020 17:22:13 -0500 Subject: [PATCH 18/19] Forgotten player check here --- src/p_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index 4f39319a6..9e34e04d9 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2790,7 +2790,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) const fixed_t maxstepmove = FixedMul(MAXSTEPMOVE, mapobjectscale); fixed_t maxstep = maxstepmove; - if (thing->player->kartstuff[k_waterskip]) + if (thing->player && thing->player->kartstuff[k_waterskip]) maxstep += maxstepmove; // Add some extra stepmove when waterskipping // If using type Section1:13, double the maxstep. From 11930b41bf704f68d7d6594e1a6e992603235d37 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 3 Mar 2020 20:11:03 -0800 Subject: [PATCH 19/19] Use tic_t --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 28a519694..308eb2616 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5433,7 +5433,7 @@ static tic_t gametime = 0; static void UpdatePingTable(void) { - int fastest; + tic_t fastest; tic_t lag; INT32 i;