From ede66a663280150637c2adbbcdb29b9879ee2adb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 31 May 2020 21:23:22 -0400 Subject: [PATCH 01/99] Trick panels --- src/d_clisrv.c | 4 ++ src/d_clisrv.h | 2 + src/d_player.h | 3 +- src/dehacked.c | 1 - src/k_kart.c | 145 +++++++++++++++++++++++++++----------------- src/lua_playerlib.c | 8 +++ src/p_enemy.c | 2 +- src/p_inter.c | 2 +- src/p_map.c | 15 +++-- src/p_mobj.c | 16 ++--- src/p_saveg.c | 6 ++ src/p_spec.c | 53 ++++++++-------- src/p_user.c | 12 ++-- 13 files changed, 164 insertions(+), 105 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 37e39aadf..e2e44039e 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -575,6 +575,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->kartstuff[j] = LONG(players[i].kartstuff[j]); // SRB2kart rsp->frameangle = (angle_t)LONG(players[i].frameangle); // SRB2kart + rsp->trickpanel = (UINT8)players[i].trickpanel; + rsp->trickdelay = (tic_t)LONG(players[i].trickdelay); // Score is resynched in the rspfirm resync packet rsp->health = 0; // resynched with mo health @@ -705,6 +707,8 @@ static void resynch_read_player(resynch_pak *rsp) players[i].kartstuff[j] = LONG(rsp->kartstuff[j]); // SRB2kart players[i].frameangle = (angle_t)LONG(rsp->frameangle); // SRB2kart + players[i].trickpanel = (UINT8)rsp->trickpanel; + players[i].trickdelay = (tic_t)LONG(rsp->trickdelay); // Score is resynched in the rspfirm resync packet players[i].health = rsp->health; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 1ef85b4f9..ae2c59fbf 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -215,6 +215,8 @@ typedef struct INT32 kartstuff[NUMKARTSTUFF]; // SRB2kart angle_t frameangle; // SRB2kart + UINT8 trickpanel; + tic_t trickdelay; // Score is resynched in the confirm resync packet INT32 health; diff --git a/src/d_player.h b/src/d_player.h index 6ed9fd719..1eea9b6f1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -289,7 +289,6 @@ typedef enum k_sparkleanim, // Angle offset for ring sparkle animation k_jmp, // In Mario Kart, letting go of the jump button stops the drift k_offroad, // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed - k_pogospring, // Pogo spring bounce effect k_brakestop, // Wait until you've made a complete stop for a few tics before letting brake go in reverse. k_waterskip, // Water skipping counter k_dashpadcooldown, // Separate the vanilla SA-style dash pads from using pw_flashing @@ -477,6 +476,8 @@ typedef struct player_s INT16 rturn_max[MAXPREDICTTICS]; // Ditto but for full-right UINT32 distancetofinish; waypoint_t *nextwaypoint; + UINT8 trickpanel; // Trick panel state + tic_t trickdelay; // Bit flags. // See pflags_t, above. diff --git a/src/dehacked.c b/src/dehacked.c index ac7c213f7..260cb6f10 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8341,7 +8341,6 @@ static const char *const KARTSTUFF_LIST[] = { "SPARKLEANIM", "JMP", "OFFROAD", - "POGOSPRING", "BRAKESTOP", "WATERSKIP", "DASHPADCOOLDOWN", diff --git a/src/k_kart.c b/src/k_kart.c index e00013128..6a499e1dd 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -978,7 +978,7 @@ static void K_DebtStingPlayer(player_t *player, INT32 length) player->kartstuff[k_driftboost] = 0; player->kartstuff[k_drift] = 0; player->kartstuff[k_driftcharge] = 0; - player->kartstuff[k_pogospring] = 0; + player->trickpanel = 0; player->kartstuff[k_spinouttype] = 2; player->kartstuff[k_spinouttimer] = length; @@ -2416,18 +2416,6 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove oldspeed = p_speed; newspeed = FixedDiv(FixedDiv(FixedMul(oldspeed, accelmax - p_accel) + FixedMul(p_speed, p_accel), accelmax), ORIG_FRICTION); - if (player->kartstuff[k_pogospring]) // Pogo Spring minimum/maximum thrust - { - const fixed_t hscale = mapobjectscale /*+ (mapobjectscale - player->mo->scale)*/; - const fixed_t minspeed = 24*hscale; - const fixed_t maxspeed = 28*hscale; - - if (newspeed > maxspeed && player->kartstuff[k_pogospring] == 2) - newspeed = maxspeed; - if (newspeed < minspeed) - newspeed = minspeed; - } - finalspeed = newspeed - oldspeed; // forwardmove is: @@ -2526,7 +2514,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto player->kartstuff[k_drift] = 0; player->kartstuff[k_driftcharge] = 0; - player->kartstuff[k_pogospring] = 0; + player->trickpanel = 0; if (G_BattleGametype()) { @@ -2673,7 +2661,7 @@ void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor) player->kartstuff[k_drift] = 0; player->kartstuff[k_driftcharge] = 0; - player->kartstuff[k_pogospring] = 0; + player->trickpanel = 0; if (G_BattleGametype()) { @@ -2800,7 +2788,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b player->kartstuff[k_drift] = 0; player->kartstuff[k_driftcharge] = 0; - player->kartstuff[k_pogospring] = 0; + player->trickpanel = 0; // This is the only part that SHOULDN'T combo :VVVVV if (G_BattleGametype() && !(player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinouttype] != 2))) @@ -4335,10 +4323,10 @@ static void K_DoShrink(player_t *user) } } - void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) { const fixed_t vscale = mapobjectscale + (mo->scale - mapobjectscale); + fixed_t thrust = 0; if (mo->player && mo->player->spectator) return; @@ -4352,47 +4340,39 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) mo->eflags |= MFE_SPRUNG; - if (mo->eflags & MFE_VERTICALFLIP) - vertispeed *= -1; - if (vertispeed == 0) { - fixed_t thrust; - - if (mo->player) - { - thrust = 3*mo->player->speed/2; - if (thrust < 48< 72<player->kartstuff[k_pogospring] != 2) - { - if (EITHERSNEAKER(mo->player)) - thrust = FixedMul(thrust, (5*FRACUNIT)/4); - else if (mo->player->kartstuff[k_invincibilitytimer]) - thrust = FixedMul(thrust, (9*FRACUNIT)/8); - } - } - else - { - thrust = FixedDiv(3*P_AproxDistance(mo->momx, mo->momy)/2, 5*FRACUNIT/2); - if (thrust < 16< 32<momz = P_MobjFlip(mo)*FixedMul(FINESINE(ANGLE_22h>>ANGLETOFINESHIFT), FixedMul(thrust, vscale)); + thrust = P_AproxDistance(mo->momx, mo->momy) * P_MobjFlip(mo); + thrust = FixedMul(thrust, FINESINE(ANGLE_22h >> ANGLETOFINESHIFT)); } else - mo->momz = FixedMul(vertispeed, vscale); + { + thrust = vertispeed * P_MobjFlip(mo); + } + + if (mo->player) + { + if (EITHERSNEAKER(mo->player)) + { + thrust = FixedMul(thrust, 5*FRACUNIT/4); + } + else if (mo->player->kartstuff[k_invincibilitytimer]) + { + thrust = FixedMul(thrust, 9*FRACUNIT/8); + } + } + + mo->momz = FixedMul(thrust, vscale); if (mo->eflags & MFE_UNDERWATER) - mo->momz = (117 * mo->momz) / 200; + { + mo->momz = FixedDiv(mo->momz, FixedSqrt(3*FRACUNIT)); + } if (sound) + { S_StartSound(mo, (sound == 1 ? sfx_kc2f : sfx_kpogos)); + } } void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source) @@ -5994,10 +5974,12 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_comebacktimer]) player->kartstuff[k_comebackmode] = 0; - if (P_IsObjectOnGround(player->mo) && player->kartstuff[k_pogospring]) + if (P_IsObjectOnGround(player->mo) && player->trickpanel != 0) { - if (P_MobjFlip(player->mo)*player->mo->momz <= 0) - player->kartstuff[k_pogospring] = 0; + if (P_MobjFlip(player->mo) * player->mo->momz <= 0) + { + player->trickpanel = 0; + } } if (cmd->buttons & BT_DRIFT) @@ -6519,6 +6501,11 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) return turnvalue; } + if (player->trickpanel != 0) + { + return 0; + } + if (K_PlayerUsesBotMovement(player)) { turnvalue = 5*turnvalue/4; // Base increase to turning @@ -7512,12 +7499,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } break; case KITEM_POGOSPRING: - if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO - && !player->kartstuff[k_pogospring]) + if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO && player->trickpanel == 0) { K_PlayBoostTaunt(player->mo); K_DoPogoSpring(player->mo, 32<kartstuff[k_pogospring] = 1; + player->trickpanel = 1; + player->trickdelay = TICRATE/2; player->kartstuff[k_itemamount]--; } break; @@ -7656,6 +7643,54 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { player->mo->flags2 &= ~MF2_SHADOW; } + + if (player->trickpanel == 1 && player->trickdelay <= 0) + { + const angle_t lr = ANGLE_45; + fixed_t speed = P_AproxDistance(player->mo->momx, player->mo->momy); + + if (cmd->driftturn > 0) + { + P_InstaThrust(player->mo, player->mo->angle + lr, speed*2); + player->trickpanel = 2; + } + else if (cmd->driftturn < 0) + { + P_InstaThrust(player->mo, player->mo->angle - lr, speed*2); + player->trickpanel = 3; + } + else if (player->kartstuff[k_throwdir] == 1) + { + if (player->mo->momz * P_MobjFlip(player->mo) > 0) + { + player->mo->momz = 0; + } + + P_InstaThrust(player->mo, player->mo->angle, speed*3); + player->trickpanel = 2; + } + else if (player->kartstuff[k_throwdir] == -1) + { + boolean relative = true; + + player->mo->momx /= 3; + player->mo->momy /= 3; + + if (player->mo->momz * P_MobjFlip(player->mo) <= 0) + { + relative = false; + } + + P_SetObjectMomZ(player->mo, 24*FRACUNIT, relative); + + player->trickpanel = 3; + } + } + + if (player->trickdelay > 0) + { + player->trickdelay--; + } } if (onground) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 433803648..b81ee3941 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -216,6 +216,10 @@ static int player_get(lua_State *L) LUA_PushUserdata(L, plr->kartstuff, META_KARTSTUFF); else if (fastcmp(field,"frameangle")) lua_pushangle(L, plr->frameangle); + else if (fastcmp(field,"trickpanel")) + lua_pushinteger(L, plr->trickpanel); + else if (fastcmp(field,"trickdelay")) + lua_pushinteger(L, plr->trickdelay); else if (fastcmp(field,"pflags")) lua_pushinteger(L, plr->pflags); else if (fastcmp(field,"panim")) @@ -483,6 +487,10 @@ static int player_set(lua_State *L) return NOSET; else if (fastcmp(field,"frameangle")) plr->frameangle = luaL_checkangle(L, 3); + else if (fastcmp(field,"trickpanel")) + plr->trickpanel = luaL_checkinteger(L, 3); + else if (fastcmp(field,"trickdelay")) + plr->trickdelay = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"kartspeed")) plr->kartspeed = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"kartweight")) diff --git a/src/p_enemy.c b/src/p_enemy.c index b05d0bc68..70708c9bf 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8650,7 +8650,7 @@ void A_SPBChase(mobj_t *actor) actor->lastlook = actor->tracer->player-players; // Save the player num for death scumming... actor->tracer->player->kartstuff[k_ringlock] = 1; // set ring lock - if (!P_IsObjectOnGround(actor->tracer) /*&& !actor->tracer->player->kartstuff[k_pogospring]*/) + if (!P_IsObjectOnGround(actor->tracer)) { // In the air you have no control; basically don't hit unless you make a near complete stop defspeed = (7 * actor->tracer->player->speed) / 8; diff --git a/src/p_inter.c b/src/p_inter.c index 959e0453a..26ec310ad 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2324,7 +2324,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) else*/ if (G_BattleGametype()) K_CheckBumpers(); - target->player->kartstuff[k_pogospring] = 0; + target->player->trickpanel = 0; } if (source && target && target->player && source->player) diff --git a/src/p_map.c b/src/p_map.c index d635c4a6d..b866aee01 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -469,9 +469,14 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) { if (object->eflags & MFE_SPRUNG) break; + if (object->player) - object->player->kartstuff[k_pogospring] = 1; - K_DoPogoSpring(object, 0, 0); + { + object->player->trickpanel = 1; + object->player->trickdelay = TICRATE/2; + } + + K_DoPogoSpring(object, 32<player->kartstuff[k_pogospring]) + if (G_BattleGametype() && tmthing->player->trickpanel) { K_StealBumper(tmthing->player, thing->player, false); K_SpinPlayer(thing->player, tmthing, 0, tmthing, false); @@ -1472,7 +1477,7 @@ static boolean PIT_CheckThing(mobj_t *thing) { zbounce = true; - if (G_BattleGametype() && thing->player->kartstuff[k_pogospring]) + if (G_BattleGametype() && thing->player->trickpanel) { K_StealBumper(thing->player, tmthing->player, false); K_SpinPlayer(tmthing->player, thing, 0, thing, false); @@ -3558,7 +3563,7 @@ void P_BouncePlayerMove(mobj_t *mo) mmomx = mo->player->rmomx; mmomy = mo->player->rmomy; - mo->player->kartstuff[k_pogospring] = 0; + mo->player->trickpanel = 0; // trace along the three leading corners if (mo->momx > 0) diff --git a/src/p_mobj.c b/src/p_mobj.c index 221b38f8d..13be9759b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1279,15 +1279,15 @@ fixed_t P_GetMobjGravity(mobj_t *mo) P_PlayerFlip(mo); } - if (mo->player->kartstuff[k_pogospring]) - { - gravityadd = (5*gravityadd)/2; - } - if (mo->player->kartstuff[k_waterskip]) { gravityadd = (4*gravityadd)/3; } + + if (mo->player->trickpanel == 2 || mo->player->trickpanel == 3) + { + gravityadd = (5*gravityadd)/2; + } } else { @@ -8054,7 +8054,7 @@ void P_MobjThinker(mobj_t *mobj) P_Thrust(mobj, mobj->angle, thrustamount); if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) - K_DoPogoSpring(mobj, 0, 1); + K_DoPogoSpring(mobj, 32<threshold > 0) mobj->threshold--; @@ -8084,7 +8084,7 @@ void P_MobjThinker(mobj_t *mobj) K_DriftDustHandling(mobj); if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) - K_DoPogoSpring(mobj, 0, 1); + K_DoPogoSpring(mobj, 32<angle, thrustamount); if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) - K_DoPogoSpring(mobj, 0, 1); + K_DoPogoSpring(mobj, 32<threshold > 0) mobj->threshold--; diff --git a/src/p_saveg.c b/src/p_saveg.c index 5aa988075..f92ce0c71 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -269,6 +269,9 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].distancetofinish); WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); + WRITEUINT8(save_p, players[i].trickpanel); + WRITEUINT32(save_p, players[i].trickdelay); + WRITEUINT8(save_p, players[i].botvars.difficulty); WRITEUINT32(save_p, players[i].botvars.itemdelay); WRITEUINT32(save_p, players[i].botvars.itemconfirm); @@ -445,6 +448,9 @@ static void P_NetUnArchivePlayers(void) players[i].distancetofinish = READUINT32(save_p); players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p); + players[i].trickpanel = READUINT8(save_p); + players[i].trickdelay = READUINT32(save_p); + players[i].botvars.difficulty = READUINT8(save_p); players[i].botvars.itemdelay = READUINT32(save_p); players[i].botvars.itemconfirm = READUINT32(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index 8678f31cc..114a82a00 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4004,49 +4004,46 @@ DoneSection2: switch (special) { case 1: // SRB2kart: Spring Panel + case 3: if (roversector || P_MobjReadyToTrigger(player->mo, sector)) { const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale); const fixed_t minspeed = 24*hscale; - angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle; + fixed_t speed = FixedHypot(player->mo->momx, player->mo->momy); + fixed_t upwards = 32*FRACUNIT; + angle_t pushangle = (speed ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle); // if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0 if (player->mo->eflags & MFE_SPRUNG) + { break; + } - if (player->speed < minspeed) // Push forward to prevent getting stuck - P_InstaThrust(player->mo, pushangle, minspeed); + if (special == 3) + { + upwards /= 2; + } - player->kartstuff[k_pogospring] = 1; - K_DoPogoSpring(player->mo, 0, 1); + player->trickpanel = 1; + player->trickdelay = TICRATE/2; + K_DoPogoSpring(player->mo, upwards, 1); + + // Reduce speed + speed /= 2; + + if (speed < minspeed) + { + speed = minspeed; + } + + player->mo->angle = pushangle; + P_InstaThrust(player->mo, pushangle, speed); } break; case 2: // Wind/Current break; - case 3: // SRB2kart: Spring Panel (capped speed) - if (roversector || P_MobjReadyToTrigger(player->mo, sector)) - { - const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale); - const fixed_t minspeed = 24*hscale; - const fixed_t maxspeed = 28*hscale; - angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle; - // if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0 - - if (player->mo->eflags & MFE_SPRUNG) - break; - - if (player->speed > maxspeed) // Prevent overshooting jumps - P_InstaThrust(player->mo, pushangle, maxspeed); - else if (player->speed < minspeed) // Push forward to prevent getting stuck - P_InstaThrust(player->mo, pushangle, minspeed); - - player->kartstuff[k_pogospring] = 2; - K_DoPogoSpring(player->mo, 0, 1); - } - break; - case 4: // Conveyor Belt break; @@ -4089,7 +4086,7 @@ DoneSection2: P_InstaThrust(player->mo, lineangle, linespeed); player->kartstuff[k_dashpadcooldown] = TICRATE/3; - player->kartstuff[k_pogospring] = 0; + player->trickpanel = 0; S_StartSound(player->mo, sfx_spdpad); { diff --git a/src/p_user.c b/src/p_user.c index 28273ca82..47c12fa27 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4019,8 +4019,7 @@ static void P_3dMovement(player_t *player) cmd->forwardmove = cmd->sidemove = 0; } - if (!(player->pflags & PF_FORCESTRAFE) && !player->kartstuff[k_pogospring]) - cmd->sidemove = 0; + cmd->sidemove = 0; // TODO: Remove sidemove entirely if (player->kartstuff[k_drift] != 0) movepushangle = player->mo->angle-(ANGLE_45/5)*player->kartstuff[k_drift]; @@ -4088,8 +4087,7 @@ static void P_3dMovement(player_t *player) cmd->forwardmove = 0; // Do not let the player control movement if not onground. - // SRB2Kart: pogo spring and speed bumps are supposed to control like you're on the ground - onground = (P_IsObjectOnGround(player->mo) || (player->kartstuff[k_pogospring])); + onground = P_IsObjectOnGround(player->mo); player->aiming = cmd->aiming<kartstuff[k_pogospring]) + if (player->trickpanel == 2) { player->frameangle += ANGLE_22h; } + else if (player->trickpanel == 3) + { + player->frameangle -= ANGLE_22h; + } else { player->frameangle = player->mo->angle; From a4217c7fd1509d07cdfd6361634b351971809f2c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 5 Jun 2020 18:38:07 -0400 Subject: [PATCH 02/99] Make back trick stronger --- 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 6a499e1dd..af0cfcb6e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7681,7 +7681,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) relative = false; } - P_SetObjectMomZ(player->mo, 24*FRACUNIT, relative); + P_SetObjectMomZ(player->mo, 48*FRACUNIT, relative); player->trickpanel = 3; } From 180a49dfc78e37d39d5e3eb621dee81b8db46bf2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 5 Jun 2020 18:43:53 -0400 Subject: [PATCH 03/99] Don't allow tricks until you go back to neutral --- src/k_kart.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index d6608b070..660b5e278 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7317,6 +7317,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->trickdelay > 0) { player->trickdelay--; + + if ((player->kartstuff[k_throwdir] != 0 || cmd->driftturn != 0) && player->trickdelay <= 0) + { + // Don't allow a trick until you go back to neutral + player->trickdelay = 1; + } } } From 0cb5ddd01d1c49c078cd668c00c7e00fe56574f5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 5 Jun 2020 19:30:06 -0400 Subject: [PATCH 04/99] k_pogospring -> trickpanel --- src/k_respawn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_respawn.c b/src/k_respawn.c index 6c20c8f62..f49ca3cf8 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -105,7 +105,7 @@ void K_DoIngameRespawn(player_t *player) player->kartstuff[k_driftboost] = 0; player->kartstuff[k_drift] = 0; player->kartstuff[k_driftcharge] = 0; - player->kartstuff[k_pogospring] = 0; + player->trickpanel = 0; // Set up respawn position if invalid if (player->respawn.wp != NULL) From 434f0a9df2ac8fc8b240628183df88ba225e2101 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 5 Jul 2020 16:58:26 -0400 Subject: [PATCH 05/99] Use facing angle --- src/p_spec.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index f153633ec..927fd71f0 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4011,8 +4011,6 @@ DoneSection2: const fixed_t minspeed = 24*hscale; fixed_t speed = FixedHypot(player->mo->momx, player->mo->momy); fixed_t upwards = 32*FRACUNIT; - angle_t pushangle = (speed ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle); - // if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0 if (player->mo->eflags & MFE_SPRUNG) { @@ -4036,8 +4034,7 @@ DoneSection2: speed = minspeed; } - player->mo->angle = pushangle; - P_InstaThrust(player->mo, pushangle, speed); + P_InstaThrust(player->mo, player->mo->angle, speed); } break; From 7e7e56f0c6b2f1ec15f7bd5f3dd2aea0ba276b47 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 31 Jul 2020 15:46:44 -0400 Subject: [PATCH 06/99] Add distance easing, so it doesn't jitter around too much when you're stuck. --- src/p_user.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 8d6014926..16c54c2e1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7714,17 +7714,40 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } // sets ideal cam pos - dist = camdist; + { + const fixed_t speedthreshold = 48*mapobjectscale; + const fixed_t olddist = P_AproxDistance(mo->x - thiscam->x, mo->y - thiscam->y); - /* player->speed subtracts conveyors, janks up the camera */ - speed = R_PointToDist2(0, 0, player->mo->momx, player->mo->momy); + fixed_t lag, distoffset; - if (speed > K_GetKartSpeed(player, false)) - dist += 4*(speed - K_GetKartSpeed(player, false)); - dist += abs(thiscam->momz)/4; + dist = camdist; - if (player->karthud[khud_boostcam]) - dist -= FixedMul(11*dist/16, player->karthud[khud_boostcam]); + if (player->karthud[khud_boostcam]) + { + dist -= FixedMul(11*dist/16, player->karthud[khud_boostcam]); + } + + speed = P_AproxDistance(P_AproxDistance(mo->momx, mo->momy), mo->momz / 16); + lag = FRACUNIT - ((FixedDiv(speed, speedthreshold) - FRACUNIT) * 2); + + if (lag > FRACUNIT) + { + lag = FRACUNIT; + } + + if (lag < camspeed) + { + lag = camspeed; + } + + distoffset = dist - olddist; + dist = olddist + FixedMul(distoffset, lag); + + if (dist < 0) + { + dist = 0; + } + } if (mo->standingslope) { @@ -8019,7 +8042,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall thiscam->momz = 0; } else if (player->exiting || timeover == 2) + { thiscam->momx = thiscam->momy = thiscam->momz = 0; + } else if (leveltime < introtime) { thiscam->momx = FixedMul(x - thiscam->x, camspeed); From 7ce53ac1045b75184c45e9771bd7e43d3ef631a2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 22 Oct 2020 02:52:33 -0400 Subject: [PATCH 07/99] Add blue spheres Doesn't have animations, and doesn't have stat-specific buffs. But it's already a massive improvement --- src/d_clisrv.c | 2 ++ src/d_clisrv.h | 1 + src/d_player.h | 1 + src/doomstat.h | 32 ++++++++++++------------ src/g_game.c | 10 +++++--- src/info.c | 30 +++++++++++------------ src/info.h | 2 +- src/k_kart.c | 21 +++++++++++++++- src/lua_playerlib.c | 4 +++ src/p_floor.c | 2 +- src/p_inter.c | 14 ++++++++++- src/p_mobj.c | 59 +++++++++++++++++++++------------------------ src/p_saveg.c | 2 ++ 13 files changed, 111 insertions(+), 69 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index bbf115124..867a3e006 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -545,6 +545,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) // Score is resynched in the rspfirm resync packet rsp->rings = SHORT(players[i].rings); + rsp->spheres = SHORT(players[i].spheres); rsp->lives = players[i].lives; rsp->lostlife = players[i].lostlife; rsp->continues = players[i].continues; @@ -689,6 +690,7 @@ static void resynch_read_player(resynch_pak *rsp) // Score is resynched in the rspfirm resync packet players[i].rings = SHORT(rsp->rings); + players[i].spheres = SHORT(rsp->spheres); players[i].lives = rsp->lives; players[i].lostlife = rsp->lostlife; players[i].continues = rsp->continues; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 2f1caa82e..573c98dc8 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -214,6 +214,7 @@ typedef struct // Score is resynched in the confirm resync packet INT16 rings; + INT16 spheres; SINT8 lives; boolean lostlife; SINT8 continues; diff --git a/src/d_player.h b/src/d_player.h index 283196e4d..36829fecc 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -497,6 +497,7 @@ typedef struct player_s // player's ring count INT16 rings; + INT16 spheres; // Power ups. invinc and invis are tic counters. UINT16 powers[NUMPOWERS]; diff --git a/src/doomstat.h b/src/doomstat.h index 7356a8c18..675318c22 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -461,30 +461,30 @@ enum GameTypeRules { // Race rules GTR_CIRCUIT = 1, // Enables the finish line, laps, and the waypoint system. - GTR_RINGS = 1<<1, // Rings will be spawned in this mode. (Don't get too cheeky, ring sting is still enabled :]) GTR_BOTS = 1<<2, // Allows bots in this gametype. Combine with BotTiccmd hooks to make bots support your gametype. // Battle gametype rules - GTR_BUMPERS = 1<<3, // Enables the bumper health system - GTR_WANTED = 1<<4, // Enables the wanted anti-camping system - GTR_KARMA = 1<<5, // Enables the Karma system if you're out of bumpers - GTR_ITEMARROWS = 1<<6, // Show item box arrows above players - GTR_CAPSULES = 1<<7, // Enables the wanted anti-camping system - GTR_BATTLESTARTS = 1<<8, // Use Battle Mode start positions. + GTR_SPHERES = 1<<3, // Replaces rings with blue spheres + GTR_BUMPERS = 1<<4, // Enables the bumper health system + GTR_WANTED = 1<<5, // Enables the wanted anti-camping system + GTR_KARMA = 1<<6, // Enables the Karma system if you're out of bumpers + GTR_ITEMARROWS = 1<<7, // Show item box arrows above players + GTR_CAPSULES = 1<<8, // Enables the wanted anti-camping system + GTR_BATTLESTARTS = 1<<9, // Use Battle Mode start positions. - GTR_POINTLIMIT = 1<<9, // Reaching point limit ends the round - GTR_TIMELIMIT = 1<<10, // Reaching time limit ends the round - GTR_OVERTIME = 1<<11, // Allow overtime behavior + GTR_POINTLIMIT = 1<<10, // Reaching point limit ends the round + GTR_TIMELIMIT = 1<<11, // Reaching time limit ends the round + GTR_OVERTIME = 1<<12, // Allow overtime behavior // Custom gametype rules - GTR_TEAMS = 1<<12, // Teams are forced on - GTR_NOTEAMS = 1<<13, // Teams are forced off - GTR_TEAMSTARTS = 1<<14, // Use team-based start positions + GTR_TEAMS = 1<<13, // Teams are forced on + GTR_NOTEAMS = 1<<14, // Teams are forced off + GTR_TEAMSTARTS = 1<<15, // Use team-based start positions // Grand Prix rules - GTR_CAMPAIGN = 1<<15, // Handles cup-based progression - GTR_LIVES = 1<<16, // Lives system, players are forced to spectate during Game Over. - GTR_SPECIALBOTS = 1<<17, // Bot difficulty gets stronger between rounds, and the rival system is enabled. + GTR_CAMPAIGN = 1<<16, // Handles cup-based progression + GTR_LIVES = 1<<17, // Lives system, players are forced to spectate during Game Over. + GTR_SPECIALBOTS = 1<<18, // Bot difficulty gets stronger between rounds, and the rival system is enabled. // free: to and including 1<<31 }; diff --git a/src/g_game.c b/src/g_game.c index 6757fb2af..7b91c0e85 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2056,6 +2056,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) UINT8 botdifficulty; INT16 rings; + INT16 spheres; angle_t playerangleturn; UINT8 botdiffincrease; @@ -2140,7 +2141,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) itemamount = 0; growshrinktimer = 0; bumper = ((gametyperules & GTR_BUMPERS) ? K_StartingBumperCount() : 0); - rings = ((gametyperules & GTR_RINGS) ? 5 : 0); + rings = ((gametyperules & GTR_SPHERES) ? 0 : 5); + spheres = 0; comebackpoints = 0; wanted = 0; } @@ -2168,6 +2170,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) bumper = players[player].kartstuff[k_bumper]; rings = players[player].rings; + spheres = players[player].spheres; comebackpoints = players[player].kartstuff[k_comebackpoints]; wanted = players[player].kartstuff[k_wanted]; } @@ -2216,6 +2219,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->bot = bot; p->botvars.difficulty = botdifficulty; p->rings = rings; + p->spheres = spheres; p->botvars.diffincrease = botdiffincrease; p->botvars.rival = botrival; p->xtralife = xtralife; @@ -2788,9 +2792,9 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] = UINT32 gametypedefaultrules[NUMGAMETYPES] = { // Race - GTR_CIRCUIT|GTR_RINGS|GTR_BOTS, + GTR_CIRCUIT|GTR_BOTS, // Battle - GTR_BUMPERS|GTR_WANTED|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME + GTR_SPHERES|GTR_BUMPERS|GTR_WANTED|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME }; // diff --git a/src/info.c b/src/info.c index 6d5bac1ea..d73c13010 100644 --- a/src/info.c +++ b/src/info.c @@ -135,7 +135,7 @@ char sprnames[NUMSPRITES + 1][5] = "TOKE", // Special Stage Token "RFLG", // Red CTF Flag "BFLG", // Blue CTF Flag - //"SPHR", // Sphere + "BSPH", // Sphere "NCHP", // NiGHTS chip "NSTR", // NiGHTS star "EMBM", // Emblem @@ -1800,19 +1800,19 @@ state_t states[NUMSTATES] = {SPR_RING, 22, 1, {NULL}, 0, 0, S_FASTRING1}, // S_FASTRING12 // Blue Sphere for special stages - {SPR_SPHR, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE - {SPR_SPHR, FF_FULLBRIGHT + {SPR_BSPH, FF_SEMIBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE + {SPR_BSPH, FF_FULLBRIGHT #ifdef MANIASPHERES |FF_ANIMATE|FF_RANDOMANIM #endif , -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS - {SPR_SPHR, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK + {SPR_BSPH, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK // Bomb Sphere - {SPR_SPHR, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_BOMBSPHERE2}, // S_BOMBSPHERE1 - {SPR_SPHR, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE3}, // S_BOMBSPHERE2 - {SPR_SPHR, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_BOMBSPHERE4}, // S_BOMBSPHERE3 - {SPR_SPHR, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE1}, // S_BOMBSPHERE4 + {SPR_BSPH, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_BOMBSPHERE2}, // S_BOMBSPHERE1 + {SPR_BSPH, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE3}, // S_BOMBSPHERE2 + {SPR_BSPH, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_BOMBSPHERE4}, // S_BOMBSPHERE3 + {SPR_BSPH, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE1}, // S_BOMBSPHERE4 // NiGHTS Chip {SPR_NCHP, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 15, 2, S_NULL}, // S_NIGHTSCHIP @@ -7923,29 +7923,29 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_BLUESPHERE - 1706, // doomednum + -1, // doomednum S_BLUESPHERE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - MT_FLINGBLUESPHERE, // reactiontime + MT_FLINGBLUESPHERE, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BLUESPHERESPARK, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate sfx_s3k65, // deathsound 38*FRACUNIT, // speed - 16*FRACUNIT, // radius - 24*FRACUNIT, // height + 48*FRACUNIT, // radius + 48*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags S_BLUESPHEREBONUS // raisestate }, @@ -7962,7 +7962,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BLUESPHERESPARK, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate sfx_s3k65, // deathsound 38*FRACUNIT, // speed diff --git a/src/info.h b/src/info.h index e7d53cb5b..4e235c1ba 100644 --- a/src/info.h +++ b/src/info.h @@ -406,7 +406,7 @@ typedef enum sprite SPR_TOKE, // Special Stage Token SPR_RFLG, // Red CTF Flag SPR_BFLG, // Blue CTF Flag - //SPR_SPHR, // Sphere + SPR_BSPH, // Sphere SPR_NCHP, // NiGHTS chip SPR_NSTR, // NiGHTS star SPR_EMBM, // Emblem diff --git a/src/k_kart.c b/src/k_kart.c index 4352ce5c5..a5595b24f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -897,7 +897,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) // SPECIAL CASE No. 4: // Being in ring debt occasionally forces Super Ring on you if you mashed - if ((gametyperules & GTR_RINGS) && mashed && player->rings < 0 && cv_superring.value) + if (!(gametyperules & GTR_SPHERES) && mashed && player->rings < 0 && cv_superring.value) { INT32 debtamount = min(20, abs(player->rings)); if (P_RandomChance((debtamount*FRACUNIT)/20)) @@ -2221,6 +2221,12 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) finalspeed = K_GetKartSpeedFromStat(kartspeed); + if (player->spheres > 0) + { + fixed_t sphereAdd = (FRACUNIT/80); // 50% at max + finalspeed = FixedMul(finalspeed, FRACUNIT + (sphereAdd * player->spheres)); + } + if (K_PlayerUsesBotMovement(player)) { // Give top speed a buff for bots, since it's a fairly weak stat without drifting @@ -2261,6 +2267,11 @@ fixed_t K_GetKartAccel(player_t *player) //k_accel += 3 * (9 - kartspeed); // 36 - 60 k_accel += 4 * (9 - kartspeed); // 32 - 64 + if (player->spheres > 0) + { + fixed_t sphereAdd = (FRACUNIT/10); // 500% at max + k_accel = FixedMul(k_accel, FRACUNIT + (sphereAdd * player->spheres)); + } if (K_PlayerUsesBotMovement(player)) { @@ -5614,6 +5625,14 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) else if (player->rings < -20) player->rings = -20; + if ((leveltime % TICRATE) == 0) + player->spheres--; + + if (player->spheres > 40) + player->spheres = 40; + else if (player->spheres < 0) + player->spheres = 0; + if (player->kartstuff[k_ringdelay]) player->kartstuff[k_ringdelay]--; diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 5b6251e80..119fab345 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -209,6 +209,8 @@ static int player_get(lua_State *L) lua_pushangle(L, plr->drawangle); else if (fastcmp(field,"rings")) lua_pushinteger(L, plr->rings); + else if (fastcmp(field,"spheres")) + lua_pushinteger(L, plr->spheres); else if (fastcmp(field,"powers")) LUA_PushUserdata(L, plr->powers, META_POWERS); else if (fastcmp(field,"kartstuff")) @@ -476,6 +478,8 @@ static int player_set(lua_State *L) plr->drawangle = luaL_checkangle(L, 3); else if (fastcmp(field,"rings")) plr->rings = (INT32)luaL_checkinteger(L, 3); + else if (fastcmp(field,"spheres")) + plr->spheres = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"powers")) return NOSET; else if (fastcmp(field,"pflags")) diff --git a/src/p_floor.c b/src/p_floor.c index f8f7fef2d..0ad27d580 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2371,7 +2371,7 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) P_SetThingPosition(thing); if (thing->flags & MF_SHOOTABLE) P_DamageMobj(thing, puncher, puncher, 1, DMG_NORMAL); - else if (thing->type == MT_RING || thing->type == MT_COIN || thing->type == MT_RANDOMITEM) + else if (thing->type == MT_RING || thing->type == MT_RANDOMITEM) { thing->momz = FixedMul(3*FRACUNIT, thing->scale); P_TouchSpecialThing(thing, puncher, false); diff --git a/src/p_inter.c b/src/p_inter.c index e408c1d27..730e7388d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -553,6 +553,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; + case MT_BLUESPHERE: + if (!(P_CanPickupItem(player, 0))) + return; + + // Reached the cap, don't waste 'em! + if (player->spheres >= 40) + return; + + special->momx = special->momy = special->momz = 0; + player->spheres++; + break; + // Secret emblem thingy case MT_EMBLEM: { @@ -2000,7 +2012,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) fixed_t momxy = 5<shadowscale = FRACUNIT/2; break; case MT_DRIFTCLIP: @@ -9205,8 +9196,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->color = skincolor_blueteam; break; case MT_RING: - case MT_COIN: - case MT_NIGHTSSTAR: if (nummaprings >= 0) nummaprings++; break; @@ -9564,10 +9553,7 @@ void P_RemoveMobj(mobj_t *mobj) // Rings only, please! if (mobj->spawnpoint && (mobj->type == MT_RING - || mobj->type == MT_COIN - || mobj->type == MT_NIGHTSSTAR - || mobj->type == MT_REDTEAMRING - || mobj->type == MT_BLUETEAMRING) + || mobj->type == MT_BLUESPHERE) && !(mobj->flags2 & MF2_DONTRESPAWN)) { itemrespawnque[iquehead] = mobj->spawnpoint; @@ -9979,22 +9965,29 @@ void P_RespawnSpecials(void) pcount++; } - if (pcount == 1) // No respawn when alone - return; - else if (pcount > 1) + if (gametyperules & GTR_SPHERES) { - time = (120 - ((pcount-2) * 10))*TICRATE; - - // If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this. - // 5 lap courses would have more retreaded ground, while 2 lap courses would have less. - if ((mapheaderinfo[gamemap-1]->numlaps != 3) - && !(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE)) - time = (time * 3) / max(1, mapheaderinfo[gamemap-1]->numlaps); - - if (time < 10*TICRATE) + time = ((MAXPLAYERS+1) - pcount) * (2*TICRATE); + } + else + { + if (pcount == 1) // No respawn when alone + return; + else if (pcount > 1) { - // Ensure it doesn't go into absurdly low values - time = 10*TICRATE; + time = (120 - ((pcount-2) * 10))*TICRATE; + + // If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this. + // 5 lap courses would have more retreaded ground, while 2 lap courses would have less. + if ((mapheaderinfo[gamemap-1]->numlaps != 3) + && !(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE)) + time = (time * 3) / max(1, mapheaderinfo[gamemap-1]->numlaps); + + if (time < 10*TICRATE) + { + // Ensure it doesn't go into absurdly low values + time = 10*TICRATE; + } } } @@ -10410,6 +10403,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt case MT_SPIKEBALL: case MT_EMBLEM: case MT_RING: + case MT_BLUESPHERE: offset += mthing->options & MTF_AMBUSH ? 24*mapobjectscale : 0; break; @@ -10516,8 +10510,11 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i) { - // Don't need this for Kart YET! (void)mthing; + + if ((gametyperules & GTR_SPHERES) && (i == MT_RING)) + return MT_BLUESPHERE; + return i; } diff --git a/src/p_saveg.c b/src/p_saveg.c index e2988e4d3..375c37120 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -109,6 +109,7 @@ static void P_NetArchivePlayers(void) WRITEANGLE(save_p, players[i].awayviewaiming); WRITEINT32(save_p, players[i].awayviewtics); WRITEINT16(save_p, players[i].rings); + WRITEINT16(save_p, players[i].spheres); for (j = 0; j < NUMPOWERS; j++) WRITEUINT16(save_p, players[i].powers[j]); @@ -302,6 +303,7 @@ static void P_NetUnArchivePlayers(void) players[i].awayviewaiming = READANGLE(save_p); players[i].awayviewtics = READINT32(save_p); players[i].rings = READINT16(save_p); + players[i].spheres = READINT16(save_p); for (j = 0; j < NUMPOWERS; j++) players[i].powers[j] = READUINT16(save_p); From 7430df5f4f42ce7e84df5a5f38d1b7a039172b37 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 22 Oct 2020 05:36:36 -0400 Subject: [PATCH 08/99] Fix time limit, make overtime kill you instantly and close in faster, remove minimum radius Radius SHOULD be doubled to 8192 to be reasonable... but something gets severely messed up, makes me MAD --- src/d_main.c | 5 ++ src/d_netcmd.c | 7 +-- src/info.c | 2 +- src/k_battle.c | 164 +++++++++++++++++-------------------------------- src/k_battle.h | 2 +- src/k_kart.c | 18 ++---- src/p_inter.c | 14 ++--- src/p_saveg.c | 6 +- 8 files changed, 80 insertions(+), 138 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index bc46fc0a3..f01633eaa 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1544,6 +1544,11 @@ void D_SRB2Main(void) CON_Init(); + memset(timelimits, 0, sizeof(timelimits)); + memset(pointlimits, 0, sizeof(pointlimits)); + + timelimits[GT_BATTLE] = 2; + D_RegisterServerCommands(); D_RegisterClientCommands(); // be sure that this is called before D_CheckNetGame R_RegisterEngineStuff(); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a93e86ac0..6e5d245da 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -460,8 +460,7 @@ consvar_t cv_scrambleonchange = {"scrambleonchange", "Off", CV_NETVAR, teamscram consvar_t cv_itemfinder = {"itemfinder", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, ItemFinder_OnChange, 0, NULL, NULL, 0, 0, NULL}; // Scoring type options -static CV_PossibleValue_t overtime_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Super"}, {0, NULL}}; -consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR|CV_CHEAT, overtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -4311,8 +4310,8 @@ static void TimeLimit_OnChange(void) if (cv_timelimit.value != 0) { - CONS_Printf(M_GetText("Levels will end after %d second%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003 - timelimitintics = cv_timelimit.value * TICRATE; + CONS_Printf(M_GetText("Levels will end after %d minute%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003 + timelimitintics = cv_timelimit.value * (60*TICRATE); // Note the deliberate absence of any code preventing // pointlimit and timelimit from being set simultaneously. diff --git a/src/info.c b/src/info.c index d73c13010..d71631dd1 100644 --- a/src/info.c +++ b/src/info.c @@ -4996,7 +4996,7 @@ state_t states[NUMSTATES] = {SPR_GRES, FF_ANIMATE|FF_PAPERSPRITE, -1, {NULL}, 2, 4, S_NULL}, // S_TIREGREASE {SPR_OTFG, FF_FULLBRIGHT|FF_TRANS50, TICRATE, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEFOG - {SPR_OTFG, 2|FF_FULLBRIGHT|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB + {SPR_OTFG, 1|FF_FULLBRIGHT|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB {SPR_OTFG, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEBEAM {SPR_CAPS, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLECAPSULE_SIDE1 diff --git a/src/k_battle.c b/src/k_battle.c index 98cc10a3b..dda33d553 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -279,110 +279,47 @@ void K_CheckBumpers(void) #define MAXPLANESPERSECTOR (MAXFFLOORS+1)*2 -static void K_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjtype_t type, boolean ceiling) +static void K_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjtype_t type) { UINT8 i; - fixed_t flatz[MAXPLANESPERSECTOR]; - boolean flip[MAXPLANESPERSECTOR]; - UINT8 numflats = 0; - mobj_t *mo; - subsector_t *ss = R_PointInSubsectorOrNull(x, y); - sector_t *sec; - if (!ss) - return; - sec = ss->sector; - - // convoluted stuff JUST to get all of the planes we need to draw orbs on :V - - for (i = 0; i < MAXPLANESPERSECTOR; i++) - flip[i] = false; - - if (sec->floorpic != skyflatnum) + for (i = 0; i <= r_splitscreen; i++) { - flatz[numflats] = P_GetZAt(sec->f_slope, x, y, sec->floorheight); - numflats++; - } - if (sec->ceilingpic != skyflatnum && ceiling) - { - flatz[numflats] = P_GetZAt(sec->c_slope, x, y, sec->ceilingheight) - FixedMul(mobjinfo[type].height, scale); - flip[numflats] = true; - numflats++; - } + player_t *player = &players[displayplayers[i]]; + mobj_t *mo; + INT32 f = 0; - if (sec->ffloors) - { - ffloor_t *rover; - for (rover = sec->ffloors; rover; rover = rover->next) + if (player == NULL || player->mo == NULL || P_MobjWasRemoved(player->mo) == true) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) - continue; - if (*rover->toppic != skyflatnum) - { - flatz[numflats] = P_GetZAt(*rover->t_slope, x, y, *rover->topheight); - numflats++; - } - if (*rover->bottompic != skyflatnum && ceiling) - { - flatz[numflats] = P_GetZAt(*rover->b_slope, x, y, *rover->bottomheight); - flip[numflats] = true; - numflats++; - } - } - } - - if (numflats <= 0) // no flats - return; - - for (i = 0; i < numflats; i++) - { - mo = P_SpawnMobj(x, y, flatz[i], type); - - // Lastly, if this can see the skybox mobj, then... we just wasted our time :V - if (skyboxmo[0] && !P_MobjWasRemoved(skyboxmo[0])) - { - const fixed_t sbz = skyboxmo[0]->z; - fixed_t checkz = sec->floorheight; - - while (checkz < sec->ceilingheight) - { - P_TeleportMove(skyboxmo[0], skyboxmo[0]->x, skyboxmo[0]->y, checkz); - if (P_CheckSight(skyboxmo[0], mo)) - { - P_RemoveMobj(mo); - break; - } - else - checkz += 32*mapobjectscale; - } - - P_TeleportMove(skyboxmo[0], skyboxmo[0]->x, skyboxmo[0]->y, sbz); - - if (P_MobjWasRemoved(mo)) - continue; + continue; } + mo = P_SpawnMobj(x, y, player->mo->z + (player->mo->height / 2), type); P_SetScale(mo, scale); - if (flip[i]) + if (player->mo->eflags & MFE_VERTICALFLIP) { mo->flags2 |= MF2_OBJECTFLIP; mo->eflags |= MFE_VERTICALFLIP; } - switch(type) + mo->drawflags |= (MFD_DONTDRAW & ~(K_GetPlayerDontDrawFlag(player))); + + switch (type) { case MT_OVERTIMEFOG: - mo->destscale = 8*mo->scale; - mo->momz = P_RandomRange(1,8)*mo->scale; + mo->destscale = 8 * mo->scale; + mo->momz = P_RandomRange(1,8) * mo->scale; break; case MT_OVERTIMEORB: - //mo->destscale = mo->scale/4; - mo->frame += ((leveltime/4) % 8); - /*if (battleovertime.enabled < 10*TICRATE) - mo->drawflags |= MFD_SHADOW;*/ mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90; - mo->z += P_RandomRange(0,48) * mo->scale; + + if (leveltime & 1) + f = 3; + else + f = (leveltime / 2) % 3; + + mo->frame += f; break; default: break; @@ -394,7 +331,7 @@ static void K_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjty void K_RunBattleOvertime(void) { - UINT16 i, j; + UINT32 i, j; if (battleovertime.enabled < 10*TICRATE) { @@ -404,14 +341,20 @@ void K_RunBattleOvertime(void) if (battleovertime.enabled == 10*TICRATE) S_StartSound(NULL, sfx_kc40); } - else + else if (battleovertime.radius > 0) { - if (battleovertime.radius > battleovertime.minradius) - battleovertime.radius -= mapobjectscale; + if (battleovertime.radius > 4*mapobjectscale) + battleovertime.radius -= 4*mapobjectscale; else - battleovertime.radius = battleovertime.minradius; + battleovertime.radius = 0; } + if (battleovertime.radius <= 0) + { + return; + } + + /* if (leveltime & 1) { UINT8 transparency = tr_trans50; @@ -430,43 +373,50 @@ void K_RunBattleOvertime(void) beam->frame |= transparency<>FRACBITS / 2));*/ - for (i = 0; i < 16; i++) { j = 0; + while (j < 32) // max attempts { - fixed_t x = battleovertime.x + ((P_RandomRange(-64,64) * 128)<kartstuff[k_bumper] > 0 && !P_PlayerInPain(player) && !player->powers[pw_flashing]) { player->kartstuff[k_wanted]++; - if (battleovertime.enabled >= 10*TICRATE) + + if ((battleovertime.enabled >= 10*TICRATE) && (P_AproxDistance(player->mo->x - battleovertime.x, player->mo->y - battleovertime.y) - (player->mo->radius * 2)) > battleovertime.radius) { - if (P_AproxDistance(player->mo->x - battleovertime.x, player->mo->y - battleovertime.y) > battleovertime.radius) - { - player->kartstuff[k_killfield]++; - if (player->kartstuff[k_killfield] > 4*TICRATE) - { - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL); - //player->kartstuff[k_killfield] = 1; - } - } - else if (player->kartstuff[k_killfield] > 0) - player->kartstuff[k_killfield]--; + P_KillMobj(player->mo, NULL, NULL, DMG_NORMAL); + player->kartstuff[k_bumper] = 0; } } - else if (player->kartstuff[k_killfield] > 0) - player->kartstuff[k_killfield]--; if (P_IsObjectOnGround(player->mo)) player->kartstuff[k_waterskip] = 0; diff --git a/src/p_inter.c b/src/p_inter.c index 730e7388d..7a778a3ab 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -726,7 +726,7 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) } // Easily make it so that overtime works offline -//#define TESTOVERTIMEINFREEPLAY +#define TESTOVERTIMEINFREEPLAY /** Checks if the level timer is over the timelimit and the round should end, * unless you are in overtime. In which case leveltime may stretch out beyond @@ -743,9 +743,6 @@ void P_CheckTimeLimit(void) if (!cv_timelimit.value) return; - if (!(multiplayer || netgame)) - return; - if (battlecapsules) // capsules override any time limit settings return; @@ -766,6 +763,7 @@ void P_CheckTimeLimit(void) { if (!playeringame[i] || players[i].spectator) continue; + if (foundone) { #endif @@ -779,6 +777,8 @@ void P_CheckTimeLimit(void) P_RespawnBattleBoxes(); // FORCE THESE TO BE RESPAWNED FOR THIS!!!!!!! // Find us an item box to center on. + // TO DO: DON'T do this, instead use a specialized center point object + // just use 0,0 if it's not found for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { mobj_t *thismo; @@ -809,15 +809,15 @@ void P_CheckTimeLimit(void) return; } - item->threshold = 70; // Set constant respawn + //item->threshold = 70; // Set constant respawn battleovertime.x = item->x; battleovertime.y = item->y; battleovertime.z = item->z; - battleovertime.radius = 4096*mapobjectscale; - battleovertime.minradius = (cv_overtime.value == 2 ? 40 : 512) * mapobjectscale; + battleovertime.radius = 4096 * mapobjectscale; battleovertime.enabled = 1; S_StartSound(NULL, sfx_kc47); } + return; #ifndef TESTOVERTIMEINFREEPLAY } diff --git a/src/p_saveg.c b/src/p_saveg.c index 375c37120..509d18ec4 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4116,8 +4116,7 @@ static void P_NetArchiveMisc(void) // battleovertime_t WRITEUINT16(save_p, battleovertime.enabled); - WRITEFIXED(save_p, battleovertime.radius); - WRITEFIXED(save_p, battleovertime.minradius); + WRITEUINT16(save_p, battleovertime.radius); WRITEFIXED(save_p, battleovertime.x); WRITEFIXED(save_p, battleovertime.y); WRITEFIXED(save_p, battleovertime.z); @@ -4250,8 +4249,7 @@ static inline boolean P_NetUnArchiveMisc(void) // battleovertime_t battleovertime.enabled = READUINT16(save_p); - battleovertime.radius = READFIXED(save_p); - battleovertime.minradius = READFIXED(save_p); + battleovertime.radius = READUINT16(save_p); battleovertime.x = READFIXED(save_p); battleovertime.y = READFIXED(save_p); battleovertime.z = READFIXED(save_p); From 9ad88cdfa9fc5c44fe8d295d1af0d8a8980272e1 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 22 Oct 2020 17:38:06 -0400 Subject: [PATCH 09/99] Add center point mobj, polish the visual a bit more, reduce the speed that the barrier shrinks --- src/dehacked.c | 12 ++-- src/info.c | 56 +++++------------ src/info.h | 16 ++--- src/k_battle.c | 165 ++++++++++++++++++++++--------------------------- src/k_kart.c | 17 ++++- src/p_inter.c | 52 +++++++--------- 6 files changed, 141 insertions(+), 177 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 2d7b58ac9..c57b8f5bf 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9286,9 +9286,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_TIREGREASE", - "S_OVERTIMEFOG", - "S_OVERTIMEORB", - "S_OVERTIMEBEAM", + "S_OVERTIME_BULB1", + "S_OVERTIME_BULB2", + "S_OVERTIME_LASER", + "S_OVERTIME_CENTER", "S_BATTLECAPSULE_SIDE1", "S_BATTLECAPSULE_SIDE2", @@ -10382,9 +10383,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_SPBDUST", "MT_TIREGREASE", - "MT_OVERTIMEFOG", - "MT_OVERTIMEORB", - "MT_OVERTIMEBEAM", + "MT_OVERTIME_PARTICLE", + "MT_OVERTIME_CENTER", "MT_BATTLECAPSULE", "MT_BATTLECAPSULE_PIECE", diff --git a/src/info.c b/src/info.c index d71631dd1..16bd03331 100644 --- a/src/info.c +++ b/src/info.c @@ -713,7 +713,9 @@ char sprnames[NUMSPRITES + 1][5] = "DRAF", "GRES", - "OTFG", + "OTBU", + "OTLS", + "OTCP", "DBOS", // Drift boost flame @@ -4995,9 +4997,10 @@ state_t states[NUMSTATES] = {SPR_GRES, FF_ANIMATE|FF_PAPERSPRITE, -1, {NULL}, 2, 4, S_NULL}, // S_TIREGREASE - {SPR_OTFG, FF_FULLBRIGHT|FF_TRANS50, TICRATE, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEFOG - {SPR_OTFG, 1|FF_FULLBRIGHT|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB - {SPR_OTFG, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEBEAM + {SPR_OTBU, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIME_BULB1 + {SPR_OTBU, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIME_BULB2 + {SPR_OTLS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIME_LASER + {SPR_OTCP, 0, -1, {NULL}, 0, 0, S_NULL}, // S_OVERTIME_CENTER {SPR_CAPS, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLECAPSULE_SIDE1 {SPR_CAPS, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLECAPSULE_SIDE2 @@ -28402,9 +28405,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_OVERTIMEFOG + { // MT_OVERTIME_PARTICLE -1, // doomednum - S_OVERTIMEFOG, // spawnstate + S_NULL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -28420,8 +28423,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16<mo == NULL || P_MobjWasRemoved(player->mo) == true) { continue; } - mo = P_SpawnMobj(x, y, player->mo->z + (player->mo->height / 2), type); - P_SetScale(mo, scale); - if (player->mo->eflags & MFE_VERTICALFLIP) { - mo->flags2 |= MF2_OBJECTFLIP; - mo->eflags |= MFE_VERTICALFLIP; + zpos = player->mo->z + player->mo->height; + } + else + { + zpos = player->mo->z; } - mo->drawflags |= (MFD_DONTDRAW & ~(K_GetPlayerDontDrawFlag(player))); + flip = P_MobjFlip(player->mo); - switch (type) + for (j = 0; j < 3; j++) { - case MT_OVERTIMEFOG: - mo->destscale = 8 * mo->scale; - mo->momz = P_RandomRange(1,8) * mo->scale; - break; - case MT_OVERTIMEORB: - mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90; + mobj_t *mo = P_SpawnMobj(x, y, zpos, MT_OVERTIME_PARTICLE); - if (leveltime & 1) - f = 3; - else - f = (leveltime / 2) % 3; + if (player->mo->eflags & MFE_VERTICALFLIP) + { + mo->flags2 |= MF2_OBJECTFLIP; + mo->eflags |= MFE_VERTICALFLIP; + } - mo->frame += f; - break; - default: - break; + mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90; + mo->drawflags |= (MFD_DONTDRAW & ~(K_GetPlayerDontDrawFlag(player))); + + P_SetScale(mo, scale); + + switch (j) + { + case 0: + P_SetMobjState(mo, S_OVERTIME_BULB1); + + if (leveltime & 1) + mo->frame += 1; + + //P_SetScale(mo, mapobjectscale); + zpos += 35 * mo->scale * flip; + break; + case 1: + P_SetMobjState(mo, S_OVERTIME_LASER); + + if (leveltime & 1) + mo->frame += 3; + else + mo->frame += (leveltime / 2) % 3; + + //P_SetScale(mo, scale); + zpos += 346 * mo->scale * flip; + break; + case 2: + P_SetMobjState(mo, S_OVERTIME_BULB2); + + if (leveltime & 1) + mo->frame += 1; + + //P_SetScale(mo, mapobjectscale); + break; + default: + I_Error("Bruh moment has occured\n"); + return; + } } } } @@ -331,8 +360,6 @@ static void K_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjty void K_RunBattleOvertime(void) { - UINT32 i, j; - if (battleovertime.enabled < 10*TICRATE) { battleovertime.enabled++; @@ -343,81 +370,35 @@ void K_RunBattleOvertime(void) } else if (battleovertime.radius > 0) { - if (battleovertime.radius > 4*mapobjectscale) - battleovertime.radius -= 4*mapobjectscale; + if (battleovertime.radius > 2*mapobjectscale) + battleovertime.radius -= 2*mapobjectscale; else battleovertime.radius = 0; } - if (battleovertime.radius <= 0) - { - return; - } - - /* - if (leveltime & 1) - { - UINT8 transparency = tr_trans50; - - if (!splitscreen && players[displayplayers[0]].mo) - { - INT32 dist = P_AproxDistance(battleovertime.x-players[displayplayers[0]].mo->x, battleovertime.y-players[displayplayers[0]].mo->y); - transparency = max(0, NUMTRANSMAPS - ((256 + (dist>>FRACBITS)) / 256)); - } - - if (transparency < NUMTRANSMAPS) - { - mobj_t *beam = P_SpawnMobj(battleovertime.x, battleovertime.y, battleovertime.z + (mobjinfo[MT_RANDOMITEM].height/2), MT_OVERTIMEBEAM); - P_SetScale(beam, beam->scale*2); - if (transparency > 0) - beam->frame |= transparency< 0) { const fixed_t pi = (22 * FRACUNIT) / 7; // loose approximation, this doesn't need to be incredibly precise - fixed_t scale = mapobjectscale + (battleovertime.radius / 2048); - fixed_t sprwidth = 64 * scale; + const UINT32 orbs = 32; + const angle_t angoff = ANGLE_MAX / orbs; + const UINT8 spriteSpacing = 128; + fixed_t circumference = FixedMul(pi, battleovertime.radius * 2); - UINT32 orbs = circumference / sprwidth; - angle_t angoff = ANGLE_MAX / orbs; + fixed_t scale = max(circumference / spriteSpacing / orbs, mapobjectscale); + + fixed_t size = FixedMul(mobjinfo[MT_OVERTIME_PARTICLE].radius, scale); + fixed_t posOffset = max(battleovertime.radius - size, 0); + + UINT32 i; for (i = 0; i < orbs; i++) { - angle_t ang = (i * angoff); - fixed_t size = FixedMul(mobjinfo[MT_OVERTIMEORB].radius, mapobjectscale); + angle_t ang = (i * angoff) + FixedAngle((leveltime * FRACUNIT) / 4); - fixed_t x = battleovertime.x + P_ReturnThrustX(NULL, ang, battleovertime.radius + size); - fixed_t y = battleovertime.y + P_ReturnThrustY(NULL, ang, battleovertime.radius + size); + fixed_t x = battleovertime.x + P_ReturnThrustX(NULL, ang, posOffset); + fixed_t y = battleovertime.y + P_ReturnThrustY(NULL, ang, posOffset); - K_SpawnOvertimeParticles(x, y, mapobjectscale, MT_OVERTIMEORB); - } - } - - if (battleovertime.enabled < 10*TICRATE) - return; - - for (i = 0; i < 16; i++) - { - j = 0; - - while (j < 32) // max attempts - { - fixed_t scale = 4*mapobjectscale; - - fixed_t x = battleovertime.x + (P_RandomRange(-64,64) * scale); - fixed_t y = battleovertime.y + (P_RandomRange(-64,64) * scale); - - fixed_t closestdist = battleovertime.radius + (8 * FixedMul(mobjinfo[MT_OVERTIMEFOG].radius, scale)); - - j++; - - if (P_AproxDistance(x - battleovertime.x, y - battleovertime.y) < closestdist) - continue; - - K_SpawnOvertimeParticles(x, y, scale, MT_OVERTIMEFOG); - break; + K_SpawnOvertimeLaser(x, y, scale); } } } diff --git a/src/k_kart.c b/src/k_kart.c index 5393504d6..f7954307e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5751,10 +5751,21 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) { player->kartstuff[k_wanted]++; - if ((battleovertime.enabled >= 10*TICRATE) && (P_AproxDistance(player->mo->x - battleovertime.x, player->mo->y - battleovertime.y) - (player->mo->radius * 2)) > battleovertime.radius) + if (battleovertime.enabled >= 10*TICRATE) { - P_KillMobj(player->mo, NULL, NULL, DMG_NORMAL); - player->kartstuff[k_bumper] = 0; + fixed_t distanceToBarrier = 0; + + if (battleovertime.radius > 0) + { + distanceToBarrier = R_PointToDist2(player->mo->x, player->mo->y, battleovertime.x, battleovertime.y) - (player->mo->radius * 2); + } + + if (distanceToBarrier > battleovertime.radius) + { + //P_KillMobj(player->mo, NULL, NULL, DMG_NORMAL); + player->kartstuff[k_bumper] = 0; + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL); + } } } diff --git a/src/p_inter.c b/src/p_inter.c index 7a778a3ab..b610ec692 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -726,7 +726,7 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) } // Easily make it so that overtime works offline -#define TESTOVERTIMEINFREEPLAY +//#define TESTOVERTIMEINFREEPLAY /** Checks if the level timer is over the timelimit and the round should end, * unless you are in overtime. In which case leveltime may stretch out beyond @@ -743,8 +743,10 @@ void P_CheckTimeLimit(void) if (!cv_timelimit.value) return; +#ifndef TESTOVERTIMEINFREEPLAY if (battlecapsules) // capsules override any time limit settings return; +#endif if (!(gametyperules & GTR_TIMELIMIT)) return; @@ -770,51 +772,43 @@ void P_CheckTimeLimit(void) // Initiate the kill zone if (!battleovertime.enabled) { - INT32 b = 0; thinker_t *th; - mobj_t *item = NULL; + mobj_t *center = NULL; - P_RespawnBattleBoxes(); // FORCE THESE TO BE RESPAWNED FOR THIS!!!!!!! - - // Find us an item box to center on. - // TO DO: DON'T do this, instead use a specialized center point object - // just use 0,0 if it's not found for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { mobj_t *thismo; + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) continue; + thismo = (mobj_t *)th; - if (thismo->type != MT_RANDOMITEM) - continue; - if (thismo->threshold == 69) // Disappears - continue; - - b++; - - // Only select items that are on the ground, ignore ones in the air. Ambush flag inverts this rule. - if ((!P_IsObjectOnGround(thismo)) != (thismo->flags2 & MF2_AMBUSH)) - continue; - - if (item == NULL || (b < nummapboxes && P_RandomChance(((nummapboxes-b)*FRACUNIT)/nummapboxes))) // This is to throw off the RNG some - item = thismo; - if (b >= nummapboxes) // end early if we've found them all already + if (thismo->type == MT_OVERTIME_CENTER) + { + center = thismo; break; + } } - if (item == NULL) // no item found, could happen if every item is in the air or has ambush flag, or the map has none + if (center == NULL || P_MobjWasRemoved(center)) { - CONS_Alert(CONS_WARNING, "No usuable items for Battle overtime!\n"); - return; + CONS_Alert(CONS_WARNING, "No center point for overtime!\n"); + + battleovertime.x = 0; + battleovertime.y = 0; + battleovertime.z = 0; + } + else + { + battleovertime.x = center->x; + battleovertime.y = center->y; + battleovertime.z = center->z; } - //item->threshold = 70; // Set constant respawn - battleovertime.x = item->x; - battleovertime.y = item->y; - battleovertime.z = item->z; battleovertime.radius = 4096 * mapobjectscale; battleovertime.enabled = 1; + S_StartSound(NULL, sfx_kc47); } From 344acfece27f74126be7a23cb485f4c566c6362f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 22 Oct 2020 17:51:18 -0400 Subject: [PATCH 10/99] Make laser transparent before it's active --- src/k_battle.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/k_battle.c b/src/k_battle.c index 9e5ff867b..ddbf649bd 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -339,6 +339,9 @@ static void K_SpawnOvertimeLaser(fixed_t x, fixed_t y, fixed_t scale) //P_SetScale(mo, scale); zpos += 346 * mo->scale * flip; + + if (battleovertime.enabled < 10*TICRATE) + mo->drawflags |= MFD_TRANS50; break; case 2: P_SetMobjState(mo, S_OVERTIME_BULB2); From f5788b34e691590da26c207bb20d2ae9e153bb57 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 22 Oct 2020 21:25:40 -0400 Subject: [PATCH 11/99] Fix players not being able to turn in certain scenarios --- src/p_user.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 3bc6471e6..2a67d8360 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -461,15 +461,9 @@ UINT8 P_FindHighestLap(void) // boolean P_PlayerInPain(player_t *player) { - if (player->kartstuff[k_spinouttimer] || player->kartstuff[k_squishedtimer] || player->respawn.state != RESPAWNST_NONE) + if (player->kartstuff[k_spinouttimer] || player->kartstuff[k_squishedtimer]) return true; - if (gametyperules & GTR_KARMA) - { - if (player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) - return true; - } - return false; } From 69e4a1c59f508f156c7b66a19a81aed3b07667bc Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 22 Oct 2020 22:15:07 -0400 Subject: [PATCH 12/99] Blue sphere jiggle physics --- src/dehacked.c | 39 ++++++++++++++++++++++++++++++++--- src/info.c | 55 ++++++++++++++++++++++++++++++++++++++------------ src/info.h | 37 +++++++++++++++++++++++++++++++-- 3 files changed, 113 insertions(+), 18 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index c57b8f5bf..fb6772499 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6173,10 +6173,43 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FASTRING11", "S_FASTRING12", - // Blue Sphere for special stages + // Blue Sphere "S_BLUESPHERE", - "S_BLUESPHEREBONUS", - "S_BLUESPHERESPARK", + "S_BLUESPHERE_SPAWN", + + "S_BLUESPHERE_BOUNCE1", + "S_BLUESPHERE_BOUNCE2", + + "S_BLUESPHERE_BOUNCE3", + "S_BLUESPHERE_BOUNCE4", + + "S_BLUESPHERE_BOUNCE5", + "S_BLUESPHERE_BOUNCE6", + "S_BLUESPHERE_BOUNCE7", + "S_BLUESPHERE_BOUNCE8", + + "S_BLUESPHERE_BOUNCE9", + "S_BLUESPHERE_BOUNCE10", + "S_BLUESPHERE_BOUNCE11", + "S_BLUESPHERE_BOUNCE12", + + "S_BLUESPHERE_BOUNCE13", + "S_BLUESPHERE_BOUNCE14", + "S_BLUESPHERE_BOUNCE15", + "S_BLUESPHERE_BOUNCE16", + "S_BLUESPHERE_BOUNCE17", + "S_BLUESPHERE_BOUNCE18", + "S_BLUESPHERE_BOUNCE19", + "S_BLUESPHERE_BOUNCE20", + + "S_BLUESPHERE_BOUNCE21", + "S_BLUESPHERE_BOUNCE22", + "S_BLUESPHERE_BOUNCE23", + "S_BLUESPHERE_BOUNCE24", + "S_BLUESPHERE_BOUNCE25", + "S_BLUESPHERE_BOUNCE26", + "S_BLUESPHERE_BOUNCE27", + "S_BLUESPHERE_BOUNCE28", // Bomb Sphere "S_BOMBSPHERE1", diff --git a/src/info.c b/src/info.c index 16bd03331..812aa2a18 100644 --- a/src/info.c +++ b/src/info.c @@ -1801,14 +1801,43 @@ state_t states[NUMSTATES] = {SPR_RING, 20, 1, {NULL}, 0, 0, S_FASTRING12}, // S_FASTRING11 {SPR_RING, 22, 1, {NULL}, 0, 0, S_FASTRING1}, // S_FASTRING12 - // Blue Sphere for special stages - {SPR_BSPH, FF_SEMIBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE - {SPR_BSPH, FF_FULLBRIGHT -#ifdef MANIASPHERES - |FF_ANIMATE|FF_RANDOMANIM -#endif - , -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS - {SPR_BSPH, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK + // Blue Sphere + {SPR_BSPH, FF_SEMIBRIGHT|2, TICRATE, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE1}, // S_BLUESPHERE + {SPR_BSPH, FF_SEMIBRIGHT|2, TICRATE, {A_SetRandomTics}, 1, TICRATE, S_BLUESPHERE_BOUNCE1}, // S_BLUESPHERE_SPAWN + + {SPR_BSPH, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE2}, // S_BLUESPHERE_BOUNCE1 + {SPR_BSPH, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE3}, // S_BLUESPHERE_BOUNCE2 + + {SPR_BSPH, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE4}, // S_BLUESPHERE_BOUNCE3 + {SPR_BSPH, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE5}, // S_BLUESPHERE_BOUNCE4 + + {SPR_BSPH, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE6}, // S_BLUESPHERE_BOUNCE5 + {SPR_BSPH, FF_SEMIBRIGHT|2, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE7}, // S_BLUESPHERE_BOUNCE6 + {SPR_BSPH, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE8}, // S_BLUESPHERE_BOUNCE7 + {SPR_BSPH, FF_SEMIBRIGHT|2, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE9}, // S_BLUESPHERE_BOUNCE8 + + {SPR_BSPH, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE10}, // S_BLUESPHERE_BOUNCE9 + {SPR_BSPH, FF_SEMIBRIGHT|2, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE11}, // S_BLUESPHERE_BOUNCE10 + {SPR_BSPH, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE12}, // S_BLUESPHERE_BOUNCE11 + {SPR_BSPH, FF_SEMIBRIGHT|2, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE13}, // S_BLUESPHERE_BOUNCE12 + + {SPR_BSPH, FF_SEMIBRIGHT, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE14}, // S_BLUESPHERE_BOUNCE13 + {SPR_BSPH, FF_SEMIBRIGHT|1, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE15}, // S_BLUESPHERE_BOUNCE14 + {SPR_BSPH, FF_SEMIBRIGHT|2, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE16}, // S_BLUESPHERE_BOUNCE15 + {SPR_BSPH, FF_SEMIBRIGHT|3, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE17}, // S_BLUESPHERE_BOUNCE16 + {SPR_BSPH, FF_SEMIBRIGHT|4, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE18}, // S_BLUESPHERE_BOUNCE17 + {SPR_BSPH, FF_SEMIBRIGHT|3, 4, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE19}, // S_BLUESPHERE_BOUNCE18 + {SPR_BSPH, FF_SEMIBRIGHT|2, 4, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE20}, // S_BLUESPHERE_BOUNCE19 + {SPR_BSPH, FF_SEMIBRIGHT|1, 4, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE21}, // S_BLUESPHERE_BOUNCE20 + + {SPR_BSPH, FF_SEMIBRIGHT, 6, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE22}, // S_BLUESPHERE_BOUNCE21 + {SPR_BSPH, FF_SEMIBRIGHT|1, 6, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE23}, // S_BLUESPHERE_BOUNCE22 + {SPR_BSPH, FF_SEMIBRIGHT|2, 6, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE24}, // S_BLUESPHERE_BOUNCE23 + {SPR_BSPH, FF_SEMIBRIGHT|3, 9, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE25}, // S_BLUESPHERE_BOUNCE24 + {SPR_BSPH, FF_SEMIBRIGHT|4, 9, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE26}, // S_BLUESPHERE_BOUNCE25 + {SPR_BSPH, FF_SEMIBRIGHT|3, 9, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE27}, // S_BLUESPHERE_BOUNCE26 + {SPR_BSPH, FF_SEMIBRIGHT|2, 9, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE28}, // S_BLUESPHERE_BOUNCE27 + {SPR_BSPH, FF_SEMIBRIGHT|1, 9, {NULL}, 0, 0, S_BLUESPHERE}, // S_BLUESPHERE_BOUNCE28 // Bomb Sphere {SPR_BSPH, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_BOMBSPHERE2}, // S_BOMBSPHERE1 @@ -7927,7 +7956,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_BLUESPHERE -1, // doomednum - S_BLUESPHERE, // spawnstate + S_BLUESPHERE_SPAWN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7948,13 +7977,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags - S_BLUESPHEREBONUS // raisestate + MF_RUNSPAWNFUNC|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags + S_NULL // raisestate }, { // MT_FLINGBLUESPHERE -1, // doomednum - S_BLUESPHERE, // spawnstate + S_BLUESPHERE_SPAWN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7976,7 +8005,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL, // flags - S_BLUESPHEREBONUS // raisestate + S_NULL // raisestate }, { // MT_BOMBSPHERE diff --git a/src/info.h b/src/info.h index cc8876f32..b56f436b2 100644 --- a/src/info.h +++ b/src/info.h @@ -2018,8 +2018,41 @@ typedef enum state // Blue Sphere for special stages S_BLUESPHERE, - S_BLUESPHEREBONUS, - S_BLUESPHERESPARK, + S_BLUESPHERE_SPAWN, + + S_BLUESPHERE_BOUNCE1, + S_BLUESPHERE_BOUNCE2, + + S_BLUESPHERE_BOUNCE3, + S_BLUESPHERE_BOUNCE4, + + S_BLUESPHERE_BOUNCE5, + S_BLUESPHERE_BOUNCE6, + S_BLUESPHERE_BOUNCE7, + S_BLUESPHERE_BOUNCE8, + + S_BLUESPHERE_BOUNCE9, + S_BLUESPHERE_BOUNCE10, + S_BLUESPHERE_BOUNCE11, + S_BLUESPHERE_BOUNCE12, + + S_BLUESPHERE_BOUNCE13, + S_BLUESPHERE_BOUNCE14, + S_BLUESPHERE_BOUNCE15, + S_BLUESPHERE_BOUNCE16, + S_BLUESPHERE_BOUNCE17, + S_BLUESPHERE_BOUNCE18, + S_BLUESPHERE_BOUNCE19, + S_BLUESPHERE_BOUNCE20, + + S_BLUESPHERE_BOUNCE21, + S_BLUESPHERE_BOUNCE22, + S_BLUESPHERE_BOUNCE23, + S_BLUESPHERE_BOUNCE24, + S_BLUESPHERE_BOUNCE25, + S_BLUESPHERE_BOUNCE26, + S_BLUESPHERE_BOUNCE27, + S_BLUESPHERE_BOUNCE28, // Bomb Sphere S_BOMBSPHERE1, From 362c98e5d604200ebcb237b223110be842390dba Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 23 Oct 2020 02:42:04 -0400 Subject: [PATCH 13/99] Add blue sphere meter --- src/k_hud.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 42c7fd7c2..ee33034a6 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -50,6 +50,7 @@ static patch_t *kp_bumperstickerwide; static patch_t *kp_capsulesticker; static patch_t *kp_capsulestickerwide; static patch_t *kp_karmasticker; +static patch_t *kp_spheresticker; static patch_t *kp_splitkarmabomb; static patch_t *kp_timeoutsticker; @@ -174,6 +175,7 @@ void K_LoadKartHUDGraphics(void) kp_capsulesticker = W_CachePatchName("K_STCAPN", PU_HUDGFX); kp_capsulestickerwide = W_CachePatchName("K_STCAPW", PU_HUDGFX); kp_karmasticker = W_CachePatchName("K_STKARM", PU_HUDGFX); + kp_spheresticker = W_CachePatchName("K_STBSMT", PU_HUDGFX); kp_splitkarmabomb = W_CachePatchName("K_SPTKRM", PU_HUDGFX); kp_timeoutsticker = W_CachePatchName("K_STTOUT", PU_HUDGFX); @@ -1951,7 +1953,7 @@ static void K_drawKartSpeedometer(void) UINT8 labeln = 0; UINT8 numbers[3]; INT32 splitflags = V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN; - UINT8 battleoffset = 0; + INT32 battleoffset = 0; if (!stplyr->exiting) // Keep the same speed value as when you crossed the finish line! { @@ -1986,7 +1988,7 @@ static void K_drawKartSpeedometer(void) numbers[2] = (convSpeed % 10); if (gametype == GT_BATTLE) - battleoffset = 8; + battleoffset = -4; V_DrawScaledPatch(LAPS_X, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_speedometersticker); V_DrawScaledPatch(LAPS_X+7, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[numbers[0]]); @@ -1995,6 +1997,34 @@ static void K_drawKartSpeedometer(void) V_DrawScaledPatch(LAPS_X+29, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_speedometerlabel[labeln]); } +static void K_drawBlueSphereMeter(void) +{ + const UINT8 maxBars = 4; + const UINT8 segColors[] = {73, 64, 52, 54, 55, 35, 34, 33, 202, 180, 181, 182, 164, 165, 166, 153, 152}; + const UINT8 sphere = max(min(stplyr->spheres, 40), 0); + + UINT8 numBars = min((sphere / 10), maxBars); + UINT8 color = segColors[(sphere * sizeof(segColors)) / (40 + 1)]; + INT32 x = LAPS_X + 25; + UINT8 i; + + V_DrawScaledPatch(LAPS_X, LAPS_Y - 22, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN, kp_spheresticker); + + for (i = 0; i <= numBars; i++) + { + UINT8 segLen = 10; + + if (i == numBars) + { + segLen = (sphere % 10); + } + + V_DrawFill(x, LAPS_Y - 16, segLen, 6, color | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN); + + x += 15; + } +} + static void K_drawKartBumpersOrKarma(void) { UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, GTC_CACHE); @@ -3995,6 +4025,11 @@ void K_drawKartHUD(void) if (LUA_HudEnabled(hud_gametypeinfo)) K_drawKartBumpersOrKarma(); } + + if (gametyperules & GTR_SPHERES) + { + K_drawBlueSphereMeter(); + } } // Draw the countdowns after everything else. From ffe4f4a400453d1c8d93770e64710e160395de60 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 23 Oct 2020 03:05:10 -0400 Subject: [PATCH 14/99] Fix leftover from old code causing desync --- src/p_saveg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 509d18ec4..8b2a31726 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4116,7 +4116,7 @@ static void P_NetArchiveMisc(void) // battleovertime_t WRITEUINT16(save_p, battleovertime.enabled); - WRITEUINT16(save_p, battleovertime.radius); + WRITEFIXED(save_p, battleovertime.radius); WRITEFIXED(save_p, battleovertime.x); WRITEFIXED(save_p, battleovertime.y); WRITEFIXED(save_p, battleovertime.z); From 6c2884b7d6d86883eb3c8088ef651c837b758e2a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 23 Oct 2020 16:40:34 -0400 Subject: [PATCH 15/99] Fix leftover from old code causing desync, part 2 --- src/p_saveg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 8b2a31726..c9797000e 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4249,7 +4249,7 @@ static inline boolean P_NetUnArchiveMisc(void) // battleovertime_t battleovertime.enabled = READUINT16(save_p); - battleovertime.radius = READUINT16(save_p); + battleovertime.radius = READFIXED(save_p); battleovertime.x = READFIXED(save_p); battleovertime.y = READFIXED(save_p); battleovertime.z = READFIXED(save_p); From 81a3a1c108124adead1d31440532d3bb9d1e87f8 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 09:18:28 -0400 Subject: [PATCH 16/99] Steal bumpers from other players on any hit --- src/d_netcmd.c | 4 +-- src/k_kart.c | 97 +++++++++++++++++++++++++++++--------------------- src/k_kart.h | 6 ++-- src/p_inter.c | 39 +++++++++++--------- src/p_map.c | 16 ++++----- 5 files changed, 90 insertions(+), 72 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 6e5d245da..1b0806832 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4310,15 +4310,13 @@ static void TimeLimit_OnChange(void) if (cv_timelimit.value != 0) { - CONS_Printf(M_GetText("Levels will end after %d minute%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003 + CONS_Printf(M_GetText("Rounds will end after %d minute%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003 timelimitintics = cv_timelimit.value * (60*TICRATE); // Note the deliberate absence of any code preventing // pointlimit and timelimit from being set simultaneously. // Some people might like to use them together. It works. } - else if (netgame || multiplayer) - CONS_Printf(M_GetText("Time limit disabled\n")); #ifdef HAVE_DISCORDRPC DRPC_UpdatePresence(); diff --git a/src/k_kart.c b/src/k_kart.c index f7954307e..6e3d11a9a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1036,7 +1036,7 @@ fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against) return FixedMul(weight, mobj->scale); } -void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) +boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) { mobj_t *fx; fixed_t momdifx, momdify; @@ -1045,16 +1045,16 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) fixed_t mass1, mass2; if (!mobj1 || !mobj2) - return; + return false; // Don't bump when you're being reborn if ((mobj1->player && mobj1->player->playerstate != PST_LIVE) || (mobj2->player && mobj2->player->playerstate != PST_LIVE)) - return; + return false; if ((mobj1->player && mobj1->player->respawn.state != RESPAWNST_NONE) || (mobj2->player && mobj2->player->respawn.state != RESPAWNST_NONE)) - return; + return false; { // Don't bump if you're flashing INT32 flash; @@ -1064,7 +1064,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) { if (mobj1->player->powers[pw_flashing] < flash-1) mobj1->player->powers[pw_flashing]++; - return; + return false; } flash = K_GetKartFlashing(mobj2->player); @@ -1072,7 +1072,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) { if (mobj2->player->powers[pw_flashing] < flash-1) mobj2->player->powers[pw_flashing]++; - return; + return false; } } @@ -1080,13 +1080,13 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) if (mobj1->player && mobj1->player->kartstuff[k_justbumped]) { mobj1->player->kartstuff[k_justbumped] = bumptime; - return; + return false; } if (mobj2->player && mobj2->player->kartstuff[k_justbumped]) { mobj2->player->kartstuff[k_justbumped] = bumptime; - return; + return false; } mass1 = K_GetMobjWeight(mobj1, mobj2); @@ -1104,8 +1104,10 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) disty = (mobj1->y + mobj2->momy*3) - (mobj2->y + mobj1->momy*3); if (distx == 0 && disty == 0) + { // if there's no distance between the 2, they're directly on top of each other, don't run this - return; + return false; + } { // Normalize distance to the sum of the two objects' radii, since in a perfect world that would be the distance at the point of collision... fixed_t dist = P_AproxDistance(distx, disty); @@ -1142,7 +1144,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) if (dot >= 0) { // They're moving away from each other - return; + return false; } force = FixedDiv(dot, FixedMul(distx, distx)+FixedMul(disty, disty)); @@ -1233,6 +1235,8 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) P_PlayerRingBurst(mobj2->player, 1); } } + + return true; } /** \brief Checks that the player is on an offroad subsector for realsies. Also accounts for line riding to prevent cheese. @@ -2413,11 +2417,14 @@ void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean } } -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source) +void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount) { UINT8 score = 1; boolean trapitem = false; + if (amount <= 0) + return; + if (!(gametyperules & GTR_BUMPERS)) return; @@ -2436,7 +2443,7 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source) { if (K_IsPlayerWanted(player)) score = 3; - else if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] == 1) + else if ((gametyperules & GTR_BUMPERS) && (player->kartstuff[k_bumper] <= amount)) score = 2; } @@ -2447,7 +2454,7 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source) if (player->kartstuff[k_bumper] > 0) { - if (player->kartstuff[k_bumper] == 1) + if (player->kartstuff[k_bumper] <= amount) { mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); // Player hitbox is too small!! P_SetTarget(&karmahitbox->target, player->mo); @@ -2456,14 +2463,15 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source) CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); } - player->kartstuff[k_bumper]--; + player->kartstuff[k_bumper] -= amount; if (K_IsPlayerWanted(player)) K_CalculateBattleWanted(); } - if (player->kartstuff[k_bumper] == 0) + if (player->kartstuff[k_bumper] <= 0) { + player->kartstuff[k_bumper] = 0; player->kartstuff[k_comebacktimer] = comebacktime; if (player->kartstuff[k_comebackmode] == 2) @@ -2587,59 +2595,68 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source) P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); } -void K_StealBumper(player_t *player, player_t *victim) +void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) { + INT32 intendedamount = player->kartstuff[k_bumper] + amount; INT32 newbumper; angle_t newangle, diff; fixed_t newx, newy; mobj_t *newmo; + if (amount <= 0) + return; + if (!(gametyperules & GTR_BUMPERS)) return; if (netgame && player->kartstuff[k_bumper] <= 0) CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]); - newbumper = player->kartstuff[k_bumper]; - if (newbumper <= 1) - diff = 0; - else - diff = FixedAngle(360*FRACUNIT/newbumper); + while (player->kartstuff[k_bumper] < intendedamount) + { + newbumper = player->kartstuff[k_bumper]; + if (newbumper <= 1) + diff = 0; + else + diff = FixedAngle(360*FRACUNIT/newbumper); - newangle = player->mo->angle; - newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); + newangle = player->mo->angle; + newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); + newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - newmo = P_SpawnMobj(newx, newy, player->mo->z, MT_BATTLEBUMPER); - newmo->threshold = newbumper; - P_SetTarget(&newmo->tracer, victim->mo); - P_SetTarget(&newmo->target, player->mo); - newmo->angle = (diff * (newbumper-1)); - newmo->color = victim->skincolor; + newmo = P_SpawnMobj(newx, newy, player->mo->z, MT_BATTLEBUMPER); + newmo->threshold = newbumper; + P_SetTarget(&newmo->tracer, victim->mo); + P_SetTarget(&newmo->target, player->mo); + newmo->angle = (diff * (newbumper-1)); + newmo->color = victim->skincolor; - if (newbumper+1 < 2) - P_SetMobjState(newmo, S_BATTLEBUMPER3); - else if (newbumper+1 < 3) - P_SetMobjState(newmo, S_BATTLEBUMPER2); - else - P_SetMobjState(newmo, S_BATTLEBUMPER1); + if (newbumper+1 < 2) + P_SetMobjState(newmo, S_BATTLEBUMPER3); + else if (newbumper+1 < 3) + P_SetMobjState(newmo, S_BATTLEBUMPER2); + else + P_SetMobjState(newmo, S_BATTLEBUMPER1); + + player->kartstuff[k_bumper]++; + } S_StartSound(player->mo, sfx_3db06); - player->kartstuff[k_bumper]++; player->kartstuff[k_comebackpoints] = 0; player->powers[pw_flashing] = K_GetKartFlashing(player); player->kartstuff[k_comebacktimer] = comebacktime; - /*victim->powers[pw_flashing] = K_GetKartFlashing(victim); - victim->kartstuff[k_comebacktimer] = comebacktime;*/ + /* + victim->powers[pw_flashing] = K_GetKartFlashing(victim); + victim->kartstuff[k_comebacktimer] = comebacktime; + */ victim->kartstuff[k_instashield] = 15; if (cv_kartdebughuddrop.value && !modeattacking) K_DropItems(victim); else K_DropHnextList(victim, false); - return; } // source is the mobj that originally threw the bomb that exploded etc. diff --git a/src/k_kart.h b/src/k_kart.h index d45a69570..2d682511a 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -27,7 +27,7 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, boolean bot, boolean rival); INT32 K_GetShieldFromItem(INT32 item); fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against); -void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid); +boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid); void K_KartPainEnergyFling(player_t *player); void K_FlipFromObject(mobj_t *mo, mobj_t *master); void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master); @@ -41,12 +41,12 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); void K_DoInstashield(player_t *player); void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted); -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source); +void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_DebtStingPlayer(player_t *player, mobj_t *source); -void K_StealBumper(player_t *player, player_t *victim); +void K_StealBumper(player_t *player, player_t *victim, UINT8 amount); void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source); void K_SpawnMineExplosion(mobj_t *source, UINT8 color); UINT16 K_DriftSparkColor(player_t *player, INT32 charge); diff --git a/src/p_inter.c b/src/p_inter.c index b610ec692..6fd7d28c1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -349,7 +349,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->target->player->kartstuff[k_comebackpoints]++; if (special->target->player->kartstuff[k_comebackpoints] >= 2) - K_StealBumper(special->target->player, player); + K_StealBumper(special->target->player, player, 1); special->target->player->kartstuff[k_comebacktimer] = comebacktime; player->kartstuff[k_itemroulette] = 1; @@ -384,7 +384,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->target->player->karthud[khud_yougotem] = 2*TICRATE; if (special->target->player->kartstuff[k_comebackpoints] >= 2) - K_StealBumper(special->target->player, player); + K_StealBumper(special->target->player, player, 1); special->target->player->kartstuff[k_comebacktimer] = comebacktime; @@ -726,7 +726,7 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) } // Easily make it so that overtime works offline -//#define TESTOVERTIMEINFREEPLAY +#define TESTOVERTIMEINFREEPLAY /** Checks if the level timer is over the timelimit and the round should end, * unless you are in overtime. In which case leveltime may stretch out beyond @@ -1661,12 +1661,11 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) return false; } - K_RemoveBumper(player, NULL, NULL); - switch (type) { case DMG_DEATHPIT: // Respawn kill types + K_RemoveBumper(player, NULL, NULL, 1); K_DoIngameRespawn(player); return false; default: @@ -1674,12 +1673,11 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) break; } + K_RemoveBumper(player, NULL, NULL, player->kartstuff[k_bumper]); + player->pflags &= ~PF_SLIDING; player->powers[pw_carry] = CR_NONE; - // Get rid of shield - player->powers[pw_shield] = SH_NONE; - player->mo->color = player->skincolor; player->mo->colorized = false; @@ -1692,7 +1690,7 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); - if (type == DMG_TIMEOVER) + if ((type == DMG_TIMEOVER) && (gametype == GT_RACE)) { mobj_t *boom; @@ -1851,7 +1849,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { if (gametyperules & GTR_BUMPERS) { - if ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1) + if ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || (player->kartstuff[k_comebackmode] == 1)) { // No bumpers, can't be hurt K_DoInstashield(player); @@ -1889,17 +1887,20 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // We successfully hit 'em! if (type != DMG_STING) { + UINT8 bumpadd = 1; + + if (damagetype & DMG_STEAL) + { + bumpadd = 2; + } + if (source && source != player->mo && source->player) { K_PlayHitEmSound(source); - - if (damagetype & DMG_STEAL) - { - K_StealBumper(source->player, player); - } + K_StealBumper(source->player, player, bumpadd); } - K_RemoveBumper(player, inflictor, source); + K_RemoveBumper(player, inflictor, source, bumpadd); } player->kartstuff[k_sneakertimer] = player->kartstuff[k_numsneakers] = 0; @@ -1930,11 +1931,17 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } if (type != DMG_STING) + { player->powers[pw_flashing] = K_GetKartFlashing(player); + } P_PlayRinglossSound(player->mo); + if (ringburst > 0) + { P_PlayerRingBurst(player, ringburst); + } + K_PlayPainSound(player->mo); if ((type == DMG_EXPLODE) || (cv_kartdebughuddrop.value && !modeattacking)) diff --git a/src/p_map.c b/src/p_map.c index 10f048e77..4a33b5427 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1322,17 +1322,13 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->player->kartstuff[k_pogospring]) P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL); } - - if ((gametyperules & GTR_BUMPERS)) + else if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer]) && !(thing->player->powers[pw_flashing])) // Don't steal bumpers while intangible { - if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer]) && !(thing->player->powers[pw_flashing])) // Don't steal bumpers while intangible - { - P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL); - } - else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer]) && !(tmthing->player->powers[pw_flashing])) - { - P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT|DMG_STEAL); - } + P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL); + } + else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer]) && !(tmthing->player->powers[pw_flashing])) + { + P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT|DMG_STEAL); } K_KartBouncing(mo1, mo2, zbounce, false); From cc1268cdf37e8d266a05e6ff9199cd03ec90c90c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 09:18:43 -0400 Subject: [PATCH 17/99] Lost bit of the commit --- src/p_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index 6fd7d28c1..82a11f3df 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -321,7 +321,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->target->player->karthud[khud_yougotem] = 2*TICRATE; if (special->target->player->kartstuff[k_comebackpoints] >= 2) - K_StealBumper(special->target->player, player); + K_StealBumper(special->target->player, player, 1); special->target->player->kartstuff[k_comebacktimer] = comebacktime; From 0969ca1af928438dd9c0ead327faf39bc1dbae8a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 11:27:42 -0400 Subject: [PATCH 18/99] Karma bombs rework - Fixed the bugs with them in our last netgame - Karma bombs are no longer slippery or have stat changes - Karma bombs cannot pick up spheres. Their remaining spheres before they died are removed 1 per tic. - Karma bombs are out of the game permanently when touching the overtime barrier - When successfully hurting another player, instead of getting 0.5 bumpers, they steal ALL of the opponent's bumpers, effectively swapping places with them. One bumper is lost in the process, meaning bumpers are slowly flitered out the more people need to come back. - Removed karma items/eggboxes... hopefully this is temporary and we can bring them back later, but currently we don't have a design for how they should work under the new rules :x. They are still in the code behind the `OTHERKARMAMODES` define - Bumpers & comeback timer are now player_t variables instead of kartstuff shit - eliminated boolean on player_t for checking when a player touched the barrier --- src/d_clisrv.c | 8 +++ src/d_clisrv.h | 3 + src/d_player.h | 3 + src/doomdef.h | 3 + src/g_game.c | 16 +++--- src/k_battle.c | 12 ++-- src/k_collide.c | 10 +++- src/k_hud.c | 95 +++++++++++++------------------ src/k_kart.c | 139 ++++++++++++++++++++++------------------------ src/k_kart.h | 2 +- src/lua_baselib.c | 3 +- src/p_enemy.c | 8 +-- src/p_inter.c | 113 ++++++++++++++++++------------------- src/p_map.c | 4 +- src/p_mobj.c | 32 +++++------ src/p_saveg.c | 8 +++ src/p_user.c | 2 +- 17 files changed, 235 insertions(+), 226 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 867a3e006..a3764913e 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -616,6 +616,10 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->airtime = (tic_t)LONG(players[i].airtime); + rsp->bumpers = SHORT(players[i].bumpers); + rsp->karmadelay = SHORT(players[i].karmadelay); + rsp->eliminated = players[i].eliminated; + // respawnvars_t rsp->respawn_state = players[i].respawn.state; rsp->respawn_pointx = (fixed_t)LONG(players[i].respawn.pointx); @@ -760,6 +764,10 @@ static void resynch_read_player(resynch_pak *rsp) players[i].airtime = (tic_t)LONG(rsp->airtime); + players[i].bumpers = SHORT(rsp->bumpers); + players[i].karmadelay = SHORT(rsp->karmadelay); + players[i].eliminated = rsp->eliminated; + // respawnvars_t players[i].respawn.state = rsp->respawn_state; players[i].respawn.pointx = (fixed_t)LONG(rsp->respawn_pointx); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 573c98dc8..4adfda142 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -281,6 +281,9 @@ typedef struct // SRB2kart INT32 kartstuff[NUMKARTSTUFF]; tic_t airtime; + INT16 bumpers; + INT16 karmadelay; + boolean eliminated; // respawnvars_t UINT8 respawn_state; diff --git a/src/d_player.h b/src/d_player.h index 36829fecc..77e5e35a3 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -509,6 +509,9 @@ typedef struct player_s waypoint_t *nextwaypoint; respawnvars_t respawn; // Respawn info tic_t airtime; // Keep track of how long you've been in the air + INT16 bumpers; + INT16 karmadelay; + boolean eliminated; // Bit flags. // See pflags_t, above. diff --git a/src/doomdef.h b/src/doomdef.h index b1960b507..6cfbd7105 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -655,6 +655,9 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Camera always has noclip. #define NOCLIPCAM +/// Other karma comeback modes +//#define OTHERKARMAMODES + /// MIDI support is really shitty -- we don't use it anyway, so lets throw it behind a define #define NO_MIDI diff --git a/src/g_game.c b/src/g_game.c index 7b91c0e85..40f8a9b67 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1575,7 +1575,7 @@ boolean G_CouldView(INT32 playernum) // I don't know if we want this actually, but I'll humor the suggestion anyway if ((gametyperules & GTR_BUMPERS) && !demo.playback) { - if (player->kartstuff[k_bumper] <= 0) + if (player->bumpers <= 0) return false; } @@ -2072,9 +2072,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) INT32 roulettetype; INT32 growshrinktimer; INT32 bumper; - INT32 comebackpoints; INT32 wanted; boolean songcredit = false; + boolean eliminated; score = players[player].score; marescore = players[player].marescore; @@ -2143,7 +2143,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) bumper = ((gametyperules & GTR_BUMPERS) ? K_StartingBumperCount() : 0); rings = ((gametyperules & GTR_SPHERES) ? 0 : 5); spheres = 0; - comebackpoints = 0; + eliminated = false; wanted = 0; } else @@ -2168,10 +2168,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) else growshrinktimer = 0; - bumper = players[player].kartstuff[k_bumper]; + bumper = players[player].bumpers; rings = players[player].rings; spheres = players[player].spheres; - comebackpoints = players[player].kartstuff[k_comebackpoints]; + eliminated = players[player].eliminated; wanted = players[player].kartstuff[k_wanted]; } @@ -2230,9 +2230,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->kartstuff[k_itemtype] = itemtype; p->kartstuff[k_itemamount] = itemamount; p->kartstuff[k_growshrinktimer] = growshrinktimer; - p->kartstuff[k_bumper] = bumper; - p->kartstuff[k_comebackpoints] = comebackpoints; - p->kartstuff[k_comebacktimer] = comebacktime; + p->bumpers = bumper; + p->karmadelay = comebacktime; + p->eliminated = eliminated; p->kartstuff[k_wanted] = wanted; p->kartstuff[k_eggmanblame] = -1; p->kartstuff[k_lastdraft] = -1; diff --git a/src/k_battle.c b/src/k_battle.c index ddbf649bd..518ae260f 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -89,24 +89,24 @@ void K_CalculateBattleWanted(void) numplaying++; - if (players[i].kartstuff[k_bumper] <= 0) // Not alive, so don't do anything else + if (players[i].bumpers <= 0) // Not alive, so don't do anything else continue; numingame++; - if (bestbumper == -1 || players[i].kartstuff[k_bumper] > bestbumper) + if (bestbumper == -1 || players[i].bumpers > bestbumper) { - bestbumper = players[i].kartstuff[k_bumper]; + bestbumper = players[i].bumpers; bestbumperplayer = i; } - else if (players[i].kartstuff[k_bumper] == bestbumper) + else if (players[i].bumpers == bestbumper) bestbumperplayer = -1; // Tie, no one has best bumper. for (j = 0; j < MAXPLAYERS; j++) { if (!playeringame[j] || players[j].spectator) continue; - if (players[j].kartstuff[k_bumper] <= 0) + if (players[j].bumpers <= 0) continue; if (j == i) continue; @@ -230,7 +230,7 @@ void K_CheckBumpers(void) numingame++; winnerscoreadd += players[i].marescore; - if (players[i].kartstuff[k_bumper] <= 0) // if you don't have any bumpers, you're probably not a winner + if (players[i].bumpers <= 0) // if you don't have any bumpers, you're probably not a winner { nobumpers = true; continue; diff --git a/src/k_collide.c b/src/k_collide.c index 56747a47f..963ec4e64 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -219,11 +219,15 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2) if (!P_CanPickupItem(t2->player, 2)) return true; - if ((gametyperules & GTR_BUMPERS) && t2->player->kartstuff[k_bumper] <= 0) + if ((gametyperules & GTR_BUMPERS) && t2->player->bumpers <= 0) { - if (t2->player->kartstuff[k_comebackmode] || t2->player->kartstuff[k_comebacktimer]) +#ifdef OTHERKARMAMODES + if (t2->player->kartstuff[k_comebackmode] || t2->player->karmadelay) return true; t2->player->kartstuff[k_comebackmode] = 2; +#else + return true; +#endif } else { @@ -253,7 +257,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2) if (t1->target && t1->target->player) { - if ((gametyperules & GTR_CIRCUIT) || t1->target->player->kartstuff[k_bumper] > 0) + if ((gametyperules & GTR_CIRCUIT) || t1->target->player->bumpers > 0) t2->player->kartstuff[k_eggmanblame] = t1->target->player-players; else t2->player->kartstuff[k_eggmanblame] = t2->player-players; diff --git a/src/k_hud.c b/src/k_hud.c index ee33034a6..73e656fcb 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1609,10 +1609,10 @@ static boolean K_drawKartPositionFaces(void) if (LUA_HudEnabled(hud_battlebumpers)) { - if (gametype == GT_BATTLE && players[rankplayer[i]].kartstuff[k_bumper] > 0) + if (gametype == GT_BATTLE && players[rankplayer[i]].bumpers > 0) { V_DrawMappedPatch(bumperx-2, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[0], colormap); - for (j = 1; j < players[rankplayer[i]].kartstuff[k_bumper]; j++) + for (j = 1; j < players[rankplayer[i]].bumpers; j++) { bumperx += 5; V_DrawMappedPatch(bumperx, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[1], colormap); @@ -1624,7 +1624,7 @@ static boolean K_drawKartPositionFaces(void) if (i == strank) V_DrawScaledPatch(FACE_X, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_facehighlight[(leveltime / 4) % 8]); - if (gametype == GT_BATTLE && players[rankplayer[i]].kartstuff[k_bumper] <= 0) + if (gametype == GT_BATTLE && players[rankplayer[i]].bumpers <= 0) V_DrawScaledPatch(FACE_X-4, Y-3, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_ranknobumpers); else { @@ -1722,11 +1722,11 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE); V_DrawMappedPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin][FACE_RANK], colormap); - /*if (gametype == GT_BATTLE && players[tab[i].num].kartstuff[k_bumper] > 0) -- not enough space for this + /*if (gametype == GT_BATTLE && players[tab[i].num].bumpers > 0) -- not enough space for this { INT32 bumperx = x+19; V_DrawMappedPatch(bumperx-2, y-4, 0, kp_tinybumper[0], colormap); - for (j = 1; j < players[tab[i].num].kartstuff[k_bumper]; j++) + for (j = 1; j < players[tab[i].num].bumpers; j++) { bumperx += 5; V_DrawMappedPatch(bumperx, y-4, 0, kp_tinybumper[1], colormap); @@ -1737,7 +1737,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN if (tab[i].num == whiteplayer) V_DrawScaledPatch(x, y-4, 0, kp_facehighlight[(leveltime / 4) % 8]); - if (gametype == GT_BATTLE && players[tab[i].num].kartstuff[k_bumper] <= 0) + if (gametype == GT_BATTLE && players[tab[i].num].bumpers <= 0) V_DrawScaledPatch(x-4, y-7, 0, kp_ranknobumpers); else { @@ -2088,37 +2088,28 @@ static void K_drawKartBumpersOrKarma(void) } else { - if (stplyr->kartstuff[k_bumper] <= 0) + INT32 maxbumper = K_StartingBumperCount(); + V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankbumper, colormap); + + if (stplyr->bumpers > 9 || maxbumper > 9) { - V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_splitkarmabomb, colormap); - V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->kartstuff[k_comebackpoints]) % 10]); - V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[2]); + UINT8 ln[2]; + ln[0] = ((abs(stplyr->bumpers) / 10) % 10); + ln[1] = (abs(stplyr->bumpers) % 10); + + V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); + V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); + + ln[0] = ((abs(maxbumper) / 10) % 10); + ln[1] = (abs(maxbumper) % 10); + + V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); + V_DrawScaledPatch(fx+31, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); } else { - INT32 maxbumper = K_StartingBumperCount(); - V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankbumper, colormap); - - if (stplyr->kartstuff[k_bumper] > 9 || maxbumper > 9) - { - UINT8 ln[2]; - ln[0] = ((abs(stplyr->kartstuff[k_bumper]) / 10) % 10); - ln[1] = (abs(stplyr->kartstuff[k_bumper]) % 10); - - V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); - V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); - - ln[0] = ((abs(maxbumper) / 10) % 10); - ln[1] = (abs(maxbumper) % 10); - - V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); - V_DrawScaledPatch(fx+31, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); - } - else - { - V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->kartstuff[k_bumper]) % 10]); - V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(maxbumper) % 10]); - } + V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->bumpers) % 10]); + V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(maxbumper) % 10]); } } } @@ -2134,22 +2125,14 @@ static void K_drawKartBumpersOrKarma(void) } else { - if (stplyr->kartstuff[k_bumper] <= 0) - { - V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_karmasticker, colormap); - V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/2", stplyr->kartstuff[k_comebackpoints])); - } + INT32 maxbumper = K_StartingBumperCount(); + + if (stplyr->bumpers > 9 && maxbumper > 9) + V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumperstickerwide, colormap); else - { - INT32 maxbumper = K_StartingBumperCount(); + V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumpersticker, colormap); - if (stplyr->kartstuff[k_bumper] > 9 && maxbumper > 9) - V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumperstickerwide, colormap); - else - V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumpersticker, colormap); - - V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->kartstuff[k_bumper], maxbumper)); - } + V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->bumpers, maxbumper)); } } } @@ -2894,7 +2877,7 @@ static void K_drawKartMinimap(void) if (i != displayplayers[0] || r_splitscreen) { - if (gametype == GT_BATTLE && players[i].kartstuff[k_bumper] <= 0) + if (gametype == GT_BATTLE && players[i].bumpers <= 0) continue; if (players[i].kartstuff[k_hyudorotimer] > 0) @@ -3330,9 +3313,9 @@ static void K_drawBattleFullscreen(void) else K_drawKartFinish(); } - else if (stplyr->kartstuff[k_bumper] <= 0 && stplyr->kartstuff[k_comebacktimer] && comeback && !stplyr->spectator && drawcomebacktimer) + else if (stplyr->bumpers <= 0 && stplyr->karmadelay && comeback && !stplyr->spectator && drawcomebacktimer) { - UINT16 t = stplyr->kartstuff[k_comebacktimer]/(10*TICRATE); + UINT16 t = stplyr->karmadelay/(10*TICRATE); INT32 txoff, adjust = (r_splitscreen > 1) ? 4 : 6; // normal string is 8, kart string is 12, half of that for ease INT32 ty = (BASEVIDHEIGHT/2)+66; @@ -3362,11 +3345,11 @@ static void K_drawBattleFullscreen(void) V_DrawFixedPatch(x< 1) - V_DrawString(x-txoff, ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE)); + V_DrawString(x-txoff, ty, 0, va("%d", stplyr->karmadelay/TICRATE)); else { V_DrawFixedPatch(x<kartstuff[k_comebacktimer]/TICRATE)); + V_DrawKartString(x-txoff, ty, 0, va("%d", stplyr->karmadelay/TICRATE)); } } @@ -3787,8 +3770,8 @@ static void K_drawDistributionDebugger(void) if (!playeringame[i] || players[i].spectator) continue; pingame++; - if (players[i].kartstuff[k_bumper] > bestbumper) - bestbumper = players[i].kartstuff[k_bumper]; + if (players[i].bumpers > bestbumper) + bestbumper = players[i].bumpers; } // lovely double loop...... @@ -3911,8 +3894,8 @@ void K_drawKartHUD(void) battlefullscreen = ((gametype == GT_BATTLE) && (stplyr->exiting - || (stplyr->kartstuff[k_bumper] <= 0 - && stplyr->kartstuff[k_comebacktimer] + || (stplyr->bumpers <= 0 + && stplyr->karmadelay && comeback && stplyr->playerstate == PST_LIVE))); diff --git a/src/k_kart.c b/src/k_kart.c index 6e3d11a9a..80d9546d1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -207,7 +207,7 @@ boolean K_IsPlayerLosing(player_t *player) INT32 winningpos = 1; UINT8 i, pcount = 0; - if (battlecapsules && player->kartstuff[k_bumper] <= 0) + if (battlecapsules && player->bumpers <= 0) return true; // DNF in break the capsules if (player->kartstuff[k_position] == 1) @@ -456,7 +456,7 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, if (!playeringame[i] || players[i].spectator) continue; - if (!(gametyperules & GTR_BUMPERS) || players[i].kartstuff[k_bumper]) + if (!(gametyperules & GTR_BUMPERS) || players[i].bumpers) pingame++; if (players[i].exiting) @@ -735,8 +735,8 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) pingame++; if (players[i].exiting) dontforcespb = true; - if (players[i].kartstuff[k_bumper] > bestbumper) - bestbumper = players[i].kartstuff[k_bumper]; + if (players[i].bumpers > bestbumper) + bestbumper = players[i].bumpers; } // No forced SPB in 1v1s, it has to be randomly rolled @@ -2218,12 +2218,8 @@ fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed) fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) { fixed_t finalspeed; - UINT8 kartspeed = player->kartspeed; - if ((gametyperules & (GTR_BUMPERS|GTR_KARMA)) == (GTR_BUMPERS|GTR_KARMA) && player->kartstuff[k_bumper] <= 0) - kartspeed = 1; - - finalspeed = K_GetKartSpeedFromStat(kartspeed); + finalspeed = K_GetKartSpeedFromStat(player->kartspeed); if (player->spheres > 0) { @@ -2234,7 +2230,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) if (K_PlayerUsesBotMovement(player)) { // Give top speed a buff for bots, since it's a fairly weak stat without drifting - fixed_t speedmul = ((kartspeed-1) * FRACUNIT / 8) / 10; // +10% for speed 9 + fixed_t speedmul = ((player->kartspeed-1) * FRACUNIT / 8) / 10; // +10% for speed 9 if (player->botvars.rival == true) { @@ -2263,13 +2259,9 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) fixed_t K_GetKartAccel(player_t *player) { fixed_t k_accel = 32; // 36; - UINT8 kartspeed = player->kartspeed; - if ((gametyperules & (GTR_BUMPERS|GTR_KARMA)) == (GTR_BUMPERS|GTR_KARMA) && player->kartstuff[k_bumper] <= 0) - kartspeed = 1; - - //k_accel += 3 * (9 - kartspeed); // 36 - 60 - k_accel += 4 * (9 - kartspeed); // 32 - 64 + //k_accel += 3 * (9 - player->kartspeed); // 36 - 60 + k_accel += 4 * (9 - player->kartspeed); // 32 - 64 if (player->spheres > 0) { @@ -2417,7 +2409,7 @@ void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean } } -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount) +void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount, boolean force) { UINT8 score = 1; boolean trapitem = false; @@ -2428,8 +2420,11 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a if (!(gametyperules & GTR_BUMPERS)) return; - if (player->powers[pw_flashing] || P_PlayerInPain(player)) - return; + if (force == false) + { + if (player->powers[pw_flashing] || P_PlayerInPain(player)) + return; + } if (inflictor && !P_MobjWasRemoved(inflictor)) { @@ -2443,7 +2438,7 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a { if (K_IsPlayerWanted(player)) score = 3; - else if ((gametyperules & GTR_BUMPERS) && (player->kartstuff[k_bumper] <= amount)) + else if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= amount)) score = 2; } @@ -2452,9 +2447,9 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a K_BattleHitPlayer(source->player, player, score, trapitem); } - if (player->kartstuff[k_bumper] > 0) + if (player->bumpers > 0) { - if (player->kartstuff[k_bumper] <= amount) + if (player->bumpers <= amount) { mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); // Player hitbox is too small!! P_SetTarget(&karmahitbox->target, player->mo); @@ -2463,16 +2458,16 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); } - player->kartstuff[k_bumper] -= amount; + player->bumpers -= amount; if (K_IsPlayerWanted(player)) K_CalculateBattleWanted(); } - if (player->kartstuff[k_bumper] <= 0) + if (player->bumpers <= 0) { - player->kartstuff[k_bumper] = 0; - player->kartstuff[k_comebacktimer] = comebacktime; + player->bumpers = 0; + player->karmadelay = comebacktime; if (player->kartstuff[k_comebackmode] == 2) { @@ -2597,7 +2592,7 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source) void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) { - INT32 intendedamount = player->kartstuff[k_bumper] + amount; + INT32 intendedamount = player->bumpers + amount; INT32 newbumper; angle_t newangle, diff; fixed_t newx, newy; @@ -2609,12 +2604,12 @@ void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) if (!(gametyperules & GTR_BUMPERS)) return; - if (netgame && player->kartstuff[k_bumper] <= 0) + if (netgame && player->bumpers <= 0) CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]); - while (player->kartstuff[k_bumper] < intendedamount) + while (player->bumpers < intendedamount) { - newbumper = player->kartstuff[k_bumper]; + newbumper = player->bumpers; if (newbumper <= 1) diff = 0; else @@ -2638,18 +2633,17 @@ void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) else P_SetMobjState(newmo, S_BATTLEBUMPER1); - player->kartstuff[k_bumper]++; + player->bumpers++; } S_StartSound(player->mo, sfx_3db06); - player->kartstuff[k_comebackpoints] = 0; player->powers[pw_flashing] = K_GetKartFlashing(player); - player->kartstuff[k_comebacktimer] = comebacktime; + player->karmadelay = comebacktime; /* victim->powers[pw_flashing] = K_GetKartFlashing(victim); - victim->kartstuff[k_comebacktimer] = comebacktime; + victim->karmadelay = comebacktime; */ victim->kartstuff[k_instashield] = 15; @@ -3194,7 +3188,7 @@ void K_SpawnBoostTrail(player_t *player) if (!P_IsObjectOnGround(player->mo) || player->kartstuff[k_hyudorotimer] != 0 - || ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer])) + || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0 && player->karmadelay)) return; if (player->mo->eflags & MFE_VERTICALFLIP) @@ -3878,7 +3872,7 @@ static void K_DoHyudoroSteal(player_t *player) // Can steal from this player && (gametype == GT_RACE //&& players[i].kartstuff[k_position] < player->kartstuff[k_position]) - || ((gametyperules & GTR_BUMPERS) && players[i].kartstuff[k_bumper] > 0)) + || ((gametyperules & GTR_BUMPERS) && players[i].bumpers > 0)) // Has an item && (players[i].kartstuff[k_itemtype] @@ -4958,7 +4952,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source) thisang = InvAngle(thisang); // Jawz only go after the person directly ahead of you in race... sort of literally now! - if (gametype == GT_RACE) + if (gametyperules & GTR_CIRCUIT) { // Don't go for people who are behind you if (thisang > ANGLE_67h) @@ -4982,7 +4976,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source) continue; // Don't pay attention to dead players - if (player->kartstuff[k_bumper] <= 0) + if (player->bumpers <= 0) continue; // Z pos too high/low @@ -5259,7 +5253,7 @@ void K_KartPlayerHUDUpdate(player_t *player) player->karthud[khud_ringspblock] = (leveltime % 14); // reset to normal anim next time } - if ((gametyperules & GTR_BUMPERS) && (player->exiting || player->kartstuff[k_comebacktimer])) + if ((gametyperules & GTR_BUMPERS) && (player->exiting || player->karmadelay)) { if (player->exiting) { @@ -5272,9 +5266,9 @@ void K_KartPlayerHUDUpdate(player_t *player) } else { - if (player->kartstuff[k_comebacktimer] < 6*TICRATE) + if (player->karmadelay < 6*TICRATE) player->karthud[khud_cardanimation] -= ((164-player->karthud[khud_cardanimation])/8)+1; - else if (player->kartstuff[k_comebacktimer] < 9*TICRATE) + else if (player->karmadelay < 9*TICRATE) player->karthud[khud_cardanimation] += ((164-player->karthud[khud_cardanimation])/8)+1; } @@ -5627,14 +5621,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_wipeoutslow] >= 1) player->mo->friction = ORIG_FRICTION; player->kartstuff[k_wipeoutslow] = 0; - if (!comeback) - player->kartstuff[k_comebacktimer] = comebacktime; - else if (player->kartstuff[k_comebacktimer]) - { - player->kartstuff[k_comebacktimer]--; - if (P_IsDisplayPlayer(player) && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer] <= 0) - comebackshowninfo = true; // client has already seen the message - } } if (player->rings > 20) @@ -5642,14 +5628,34 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) else if (player->rings < -20) player->rings = -20; - if ((leveltime % TICRATE) == 0) + if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= 0)) + { + // Deplete 1 every tic when removed from the game. player->spheres--; + } + else + { + // Deplete 1 every second when playing. + if ((leveltime % TICRATE) == 0) + player->spheres--; + } if (player->spheres > 40) player->spheres = 40; else if (player->spheres < 0) player->spheres = 0; + if (comeback == false || !(gametyperules & GTR_KARMA) || player->eliminated == true) + { + player->karmadelay = comebacktime; + } + else if (player->karmadelay > 0 && !P_PlayerInPain(player)) + { + player->karmadelay--; + if (P_IsDisplayPlayer(player) && player->bumpers <= 0 && player->karmadelay <= 0) + comebackshowninfo = true; // client has already seen the message + } + if (player->kartstuff[k_ringdelay]) player->kartstuff[k_ringdelay]--; @@ -5764,7 +5770,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_KartPlayerHUDUpdate(player); - if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] > 0 && !P_PlayerInPain(player) && !player->powers[pw_flashing]) + if ((gametyperules & GTR_BUMPERS) && player->bumpers > 0 && !P_PlayerInPain(player) && !player->powers[pw_flashing]) { player->kartstuff[k_wanted]++; @@ -5779,9 +5785,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (distanceToBarrier > battleovertime.radius) { - //P_KillMobj(player->mo, NULL, NULL, DMG_NORMAL); - player->kartstuff[k_bumper] = 0; - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL); + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER); } } } @@ -5794,7 +5798,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_eggmanexplode]) { - if (player->spectator || (gametype == GT_BATTLE && !player->kartstuff[k_bumper])) + if (player->spectator || (gametype == GT_BATTLE && !player->bumpers)) player->kartstuff[k_eggmanexplode] = 0; else { @@ -5837,7 +5841,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_FlameDashLeftoverSmoke(player->mo); } - if (player->kartstuff[k_comebacktimer]) + if (player->karmadelay) player->kartstuff[k_comebackmode] = 0; if (P_IsObjectOnGround(player->mo) && player->kartstuff[k_pogospring]) @@ -6411,10 +6415,7 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) INT32 K_GetKartDriftSparkValue(player_t *player) { - UINT8 kartspeed = (gametype == GT_BATTLE && player->kartstuff[k_bumper] <= 0) - ? 1 - : player->kartspeed; - return (26*4 + kartspeed*2 + (9 - player->kartweight))*8; + return (26*4 + player->kartspeed*2 + (9 - player->kartweight))*8; } /* @@ -6732,8 +6733,8 @@ void K_KartUpdatePosition(player_t *player) { // I have less points than but the same bumpers as this player OR // I have less bumpers than this player - if ((players[i].kartstuff[k_bumper] == player->kartstuff[k_bumper] && players[i].marescore > player->marescore) - || (players[i].kartstuff[k_bumper] > player->kartstuff[k_bumper])) + if ((players[i].bumpers == player->bumpers && players[i].marescore > player->marescore) + || (players[i].bumpers > player->bumpers)) position++; } } @@ -6936,12 +6937,6 @@ void K_AdjustPlayerFriction(player_t *player) } */ - // Karma ice physics - if (gametype == GT_BATTLE && player->kartstuff[k_bumper] <= 0) - { - player->mo->friction += 1228; - } - // Water gets ice physics too if (player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) { @@ -7061,7 +7056,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) newitem->fuse = 15*TICRATE; // selected randomly. player->kartstuff[k_comebackmode] = 0; - player->kartstuff[k_comebacktimer] = comebacktime; + player->karmadelay = comebacktime; S_StartSound(player->mo, sfx_s254); } } @@ -7650,14 +7645,14 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->drawflags &= ~MFD_DONTDRAW; } - if (gametype == GT_BATTLE && player->kartstuff[k_bumper] <= 0) // dead in match? you da bomb + if (gametype == GT_BATTLE && player->bumpers <= 0) // dead in match? you da bomb { K_DropItems(player); //K_StripItems(player); K_StripOther(player); player->mo->drawflags |= MFD_SHADOW; - player->powers[pw_flashing] = player->kartstuff[k_comebacktimer]; + player->powers[pw_flashing] = player->karmadelay; } - else if (gametype == GT_RACE || player->kartstuff[k_bumper] > 0) + else if (gametype == GT_RACE || player->bumpers > 0) { player->mo->drawflags &= ~(MFD_TRANSMASK|MFD_BRIGHTMASK); } diff --git a/src/k_kart.h b/src/k_kart.h index 2d682511a..0a4765b32 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -41,7 +41,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); void K_DoInstashield(player_t *player); void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted); -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount); +void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount, boolean force); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9ddbd868e..a7bad0390 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3382,12 +3382,13 @@ static int lib_kStealBumper(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *victim = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); + UINT8 amount = (UINT8)luaL_optinteger(L, 3, 1); NOHUD if (!player) return LUA_ErrInvalid(L, "player_t"); if (!victim) return LUA_ErrInvalid(L, "player_t"); - K_StealBumper(player, victim); + K_StealBumper(player, victim, amount); return 0; } diff --git a/src/p_enemy.c b/src/p_enemy.c index 605ba24b0..fe7bd65aa 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4428,7 +4428,7 @@ static inline boolean PIT_GrenadeRing(mobj_t *thing) return true; if (thing->player && (thing->player->kartstuff[k_hyudorotimer] - || ((gametyperules & GTR_BUMPERS) && thing->player && thing->player->kartstuff[k_bumper] <= 0 && thing->player->kartstuff[k_comebacktimer]))) + || ((gametyperules & GTR_BUMPERS) && thing->player && thing->player->bumpers <= 0 && thing->player->karmadelay))) return true; // see if it went over / under @@ -4493,7 +4493,7 @@ static inline boolean PIT_MineExplode(mobj_t *thing) if (netgame && thing->player && thing->player->spectator) return true; - if ((gametyperules & GTR_BUMPERS) && grenade->target && grenade->target->player && grenade->target->player->kartstuff[k_bumper] <= 0 && thing == grenade->target) + if ((gametyperules & GTR_BUMPERS) && grenade->target && grenade->target->player && grenade->target->player->bumpers <= 0 && thing == grenade->target) return true; // see if it went over / under @@ -8641,7 +8641,7 @@ void A_ItemPop(mobj_t *actor) if (actor->info->deathsound) S_StartSound(remains, actor->info->deathsound); - if (!((gametyperules & GTR_BUMPERS) && actor->target->player->kartstuff[k_bumper] <= 0)) + if (!((gametyperules & GTR_BUMPERS) && actor->target->player->bumpers <= 0)) actor->target->player->kartstuff[k_itemroulette] = 1; remains->flags2 &= ~MF2_AMBUSH; @@ -9707,7 +9707,7 @@ void A_ReaperThinker(mobj_t *actor) continue; player = &players[i]; - if (player && player->mo && player->kartstuff[k_bumper] && player->score >= maxscore) + if (player && player->mo && player->bumpers && player->score >= maxscore) { targetplayermo = player->mo; maxscore = player->score; diff --git a/src/p_inter.c b/src/p_inter.c index 82a11f3df..c23221ae1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -111,7 +111,7 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) if (player->exiting || mapreset) return false; - /*if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0) // No bumpers in Match + /*if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) // No bumpers in Match return false;*/ if (weapon) @@ -235,7 +235,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!P_CanPickupItem(player, 3) || (player->kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != special->threshold)) return; - if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0) + if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) return; player->kartstuff[k_itemtype] = special->threshold; @@ -256,11 +256,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!P_CanPickupItem(player, 1)) return; - if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0) + if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) { - if (player->kartstuff[k_comebackmode] || player->kartstuff[k_comebacktimer]) +#ifdef OTHERKARMAMODES + if (player->kartstuff[k_comebackmode] || player->karmadelay) return; player->kartstuff[k_comebackmode] = 1; +#else + return; +#endif } special->momx = special->momy = special->momz = 0; @@ -272,7 +276,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; if (player == special->target->player) return; - if (player->kartstuff[k_bumper] <= 0) + if (player->bumpers <= 0) return; if (special->target->player->exiting || player->exiting) return; @@ -280,53 +284,41 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (P_PlayerInPain(special->target->player)) return; + if (special->target->player->karmadelay > 0) + return; + +#ifdef OTHERKARMAMODES if (!special->target->player->kartstuff[k_comebackmode]) { - if (player->kartstuff[k_growshrinktimer] || player->kartstuff[k_squishedtimer] - || player->kartstuff[k_hyudorotimer] || P_PlayerInPain(player) - || player->kartstuff[k_invincibilitytimer] || player->powers[pw_flashing]) - return; - else +#endif { - mobj_t *boom = P_SpawnMobj(special->target->x, special->target->y, special->target->z, MT_BOOMEXPLODE); - UINT8 ptadd = (K_IsPlayerWanted(player) ? 2 : 1); + mobj_t *boom; + + if (P_DamageMobj(toucher, special, special->target, 1, DMG_EXPLODE) == false) + { + return; + } + + boom = P_SpawnMobj(special->target->x, special->target->y, special->target->z, MT_BOOMEXPLODE); boom->scale = special->target->scale; boom->destscale = special->target->scale; boom->momz = 5*FRACUNIT; + if (special->target->color) boom->color = special->target->color; else boom->color = SKINCOLOR_KETCHUP; + S_StartSound(boom, special->info->attacksound); - if (player->kartstuff[k_bumper] == 1) // If you have only one bumper left, and see if it's a 1v1 - { - INT32 numingame = 0; + K_StealBumper(special->target->player, player, max(1, player->bumpers-1)); // bumpers-1 to slowly remove bumpers from the economy + K_RemoveBumper(player, special->target, special->target, player->bumpers, true); - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator || players[i].kartstuff[k_bumper] <= 0) - continue; - numingame++; - } - - if (numingame <= 2) // If so, then an extra karma point so they are 100% certain to switch places; it's annoying to end matches with a bomb kill - ptadd++; - } - - special->target->player->kartstuff[k_comebackpoints] += ptadd; - - if (ptadd > 1) - special->target->player->karthud[khud_yougotem] = 2*TICRATE; - - if (special->target->player->kartstuff[k_comebackpoints] >= 2) - K_StealBumper(special->target->player, player, 1); - - special->target->player->kartstuff[k_comebacktimer] = comebacktime; - - P_DamageMobj(toucher, special, special->target, 1, DMG_EXPLODE); + special->target->player->karthud[khud_yougotem] = 2*TICRATE; + special->target->player->karmadelay = comebacktime; } +#ifdef OTHERKARMAMODES } else if (special->target->player->kartstuff[k_comebackmode] == 1 && P_CanPickupItem(player, 1)) { @@ -350,7 +342,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->target->player->kartstuff[k_comebackpoints] >= 2) K_StealBumper(special->target->player, player, 1); - special->target->player->kartstuff[k_comebacktimer] = comebacktime; + special->target->player->karmadelay = comebacktime; player->kartstuff[k_itemroulette] = 1; player->kartstuff[k_roulettetype] = 1; @@ -362,13 +354,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(poof, special->info->seesound); - if (player->kartstuff[k_bumper] == 1) // If you have only one bumper left, and see if it's a 1v1 + if (player->bumpers == 1) // If you have only one bumper left, and see if it's a 1v1 { INT32 numingame = 0; for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i] || players[i].spectator || players[i].kartstuff[k_bumper] <= 0) + if (!playeringame[i] || players[i].spectator || players[i].bumpers <= 0) continue; numingame++; } @@ -386,7 +378,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->target->player->kartstuff[k_comebackpoints] >= 2) K_StealBumper(special->target->player, player, 1); - special->target->player->kartstuff[k_comebacktimer] = comebacktime; + special->target->player->karmadelay = comebacktime; K_DropItems(player); //K_StripItems(player); //K_StripOther(player); @@ -404,6 +396,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->target->player->kartstuff[k_eggmanblame] = -1; } +#endif return; case MT_SPB: if ((special->target == toucher || special->target == toucher->target) && (special->threshold > 0)) @@ -474,7 +467,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(special, sfx_s1a2); return; case MT_CDUFO: // SRB2kart - if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0)) + if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)) return; player->kartstuff[k_itemroulette] = 1; @@ -561,6 +554,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->spheres >= 40) return; + // Not alive + if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= 0)) + return; + special->momx = special->momy = special->momz = 0; player->spheres++; break; @@ -1665,7 +1662,7 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) { case DMG_DEATHPIT: // Respawn kill types - K_RemoveBumper(player, NULL, NULL, 1); + K_RemoveBumper(player, NULL, NULL, 1, true); K_DoIngameRespawn(player); return false; default: @@ -1673,8 +1670,6 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) break; } - K_RemoveBumper(player, NULL, NULL, player->kartstuff[k_bumper]); - player->pflags &= ~PF_SLIDING; player->powers[pw_carry] = CR_NONE; @@ -1690,17 +1685,23 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); - if ((type == DMG_TIMEOVER) && (gametype == GT_RACE)) + if (type == DMG_TIMEOVER) { - mobj_t *boom; + if (gametyperules & GTR_CIRCUIT) + { + mobj_t *boom; - player->mo->flags |= (MF_NOGRAVITY|MF_NOCLIP); - player->mo->drawflags |= MFD_DONTDRAW; + player->mo->flags |= (MF_NOGRAVITY|MF_NOCLIP); + player->mo->drawflags |= MFD_DONTDRAW; - boom = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FZEROBOOM); - boom->scale = player->mo->scale; - boom->angle = player->mo->angle; - P_SetTarget(&boom->target, player->mo); + boom = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FZEROBOOM); + boom->scale = player->mo->scale; + boom->angle = player->mo->angle; + P_SetTarget(&boom->target, player->mo); + } + + K_RemoveBumper(player, NULL, NULL, player->bumpers, true); + player->eliminated = true; } return true; @@ -1849,9 +1850,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { if (gametyperules & GTR_BUMPERS) { - if ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || (player->kartstuff[k_comebackmode] == 1)) + if ((player->bumpers <= 0 && player->karmadelay) || (player->kartstuff[k_comebackmode] == 1)) { - // No bumpers, can't be hurt + // No bumpers & in WAIT, can't be hurt K_DoInstashield(player); return false; } @@ -1900,7 +1901,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da K_StealBumper(source->player, player, bumpadd); } - K_RemoveBumper(player, inflictor, source, bumpadd); + K_RemoveBumper(player, inflictor, source, bumpadd, false); } player->kartstuff[k_sneakertimer] = player->kartstuff[k_numsneakers] = 0; diff --git a/src/p_map.c b/src/p_map.c index 4a33b5427..f213c2d37 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1294,8 +1294,8 @@ static boolean PIT_CheckThing(mobj_t *thing) } if ((gametyperules & GTR_BUMPERS) - && ((thing->player->kartstuff[k_bumper] && !tmthing->player->kartstuff[k_bumper]) - || (tmthing->player->kartstuff[k_bumper] && !thing->player->kartstuff[k_bumper]))) + && ((thing->player->bumpers && !tmthing->player->bumpers) + || (tmthing->player->bumpers && !thing->player->bumpers))) { return true; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 9957f4114..7eecebb62 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5286,10 +5286,10 @@ static void P_MobjSceneryThink(mobj_t *mobj) else ang = FixedAngle(mobj->info->speed); - if (mobj->target->player->kartstuff[k_bumper] <= 1) + if (mobj->target->player->bumpers <= 1) diff = 0; else - diff = FixedAngle(360*FRACUNIT/mobj->target->player->kartstuff[k_bumper]); + diff = FixedAngle(360*FRACUNIT/mobj->target->player->bumpers); ang = (ang*leveltime) + (diff * (mobj->threshold-1)); @@ -5318,9 +5318,9 @@ static void P_MobjSceneryThink(mobj_t *mobj) else mobj->color = mobj->target->color; // but do so if it belongs to you :B - if (mobj->target->player->kartstuff[k_bumper] < 2) + if (mobj->target->player->bumpers < 2) P_SetMobjState(mobj, S_BATTLEBUMPER3); - else if (mobj->target->player->kartstuff[k_bumper] < 3) + else if (mobj->target->player->bumpers < 3) P_SetMobjState(mobj, S_BATTLEBUMPER2); else P_SetMobjState(mobj, S_BATTLEBUMPER1); @@ -5338,7 +5338,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) } // Was this so hard? - if (mobj->target->player->kartstuff[k_bumper] <= mobj->threshold) + if (mobj->target->player->bumpers <= mobj->threshold) { P_RemoveMobj(mobj); return; @@ -5363,7 +5363,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->color = mobj->target->color; K_MatchGenericExtraFlags(mobj, mobj->target); - if ((gametype == GT_RACE || mobj->target->player->kartstuff[k_bumper] <= 0) + if ((gametype == GT_RACE || mobj->target->player->bumpers <= 0) #if 1 // Set to 0 to test without needing to host || (P_IsDisplayPlayer(mobj->target->player)) #endif @@ -7019,7 +7019,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) statenum_t state = (mobj->state-states); if (!mobj->target || !mobj->target->health || !mobj->target->player || mobj->target->player->spectator - || (gametype == GT_RACE || mobj->target->player->kartstuff[k_bumper])) + || (gametype == GT_RACE || mobj->target->player->bumpers)) { P_RemoveMobj(mobj); return false; @@ -7040,11 +7040,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->radius = 24*mobj->target->scale; mobj->height = 2*mobj->radius; - if (mobj->target->player->kartstuff[k_comebacktimer] > 0) + if (mobj->target->player->karmadelay > 0) { if (state < S_PLAYERBOMB1 || state > S_PLAYERBOMB20) P_SetMobjState(mobj, S_PLAYERBOMB1); - if (mobj->target->player->kartstuff[k_comebacktimer] < TICRATE && (leveltime & 1)) + if (mobj->target->player->karmadelay < TICRATE && (leveltime & 1)) mobj->drawflags &= ~MFD_DONTDRAW; else mobj->drawflags |= MFD_DONTDRAW; @@ -10153,22 +10153,22 @@ void P_SpawnPlayer(INT32 playernum) P_SetScale(overheadarrow, mobj->destscale); if (p->spectator && pcount > 1) // HEY! No being cheap... - p->kartstuff[k_bumper] = 0; - else if (p->kartstuff[k_bumper] > 0 || leveltime < 1 + p->bumpers = 0; + else if (p->bumpers > 0 || leveltime < 1 || (p->jointime <= 1 && pcount <= 1)) { if (leveltime < 1 || (p->jointime <= 1 && pcount <= 1)) // Start of the map? - p->kartstuff[k_bumper] = K_StartingBumperCount(); // Reset those bumpers! + p->bumpers = K_StartingBumperCount(); // Reset those bumpers! - if (p->kartstuff[k_bumper]) + if (p->bumpers) { - angle_t diff = FixedAngle(360*FRACUNIT/p->kartstuff[k_bumper]); + angle_t diff = FixedAngle(360*FRACUNIT/p->bumpers); angle_t newangle = mobj->angle; fixed_t newx = mobj->x + P_ReturnThrustX(mobj, newangle + ANGLE_180, 64*FRACUNIT); fixed_t newy = mobj->y + P_ReturnThrustY(mobj, newangle + ANGLE_180, 64*FRACUNIT); mobj_t *mo; - for (i = 0; i < p->kartstuff[k_bumper]; i++) + for (i = 0; i < p->bumpers; i++) { mo = P_SpawnMobj(newx, newy, mobj->z, MT_BATTLEBUMPER); mo->threshold = i; @@ -10182,7 +10182,7 @@ void P_SpawnPlayer(INT32 playernum) } } } - else if (p->kartstuff[k_bumper] <= 0) + else if (p->bumpers <= 0) { mobj_t *karmahitbox = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_KARMAHITBOX); // Player hitbox is too small!! P_SetTarget(&karmahitbox->target, mobj); diff --git a/src/p_saveg.c b/src/p_saveg.c index c9797000e..b3ea81ecd 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -255,6 +255,10 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); WRITEUINT32(save_p, players[i].airtime); + WRITEINT16(save_p, players[i].bumpers); + WRITEINT16(save_p, players[i].karmadelay); + WRITEUINT8(save_p, players[i].eliminated); + // respawnvars_t WRITEUINT8(save_p, players[i].respawn.state); WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].respawn.wp)); @@ -441,6 +445,10 @@ static void P_NetUnArchivePlayers(void) players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p); players[i].airtime = READUINT32(save_p); + players[i].bumpers = READINT16(save_p); + players[i].karmadelay = READINT16(save_p); + players[i].eliminated = (boolean)READUINT8(save_p); + // respawnvars_t players[i].respawn.state = READUINT8(save_p); players[i].respawn.wp = (waypoint_t *)(size_t)READUINT32(save_p); diff --git a/src/p_user.c b/src/p_user.c index 2a67d8360..9cf365ab5 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4515,7 +4515,7 @@ void P_PlayerThink(player_t *player) || player->kartstuff[k_growshrinktimer] > 0 // Grow doesn't flash either. || (player->respawn.state != RESPAWNST_NONE) // Respawn timer (for drop dash effect) || (player->pflags & PF_GAMETYPEOVER) // NO CONTEST explosion - || ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) + || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0 && player->karmadelay) || leveltime < starttime)) // Level intro { if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < K_GetKartFlashing(player) From c92871d31722085a5e172422ca406310159585e2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 11:28:02 -0400 Subject: [PATCH 19/99] Fix name tags showing for dead or invisible players --- src/k_hud.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/k_hud.c b/src/k_hud.c index 73e656fcb..b3ea7cd29 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2555,6 +2555,18 @@ static void K_drawKartNameTags(void) continue; } + if (ntplayer->mo->drawflags & K_GetPlayerDontDrawFlag(stplyr)) + { + // Invisible on this screen + continue; + } + + if ((gametyperules & GTR_BUMPERS) && (ntplayer->bumpers <= 0)) + { + // Dead in Battle + continue; + } + if (!P_CheckSight(stplyr->mo, ntplayer->mo)) { // Can't see From dc7fe0bd586431222f7d12ac80987e0cec2ae1cd Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 11:33:07 -0400 Subject: [PATCH 20/99] Fix overtime barrier not applying to bombs/flashing players --- src/k_kart.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 80d9546d1..af66c739b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5770,23 +5770,23 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_KartPlayerHUDUpdate(player); - if ((gametyperules & GTR_BUMPERS) && player->bumpers > 0 && !P_PlayerInPain(player) && !player->powers[pw_flashing]) + if ((gametyperules & GTR_WANTED) && player->bumpers > 0 && !P_PlayerInPain(player) && !player->powers[pw_flashing]) { player->kartstuff[k_wanted]++; + } - if (battleovertime.enabled >= 10*TICRATE) + if (battleovertime.enabled >= 10*TICRATE) + { + fixed_t distanceToBarrier = 0; + + if (battleovertime.radius > 0) { - fixed_t distanceToBarrier = 0; + distanceToBarrier = R_PointToDist2(player->mo->x, player->mo->y, battleovertime.x, battleovertime.y) - (player->mo->radius * 2); + } - if (battleovertime.radius > 0) - { - distanceToBarrier = R_PointToDist2(player->mo->x, player->mo->y, battleovertime.x, battleovertime.y) - (player->mo->radius * 2); - } - - if (distanceToBarrier > battleovertime.radius) - { - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER); - } + if (distanceToBarrier > battleovertime.radius) + { + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER); } } From 5504cb8ceeb9d6fbdf6994f22c34922354563ab7 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 11:46:56 -0400 Subject: [PATCH 21/99] Don't show comeback timer & screen fade after you've been eliminated --- src/k_hud.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index b3ea7cd29..ff689f7f2 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -3904,11 +3904,12 @@ void K_drawKartHUD(void) return; } - battlefullscreen = ((gametype == GT_BATTLE) + battlefullscreen = ((gametyperules & (GTR_BUMPERS|GTR_KARMA)) == (GTR_BUMPERS|GTR_KARMA) && (stplyr->exiting || (stplyr->bumpers <= 0 - && stplyr->karmadelay - && comeback + && stplyr->karmadelay > 0 + && stplyr->eliminated == false + && comeback == true && stplyr->playerstate == PST_LIVE))); if (!demo.title && (!battlefullscreen || r_splitscreen)) From 5db7b337d9ca6ed9472e3512a37f4e45175ab04b Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 21:45:35 -0400 Subject: [PATCH 22/99] Speed up sphere respawn --- src/p_mobj.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 96086a849..11cd407b9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9967,7 +9967,11 @@ void P_RespawnSpecials(void) if (gametyperules & GTR_SPHERES) { - time = ((MAXPLAYERS+1) - pcount) * (2*TICRATE); + if (pcount > 2) + time -= (5*TICRATE) * (pcount-2); + + if (time < 5*TICRATE) + time = 5*TICRATE; } else { @@ -9975,7 +9979,7 @@ void P_RespawnSpecials(void) return; else if (pcount > 1) { - time = (120 - ((pcount-2) * 10))*TICRATE; + time = (120 - ((pcount-2) * 10)) * TICRATE; // If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this. // 5 lap courses would have more retreaded ground, while 2 lap courses would have less. From 449d1df014352f47964afe7dd9525343e338c2f0 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 21:46:23 -0400 Subject: [PATCH 23/99] Remove flashing tics increase in Battle --- src/k_kart.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 0a4d06b29..58c2d5f65 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2288,9 +2288,6 @@ UINT16 K_GetKartFlashing(player_t *player) tics += (tics/8) * (player->kartspeed); - if (gametype == GT_BATTLE) - tics *= 2; - return tics; } From ed6787ae4dd358d2e2eb62686ab6b413f81364a0 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Oct 2020 14:42:23 -0400 Subject: [PATCH 24/99] remove lj's thing --- src/d_clisrv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 21eb83d74..0e1d58098 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -6136,12 +6136,12 @@ void NetUpdate(void) firstticstosend = gametic; for (i = 0; i < MAXNETNODES; i++) if (nodeingame[i] && nettics[i] < firstticstosend) - { + //{ firstticstosend = nettics[i]; - if (maketic + 1 >= nettics[i] + BACKUPTICS) - Net_ConnectionTimeout(i); - } + //if (maketic + 1 >= nettics[i] + BACKUPTICS) + //Net_ConnectionTimeout(i); + //} // Don't erase tics not acknowledged counts = realtics; From 5f0658e6ca700bb248cb06552b00523c0feeae59 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Oct 2020 16:07:33 -0400 Subject: [PATCH 25/99] The barrier won't do anything if they've already been eliminated --- 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 4a62e9a78..cc9824722 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5765,7 +5765,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->kartstuff[k_wanted]++; } - if (battleovertime.enabled >= 10*TICRATE) + if ((battleovertime.enabled >= 10*TICRATE) && (player->eliminated == false)) { fixed_t distanceToBarrier = 0; From 6a2ace3067939fec8ef1cc9d1b51703627836c91 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 25 Oct 2020 13:12:08 -0700 Subject: [PATCH 26/99] Fix compiler warning --- src/k_battle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_battle.c b/src/k_battle.c index 518ae260f..3b4a0e95f 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -382,7 +382,7 @@ void K_RunBattleOvertime(void) if (battleovertime.radius > 0) { const fixed_t pi = (22 * FRACUNIT) / 7; // loose approximation, this doesn't need to be incredibly precise - const UINT32 orbs = 32; + const INT32 orbs = 32; const angle_t angoff = ANGLE_MAX / orbs; const UINT8 spriteSpacing = 128; From 4570757c4eaaebf174c9c911e53cfd503c298a47 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 25 Oct 2020 15:42:14 -0700 Subject: [PATCH 27/99] Fix item respawn time underflow --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b1b415114..c9cf27b87 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9945,7 +9945,7 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype) void P_RespawnSpecials(void) { UINT8 p, pcount = 0; - tic_t time = 30*TICRATE; // Respawn things in empty dedicated servers + INT32 time = 30*TICRATE; // Respawn things in empty dedicated servers mapthing_t *mthing = NULL; if (!(gametyperules & GTR_CIRCUIT) && numgotboxes >= (4*nummapboxes/5)) // Battle Mode respawns all boxes in a different way @@ -9993,7 +9993,7 @@ void P_RespawnSpecials(void) return; // the first item in the queue is the first to respawn - if (leveltime - itemrespawntime[iquetail] < time) + if (leveltime - itemrespawntime[iquetail] < (tic_t)time) return; mthing = itemrespawnque[iquetail]; From 62139f144a65c93b7a8233e21b480bfdf252c081 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 26 Oct 2020 22:20:02 -0400 Subject: [PATCH 28/99] Paper item spawners Code is a little horrendous in a few places but I will hopefully fix later :V --- src/dehacked.c | 2 + src/doomstat.h | 33 ++++++------ src/g_game.c | 2 +- src/info.c | 27 ++++++++++ src/info.h | 2 + src/k_battle.c | 123 ++++++++++++++++++++++++++++++++++++++++++++- src/k_battle.h | 1 + src/k_kart.c | 133 +++++++++++++++++++++++++++++++++++++++++++------ src/k_kart.h | 1 + src/p_mobj.c | 3 ++ src/p_tick.c | 6 +++ 11 files changed, 298 insertions(+), 35 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 1fa855c9a..cc0c336d3 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -10430,6 +10430,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_WATERTRAIL", "MT_WATERTRAILUNDERLAY", + "MT_PAPERITEMSPOT", + #ifdef SEENAMES "MT_NAMECHECK", #endif diff --git a/src/doomstat.h b/src/doomstat.h index b8d82f379..57738aaa2 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -459,27 +459,28 @@ enum GameTypeRules GTR_BOTS = 1<<2, // Allows bots in this gametype. Combine with BotTiccmd hooks to make bots support your gametype. // Battle gametype rules - GTR_SPHERES = 1<<3, // Replaces rings with blue spheres - GTR_BUMPERS = 1<<4, // Enables the bumper health system - GTR_WANTED = 1<<5, // Enables the wanted anti-camping system - GTR_KARMA = 1<<6, // Enables the Karma system if you're out of bumpers - GTR_ITEMARROWS = 1<<7, // Show item box arrows above players - GTR_CAPSULES = 1<<8, // Enables the wanted anti-camping system - GTR_BATTLESTARTS = 1<<9, // Use Battle Mode start positions. + GTR_BUMPERS = 1<<3, // Enables the bumper health system + GTR_SPHERES = 1<<4, // Replaces rings with blue spheres + GTR_PAPERITEMS = 1<<5, // Replaces item boxes with paper item spawners + GTR_WANTED = 1<<6, // Enables the wanted anti-camping system + GTR_KARMA = 1<<7, // Enables the Karma system if you're out of bumpers + GTR_ITEMARROWS = 1<<8, // Show item box arrows above players + GTR_CAPSULES = 1<<9, // Enables the wanted anti-camping system + GTR_BATTLESTARTS = 1<<10, // Use Battle Mode start positions. - GTR_POINTLIMIT = 1<<10, // Reaching point limit ends the round - GTR_TIMELIMIT = 1<<11, // Reaching time limit ends the round - GTR_OVERTIME = 1<<12, // Allow overtime behavior + GTR_POINTLIMIT = 1<<11, // Reaching point limit ends the round + GTR_TIMELIMIT = 1<<12, // Reaching time limit ends the round + GTR_OVERTIME = 1<<13, // Allow overtime behavior // Custom gametype rules - GTR_TEAMS = 1<<13, // Teams are forced on - GTR_NOTEAMS = 1<<14, // Teams are forced off - GTR_TEAMSTARTS = 1<<15, // Use team-based start positions + GTR_TEAMS = 1<<14, // Teams are forced on + GTR_NOTEAMS = 1<<15, // Teams are forced off + GTR_TEAMSTARTS = 1<<16, // Use team-based start positions // Grand Prix rules - GTR_CAMPAIGN = 1<<16, // Handles cup-based progression - GTR_LIVES = 1<<17, // Lives system, players are forced to spectate during Game Over. - GTR_SPECIALBOTS = 1<<18, // Bot difficulty gets stronger between rounds, and the rival system is enabled. + GTR_CAMPAIGN = 1<<17, // Handles cup-based progression + GTR_LIVES = 1<<18, // Lives system, players are forced to spectate during Game Over. + GTR_SPECIALBOTS = 1<<19, // Bot difficulty gets stronger between rounds, and the rival system is enabled. // free: to and including 1<<31 }; diff --git a/src/g_game.c b/src/g_game.c index 4378b014e..793ec8dbb 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2793,7 +2793,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = // Race GTR_CIRCUIT|GTR_BOTS, // Battle - GTR_SPHERES|GTR_BUMPERS|GTR_WANTED|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME + GTR_SPHERES|GTR_BUMPERS|GTR_PAPERITEMS|GTR_WANTED|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME }; // diff --git a/src/info.c b/src/info.c index 8bd117731..90da90918 100644 --- a/src/info.c +++ b/src/info.c @@ -28680,6 +28680,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_PAPERITEMSPOT + -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 + 0, // speed + 48*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + // ============================================================================================================================// #ifdef SEENAMES diff --git a/src/info.h b/src/info.h index b56f436b2..e7d21744e 100644 --- a/src/info.h +++ b/src/info.h @@ -6312,6 +6312,8 @@ typedef enum mobj_type MT_WATERTRAIL, MT_WATERTRAILUNDERLAY, + MT_PAPERITEMSPOT, + #ifdef SEENAMES MT_NAMECHECK, #endif diff --git a/src/k_battle.c b/src/k_battle.c index 518ae260f..b3939dad8 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -277,6 +277,127 @@ void K_CheckBumpers(void) P_DoPlayerExit(&players[i]); } +void K_RunPaperItemSpawners(void) +{ + const boolean overtime = (battleovertime.enabled >= 10*TICRATE); + tic_t interval = 8*TICRATE; + + if (leveltime <= starttime) + { + return; + } + + if ((battleovertime.enabled > 0) && (battleovertime.radius < 256*mapobjectscale)) + { + return; + } + + if (overtime == true) + { + interval /= 2; + } + + if (((leveltime - starttime - (interval / 2)) % interval) != 0) + { + return; + } + + if (overtime == true) + { + SINT8 flip = 1; + + K_CreatePaperItem( + battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip), + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + 0, 0 + ); + } + else + { + UINT8 pcount = 0; + UINT8 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator + || players[i].exiting > 0 + || players[i].eliminated) + { + continue; + } + + if ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0) + { + continue; + } + + pcount++; + } + + if (pcount > 0) + { +#define MAXITEM 64 + UINT16 item = 0; + mobj_t *spotList[MAXITEM]; + boolean spotUsed[MAXITEM]; + + thinker_t *th; + mobj_t *mo; + + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (item >= MAXITEM) + break; + + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo = (mobj_t *)th; + + if (mo->type == MT_PAPERITEMSPOT) + { + spotList[item] = mo; + item++; + } + } + + if (item <= 0) + { + return; + } + + for (i = 0; i < min(item, pcount); i++) + { + UINT8 r = P_RandomRange(0, item-1); + UINT8 recursion = 0; + mobj_t *drop = NULL; + SINT8 flip = 1; + + while (spotUsed[r] == true) + { + r = P_RandomRange(0, item-1); + + if ((recursion++) > 32) + { + break; + } + } + + flip = P_MobjFlip(spotList[r]); + + drop = K_CreatePaperItem( + spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip), + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + 0, 0 + ); + + K_FlipFromObject(drop, spotList[r]); + spotUsed[r] = true; + } + } + } +} + static void K_SpawnOvertimeLaser(fixed_t x, fixed_t y, fixed_t scale) { UINT8 i, j; @@ -359,8 +480,6 @@ static void K_SpawnOvertimeLaser(fixed_t x, fixed_t y, fixed_t scale) } } -#undef MAXPLANESPERSECTOR - void K_RunBattleOvertime(void) { if (battleovertime.enabled < 10*TICRATE) diff --git a/src/k_battle.h b/src/k_battle.h index 3f63e25f2..90ee20df7 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -20,6 +20,7 @@ boolean K_IsPlayerWanted(player_t *player); void K_CalculateBattleWanted(void); void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); void K_CheckBumpers(void); +void K_RunPaperItemSpawners(void); void K_RunBattleOvertime(void); void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj); void K_SpawnBattleCapsules(void); diff --git a/src/k_kart.c b/src/k_kart.c index cc9824722..273903ff0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4342,6 +4342,118 @@ void K_DropHnextList(player_t *player, boolean keepshields) } } +mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 type, UINT8 amount) +{ + mobj_t *drop = P_SpawnMobj(x, y, z, MT_FLOATINGITEM); + P_SetScale(drop, drop->scale>>4); + drop->destscale = (3*drop->destscale)/2; + + drop->angle = angle; + P_Thrust(drop, + FixedAngle(P_RandomFixed() * 180) + angle, + 16*mapobjectscale); + + drop->momz = flip * 3 * mapobjectscale; + if (drop->eflags & MFE_UNDERWATER) + drop->momz = (117 * drop->momz) / 200; + + if (type == 0) + { + UINT8 useodds = 0; + INT32 spawnchance[NUMKARTRESULTS]; + INT32 totalspawnchance = 0; + INT32 i; + + memset(spawnchance, 0, sizeof (spawnchance)); + + useodds = amount; + + for (i = 1; i < NUMKARTRESULTS; i++) + spawnchance[i] = (totalspawnchance += K_KartGetItemOdds(useodds, i, 0, false, false, false)); + + if (totalspawnchance > 0) + { + UINT8 newType; + UINT8 newAmount; + + totalspawnchance = P_RandomKey(totalspawnchance); + for (i = 0; i < NUMKARTRESULTS && spawnchance[i] <= totalspawnchance; i++); + + // TODO: this is bad! + // K_KartGetItemResult requires a player + // but item roulette will need rewritten to change this + + switch (i) + { + // Special roulettes first, then the generic ones are handled by default + case KRITEM_DUALSNEAKER: // Sneaker x2 + newType = KITEM_SNEAKER; + newAmount = 2; + break; + case KRITEM_TRIPLESNEAKER: // Sneaker x3 + newType = KITEM_SNEAKER; + newAmount = 3; + break; + case KRITEM_TRIPLEBANANA: // Banana x3 + newType = KITEM_BANANA; + newAmount = 3; + break; + case KRITEM_TENFOLDBANANA: // Banana x10 + newType = KITEM_BANANA; + newAmount = 10; + break; + case KRITEM_TRIPLEORBINAUT: // Orbinaut x3 + newType = KITEM_ORBINAUT; + newAmount = 3; + break; + case KRITEM_QUADORBINAUT: // Orbinaut x4 + newType = KITEM_ORBINAUT; + newAmount = 4; + break; + case KRITEM_DUALJAWZ: // Jawz x2 + newType = KITEM_JAWZ; + newAmount = 2; + break; + default: + newType = i; + newAmount = 1; + break; + } + + if (newAmount > 1) + { + UINT8 j; + + for (j = 0; j < newAmount-1; j++) + { + K_CreatePaperItem( + x, y, z, + angle, flip, + newType, 1 + ); + } + } + + drop->threshold = newType; + drop->movecount = 1; + } + else + { + drop->threshold = 1; + drop->movecount = 1; + } + } + else + { + drop->threshold = type; + drop->movecount = amount; + } + + drop->flags |= MF_NOCLIPTHING; + + return drop; +} + // For getting EXTRA hit! void K_DropItems(player_t *player) { @@ -4349,24 +4461,13 @@ void K_DropItems(player_t *player) if (player->mo && !P_MobjWasRemoved(player->mo) && player->kartstuff[k_itemamount] > 0) { - mobj_t *drop = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FLOATINGITEM); - P_SetScale(drop, drop->scale>>4); - drop->destscale = (3*drop->destscale)/2; - - drop->angle = player->mo->angle + ANGLE_90; - P_Thrust(drop, - FixedAngle(P_RandomFixed()*180) + player->mo->angle + ANGLE_90, - 16*mapobjectscale); - drop->momz = P_MobjFlip(player->mo)*3*mapobjectscale; - if (drop->eflags & MFE_UNDERWATER) - drop->momz = (117 * drop->momz) / 200; - - drop->threshold = player->kartstuff[k_itemtype]; - drop->movecount = player->kartstuff[k_itemamount]; + mobj_t *drop = K_CreatePaperItem( + player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, + player->mo->angle + ANGLE_90, P_MobjFlip(player->mo), + player->kartstuff[k_itemtype], player->kartstuff[k_itemamount] + ); K_FlipFromObject(drop, player->mo); - - drop->flags |= MF_NOCLIPTHING; } K_StripItems(player); diff --git a/src/k_kart.h b/src/k_kart.h index 0a4765b32..115b7f47c 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -70,6 +70,7 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue); INT32 K_GetKartDriftSparkValue(player_t *player); void K_SpawnDriftBoostExplosion(player_t *player, int stage); void K_KartUpdatePosition(player_t *player); +mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 type, UINT8 amount); void K_DropItems(player_t *player); void K_DropRocketSneaker(player_t *player); void K_DropKitchenSink(player_t *player); diff --git a/src/p_mobj.c b/src/p_mobj.c index b1b415114..7d5d04bdc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10512,6 +10512,9 @@ static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i) if ((gametyperules & GTR_SPHERES) && (i == MT_RING)) return MT_BLUESPHERE; + if ((gametyperules & GTR_PAPERITEMS) && (i == MT_RANDOMITEM)) + return MT_PAPERITEMSPOT; + return i; } diff --git a/src/p_tick.c b/src/p_tick.c index 79e71c655..5a9acefa1 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -595,6 +595,9 @@ void P_Ticker(boolean run) if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled) K_RunBattleOvertime(); + if (gametyperules & GTR_PAPERITEMS) + K_RunPaperItemSpawners(); + ps_lua_thinkframe_time = I_GetTimeMicros(); LUAh_ThinkFrame(); ps_lua_thinkframe_time = I_GetTimeMicros() - ps_lua_thinkframe_time; @@ -755,6 +758,9 @@ void P_PreTicker(INT32 frames) if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled) K_RunBattleOvertime(); + if (gametyperules & GTR_PAPERITEMS) + K_RunPaperItemSpawners(); + LUAh_ThinkFrame(); // Run shield positioning From 16e08d43889e2080de2a033d308c47dbd567e6bb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 26 Oct 2020 22:33:14 -0400 Subject: [PATCH 29/99] Don't run P_RespawnBattleBoxes --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e40885875..e13e9f428 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9948,8 +9948,8 @@ void P_RespawnSpecials(void) INT32 time = 30*TICRATE; // Respawn things in empty dedicated servers mapthing_t *mthing = NULL; - if (!(gametyperules & GTR_CIRCUIT) && numgotboxes >= (4*nummapboxes/5)) // Battle Mode respawns all boxes in a different way - P_RespawnBattleBoxes(); + //if (!(gametyperules & GTR_CIRCUIT) && numgotboxes >= (4*nummapboxes/5)) // Battle Mode respawns all boxes in a different way + //P_RespawnBattleBoxes(); // wait time depends on player count for (p = 0; p < MAXPLAYERS; p++) From ddee6257e7e5cbac6acd90f1995c7cbd64dffd04 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 26 Oct 2020 23:46:56 -0400 Subject: [PATCH 30/99] Move to P_RunThinkers --- src/p_tick.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/p_tick.c b/src/p_tick.c index 5a9acefa1..eed42f049 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -332,6 +332,11 @@ static inline void P_RunThinkers(void) ps_thlist_times[i] = I_GetTimeMicros() - ps_thlist_times[i]; } + if (gametyperules & GTR_PAPERITEMS) + K_RunPaperItemSpawners(); + + if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled) + K_RunBattleOvertime(); } // @@ -592,12 +597,6 @@ void P_Ticker(boolean run) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerAfterThink(&players[i]); - if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled) - K_RunBattleOvertime(); - - if (gametyperules & GTR_PAPERITEMS) - K_RunPaperItemSpawners(); - ps_lua_thinkframe_time = I_GetTimeMicros(); LUAh_ThinkFrame(); ps_lua_thinkframe_time = I_GetTimeMicros() - ps_lua_thinkframe_time; @@ -755,12 +754,6 @@ void P_PreTicker(INT32 frames) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerAfterThink(&players[i]); - if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled) - K_RunBattleOvertime(); - - if (gametyperules & GTR_PAPERITEMS) - K_RunPaperItemSpawners(); - LUAh_ThinkFrame(); // Run shield positioning From a2a947db62148cf687dd6580d230c5f86bb5a9c9 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Oct 2020 00:19:11 -0400 Subject: [PATCH 31/99] bruh thanks jart --- src/k_battle.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/k_battle.c b/src/k_battle.c index 461799f74..cfc389b88 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -344,6 +344,8 @@ void K_RunPaperItemSpawners(void) thinker_t *th; mobj_t *mo; + memset(spotUsed, false, sizeof(spotUsed)); + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { if (item >= MAXITEM) From f8e52ae6a0c34a0677c61d91429c6858176d8b37 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Oct 2020 00:22:33 -0400 Subject: [PATCH 32/99] Increase radius of floating items --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 90da90918..7aa323150 100644 --- a/src/info.c +++ b/src/info.c @@ -22940,7 +22940,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itpick, // deathsound 0, // speed - 32*FRACUNIT, // radius + 48*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset 100, // mass From 63c84567c51ee5d250e208dd3f299bf30b2dc0f5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Oct 2020 00:23:46 -0400 Subject: [PATCH 33/99] Spawn an item right at 0:00.00, instead of at 0:04.00 --- src/k_battle.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index cfc389b88..4c13cd9cf 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -282,7 +282,7 @@ void K_RunPaperItemSpawners(void) const boolean overtime = (battleovertime.enabled >= 10*TICRATE); tic_t interval = 8*TICRATE; - if (leveltime <= starttime) + if (leveltime < starttime) { return; } @@ -297,7 +297,7 @@ void K_RunPaperItemSpawners(void) interval /= 2; } - if (((leveltime - starttime - (interval / 2)) % interval) != 0) + if (((leveltime - starttime) % interval) != 0) { return; } From 714f04c93095dd8fbc7f9ea32ae081fd4bd820f5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Oct 2020 01:09:51 -0400 Subject: [PATCH 34/99] Eliminate karma players at overtime --- src/k_kart.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index bbdc62e82..bee2e88d9 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2451,6 +2451,11 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a karmahitbox->destscale = player->mo->scale; P_SetScale(karmahitbox, player->mo->scale); CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); + + if (battleovertime.enabled > 0) + { + player->eliminated = true; + } } player->bumpers -= amount; @@ -5740,6 +5745,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } else if (player->karmadelay > 0 && !P_PlayerInPain(player)) { + if (battleovertime.enabled > 0) + { + player->eliminated = true; + } + player->karmadelay--; if (P_IsDisplayPlayer(player) && player->bumpers <= 0 && player->karmadelay <= 0) comebackshowninfo = true; // client has already seen the message From 32008425190b20a3afa601789d9e3375deb9317d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Oct 2020 01:27:51 -0400 Subject: [PATCH 35/99] this is stupid --- 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 bee2e88d9..f652778a0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5745,7 +5745,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } else if (player->karmadelay > 0 && !P_PlayerInPain(player)) { - if (battleovertime.enabled > 0) + if ((battleovertime.enabled > 0) && (player->bumpers <= 0)) { player->eliminated = true; } From 9dd43d4e4e342940e0b5819c48fd3ab0d2fe69e6 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 28 Oct 2020 18:36:26 -0400 Subject: [PATCH 36/99] Remove modeltilt, use roll & pitch instead Broken currently, about half of the slopes you can go into have the wrong tilt --- src/hardware/hw_defs.h | 7 +----- src/hardware/hw_md2.c | 20 +++++++--------- src/hardware/r_opengl/r_opengl.c | 2 -- src/k_kart.c | 12 ++++------ src/p_local.h | 1 + src/p_map.c | 8 ++----- src/p_mobj.c | 40 ++++++++++++++++++++++---------- src/p_mobj.h | 3 --- src/p_saveg.c | 5 ---- src/p_slopes.c | 9 +++---- src/p_user.c | 6 ++--- 11 files changed, 51 insertions(+), 62 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index f9e6f0c11..67a996466 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -102,8 +102,7 @@ typedef struct //BP: transform order : scale(rotation_x(rotation_y(translation(v)))) // Kart features -//#define USE_FTRANSFORM_ANGLEZ -//#define USE_FTRANSFORM_MIRROR +#define USE_FTRANSFORM_MIRROR // Vanilla features #define USE_MODEL_NEXTFRAME @@ -111,11 +110,7 @@ typedef struct typedef struct { FLOAT x,y,z; // position -#ifdef USE_FTRANSFORM_ANGLEZ FLOAT anglex,angley,anglez; // aimingangle / viewangle -#else - FLOAT anglex,angley; // aimingangle / viewangle -#endif FLOAT scalex,scaley,scalez; FLOAT fovxangle, fovyangle; UINT8 splitscreen; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 9896eb458..cbf84e212 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1605,22 +1605,18 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) p.rollflip *= -1; } + p.anglez = 0.0f; p.anglex = 0.0f; -#ifdef USE_FTRANSFORM_ANGLEZ - // Slope rotation from Kart - p.anglez = 0.0f; - if (spr->mobj->standingslope) + if (spr->mobj->pitch) { - fixed_t tempz = spr->mobj->standingslope->normal.z; - fixed_t tempy = spr->mobj->standingslope->normal.y; - fixed_t tempx = spr->mobj->standingslope->normal.x; - fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx)); - p.anglez = FIXED_TO_FLOAT(tempangle); - tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy)); - p.anglex = FIXED_TO_FLOAT(tempangle); + p.anglez = FIXED_TO_FLOAT(-AngleFixed(spr->mobj->pitch)); + } + + if (spr->mobj->roll) + { + p.anglex = FIXED_TO_FLOAT(AngleFixed(spr->mobj->roll)); } -#endif // SRB2CBTODO: MD2 scaling support finalscale *= FIXED_TO_FLOAT(spr->mobj->scale); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 942d3d3de..fe07fc808 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2643,9 +2643,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (hflipped) scalez = -scalez; -#ifdef USE_FTRANSFORM_ANGLEZ pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart -#endif pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f); diff --git a/src/k_kart.c b/src/k_kart.c index 8a3597f1f..5196ad751 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4576,10 +4576,7 @@ static void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z } //mobj->standingslope = slope; - -#ifdef HWRENDER - mobj->modeltilt = slope; -#endif + P_SetPitchRollFromSlope(mobj, slope); } // Move the hnext chain! @@ -4872,9 +4869,10 @@ static void K_MoveHeldObjects(player_t *player) P_TeleportMove(cur, targx, targy, targz); K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks. -#ifdef HWRENDER - cur->modeltilt = player->mo->modeltilt; -#endif + + cur->roll = player->mo->roll; + cur->pitch = player->mo->pitch; + num = (num+1) % 2; cur = cur->hnext; } diff --git a/src/p_local.h b/src/p_local.h index bdc28075a..34ba47807 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -517,5 +517,6 @@ boolean P_CheckMissileSpawn(mobj_t *th); void P_Thrust(mobj_t *mo, angle_t angle, fixed_t move); void P_ExplodeMissile(mobj_t *mo); void P_CheckGravity(mobj_t *mo, boolean affect); +void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope); #endif // __P_LOCAL__ diff --git a/src/p_map.c b/src/p_map.c index b8d9820dd..8c4acdfbf 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2633,9 +2633,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thing->momz <= 0) { thing->standingslope = tmfloorslope; -#ifdef HWRENDER - thing->modeltilt = thing->standingslope; -#endif + P_SetPitchRollFromSlope(thing, thing->standingslope); if (thing->momz == 0 && thing->player && !startingonground) P_PlayerHitFloor(thing->player, true); @@ -2648,9 +2646,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thing->momz >= 0) { thing->standingslope = tmceilingslope; -#ifdef HWRENDER - thing->modeltilt = thing->standingslope; -#endif + P_SetPitchRollFromSlope(thing, thing->standingslope); if (thing->momz == 0 && thing->player && !startingonground) P_PlayerHitFloor(thing->player, true); diff --git a/src/p_mobj.c b/src/p_mobj.c index be907321e..59f8af921 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1216,6 +1216,26 @@ void P_CheckGravity(mobj_t *mo, boolean affect) } } +// +// P_SetPitchRollFromSlope +// +void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope) +{ + if (slope) + { + fixed_t tempz = slope->normal.z; + fixed_t tempy = slope->normal.y; + fixed_t tempx = slope->normal.x; + + mo->pitch = -R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx); + mo->roll = -R_PointToAngle2(0, 0, tempz, tempy); + } + else + { + mo->pitch = mo->roll = 0; + } +} + #define STOPSPEED (FRACUNIT) // @@ -1708,9 +1728,7 @@ void P_XYMovement(mobj_t *mo) // Now compare the Zs of the different quantizations if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later mo->standingslope = oldslope; -#ifdef HWRENDER - mo->modeltilt = mo->standingslope; -#endif + P_SetPitchRollFromSlope(mo, mo->standingslope); P_SlopeLaunch(mo); //CONS_Printf("launched off of slope - "); @@ -2228,9 +2246,7 @@ boolean P_ZMovement(mobj_t *mo) if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM)) { mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; -#ifdef HWRENDER - mo->modeltilt = mo->standingslope; -#endif + P_SetPitchRollFromSlope(mo, mo->standingslope); P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope); } @@ -6426,9 +6442,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->target->z); } P_SetScale(mobj, mobj->target->scale); -#ifdef HWRENDER - mobj->modeltilt = mobj->target->modeltilt; -#endif + + mobj->roll = mobj->target->roll; + mobj->pitch = mobj->target->pitch; if (mobj->fuse <= 16) { @@ -6490,9 +6506,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z); P_SetScale(mobj, mobj->target->scale); -#ifdef HWRENDER - mobj->modeltilt = mobj->target->modeltilt; -#endif + + mobj->roll = mobj->target->roll; + mobj->pitch = mobj->target->pitch; { player_t *p = NULL; diff --git a/src/p_mobj.h b/src/p_mobj.h index 6ffa393aa..60fd7d07c 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -408,9 +408,6 @@ typedef struct mobj_s INT32 cvmem; struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) -#ifdef HWRENDER - struct pslope_s *modeltilt; // Slope used for model tilting. Also is not synched, this is totally visual. -#endif boolean colorized; // Whether the mobj uses the rainbow colormap boolean mirrored; // The object's rotations will be mirrored left to right, e.g., see frame AL from the right and AR from the left diff --git a/src/p_saveg.c b/src/p_saveg.c index 0b083e42c..eb88e0c50 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2795,12 +2795,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) if (diff2 & MD2_ITNEXT) mobj->itnext = (mobj_t *)(size_t)READUINT32(save_p); if (diff2 & MD2_SLOPE) - { mobj->standingslope = P_SlopeById(READUINT16(save_p)); -#ifdef HWRENDER - mobj->modeltilt = mobj->standingslope; -#endif - } if (diff2 & MD2_COLORIZED) mobj->colorized = READUINT8(save_p); if (diff2 & MD2_MIRRORED) diff --git a/src/p_slopes.c b/src/p_slopes.c index d903afb71..f3e1e2930 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -897,9 +897,8 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope { thing->standingslope = slope; -#ifdef HWRENDER - thing->modeltilt = thing->standingslope; -#endif + P_SetPitchRollFromSlope(thing, slope); + if (!thing->player || !(thing->player->pflags & PF_BOUNCING)) thing->momz = -P_MobjFlip(thing); } @@ -916,9 +915,7 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) thing->momx = mom.x; thing->momy = mom.y; thing->standingslope = slope; -#ifdef HWRENDER - thing->modeltilt = thing->standingslope; -#endif + P_SetPitchRollFromSlope(thing, slope); if (!thing->player || !(thing->player->pflags & PF_BOUNCING)) thing->momz = -P_MobjFlip(thing); } diff --git a/src/p_user.c b/src/p_user.c index cdaa24123..5a8e5612c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1290,6 +1290,8 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->colorized = mobj->colorized; // Kart: they should also be colorized if their origin is ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle); + ghost->roll = mobj->roll; + ghost->pitch = mobj->pitch; ghost->sprite = mobj->sprite; ghost->sprite2 = mobj->sprite2; ghost->frame = mobj->frame; @@ -1298,13 +1300,11 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->fuse = ghost->info->damage; ghost->skin = mobj->skin; ghost->standingslope = mobj->standingslope; -#ifdef HWRENDER - ghost->modeltilt = mobj->modeltilt; -#endif ghost->sprxoff = mobj->sprxoff; ghost->spryoff = mobj->spryoff; ghost->sprzoff = mobj->sprzoff; + ghost->rollangle = mobj->rollangle; if (mobj->flags2 & MF2_OBJECTFLIP) ghost->flags |= MF2_OBJECTFLIP; From 64c321fbedc5013dd8bc6a8451d9b3b640297fef Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 28 Oct 2020 21:05:58 -0400 Subject: [PATCH 37/99] Fix incorrect tilts --- src/hardware/hw_md2.c | 14 ++------------ src/hardware/r_opengl/r_opengl.c | 4 ++-- src/p_mobj.c | 4 ++-- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index cbf84e212..e8f28d8f5 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1605,18 +1605,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) p.rollflip *= -1; } - p.anglez = 0.0f; - p.anglex = 0.0f; - - if (spr->mobj->pitch) - { - p.anglez = FIXED_TO_FLOAT(-AngleFixed(spr->mobj->pitch)); - } - - if (spr->mobj->roll) - { - p.anglex = FIXED_TO_FLOAT(AngleFixed(spr->mobj->roll)); - } + p.anglez = FIXED_TO_FLOAT(AngleFixed(spr->mobj->pitch)); + p.anglex = FIXED_TO_FLOAT(AngleFixed(spr->mobj->roll)); // SRB2CBTODO: MD2 scaling support finalscale *= FIXED_TO_FLOAT(spr->mobj->scale); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index fe07fc808..3e97bc807 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2643,9 +2643,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (hflipped) scalez = -scalez; - pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart - pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); + pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f); + pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); if (pos->roll) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 59f8af921..910f9ee20 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1227,8 +1227,8 @@ void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope) fixed_t tempy = slope->normal.y; fixed_t tempx = slope->normal.x; - mo->pitch = -R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx); - mo->roll = -R_PointToAngle2(0, 0, tempz, tempy); + mo->pitch = R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx); + mo->roll = R_PointToAngle2(0, 0, tempz, tempy); } else { From 918b4a203989e57b282f9dd61b644ea04acb6c48 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 28 Oct 2020 23:30:34 -0700 Subject: [PATCH 38/99] Revert "this is stupid" This reverts commit 32008425190b20a3afa601789d9e3375deb9317d. --- 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 f652778a0..bee2e88d9 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5745,7 +5745,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } else if (player->karmadelay > 0 && !P_PlayerInPain(player)) { - if ((battleovertime.enabled > 0) && (player->bumpers <= 0)) + if (battleovertime.enabled > 0) { player->eliminated = true; } From 4d8447dc1c2bb8735d4cb0da9857cdf4069b1d72 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 28 Oct 2020 23:30:37 -0700 Subject: [PATCH 39/99] Revert "Eliminate karma players at overtime" This reverts commit 714f04c93095dd8fbc7f9ea32ae081fd4bd820f5. --- src/k_kart.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index bee2e88d9..bbdc62e82 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2451,11 +2451,6 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a karmahitbox->destscale = player->mo->scale; P_SetScale(karmahitbox, player->mo->scale); CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); - - if (battleovertime.enabled > 0) - { - player->eliminated = true; - } } player->bumpers -= amount; @@ -5745,11 +5740,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } else if (player->karmadelay > 0 && !P_PlayerInPain(player)) { - if (battleovertime.enabled > 0) - { - player->eliminated = true; - } - player->karmadelay--; if (P_IsDisplayPlayer(player) && player->bumpers <= 0 && player->karmadelay <= 0) comebackshowninfo = true; // client has already seen the message From cb941050e228f8014ca6e7936f2b2c4c45505220 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 28 Oct 2020 23:48:16 -0700 Subject: [PATCH 40/99] Paper item hitbox extends just as far below --- src/k_collide.c | 29 +++++++++++++++++++++++++++++ src/k_collide.h | 1 + src/p_inter.c | 21 --------------------- src/p_map.c | 21 +++++++++++++++++++++ 4 files changed, 51 insertions(+), 21 deletions(-) diff --git a/src/k_collide.c b/src/k_collide.c index 963ec4e64..48b20c8a1 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -404,3 +404,32 @@ boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2) K_KartBouncing(t2, t1, false, true); return false; } + +boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) +{ + player_t * player = t2->player; + + if (! player) + return true; + + if (!P_CanPickupItem(player, 3) || (player->kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != t1->threshold)) + return true; + + if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) + return true; + + player->kartstuff[k_itemtype] = t2->threshold; + player->kartstuff[k_itemamount] += t2->movecount; + if (player->kartstuff[k_itemamount] > 255) + player->kartstuff[k_itemamount] = 255; + + S_StartSound(t1, t1->info->deathsound); + + P_SetTarget(&t1->tracer, t2); + t1->flags2 |= MF2_NIGHTSPULL; + t1->destscale = mapobjectscale>>4; + t1->scalespeed <<= 1; + + t1->flags &= ~MF_SPECIAL; + return false; +} diff --git a/src/k_collide.h b/src/k_collide.h index 86f643b3f..fed8969d6 100644 --- a/src/k_collide.h +++ b/src/k_collide.h @@ -12,5 +12,6 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2); boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2); boolean K_FallingRockCollide(mobj_t *t1, mobj_t *t2); boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2); +boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2); #endif diff --git a/src/p_inter.c b/src/p_inter.c index e190e1274..08bd29fdf 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -231,27 +231,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetObjectMomZ(player->mo, 12<mo, player->mo->angle, 20<kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != special->threshold)) - return; - - if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) - return; - - player->kartstuff[k_itemtype] = special->threshold; - player->kartstuff[k_itemamount] += special->movecount; - if (player->kartstuff[k_itemamount] > 255) - player->kartstuff[k_itemamount] = 255; - - S_StartSound(special, special->info->deathsound); - - P_SetTarget(&special->tracer, toucher); - special->flags2 |= MF2_NIGHTSPULL; - special->destscale = mapobjectscale>>4; - special->scalespeed <<= 1; - - special->flags &= ~MF_SPECIAL; - return; case MT_RANDOMITEM: // SRB2kart if (!P_CanPickupItem(player, 1)) return; diff --git a/src/p_map.c b/src/p_map.c index 7a0958f7f..bea4849dd 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -970,6 +970,27 @@ static boolean PIT_CheckThing(mobj_t *thing) return K_FallingRockCollide(thing, tmthing); } + if (tmthing->type == MT_FLOATINGITEM) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z - thing->height) // extended hitbox + return true; // underneath + + return K_FloatingItemCollide(tmthing, thing); + } + else if (thing->type == MT_FLOATINGITEM) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z - thing->height) // extended hitbox + return true; // underneath + + return K_FloatingItemCollide(thing, tmthing); + } + //} if ((thing->type == MT_SPRINGSHELL || thing->type == MT_YELLOWSHELL) && thing->health > 0 From 875493d77842a7b62fbf1fb78d494da6cbfff57c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 30 Oct 2020 02:15:49 -0400 Subject: [PATCH 41/99] Remove the need for setting rotation axis in spriteinfo for models Now it just does it like Software --- src/dehacked.c | 7 ------- src/hardware/hw_defs.h | 8 +------- src/hardware/hw_main.c | 6 ++++++ src/hardware/hw_md2.c | 33 +++++++++----------------------- src/hardware/r_opengl/r_opengl.c | 26 ++----------------------- src/lua_infolib.c | 6 ------ 6 files changed, 18 insertions(+), 68 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index a467543e9..fa361169b 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1271,8 +1271,6 @@ static void readspriteframe(MYFILE *f, spriteinfo_t *sprinfo, UINT8 frame) sprinfo->pivot[frame].x = value; else if (fastcmp(word, "YPIVOT")) sprinfo->pivot[frame].y = value; - else if (fastcmp(word, "ROTAXIS")) - sprinfo->pivot[frame].rotaxis = value; else { f->curpos = lastline; @@ -11480,11 +11478,6 @@ struct { {"DI_SOUTHEAST",DI_SOUTHEAST}, {"NUMDIRS",NUMDIRS}, - // Sprite rotation axis (rotaxis_t) - {"ROTAXIS_X",ROTAXIS_X}, - {"ROTAXIS_Y",ROTAXIS_Y}, - {"ROTAXIS_Z",ROTAXIS_Z}, - // Buttons (ticcmd_t) // SRB2kart {"BT_ACCELERATE",BT_ACCELERATE}, {"BT_DRIFT",BT_DRIFT}, diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 67a996466..9cb48620e 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -101,9 +101,6 @@ typedef struct //Hurdler: Transform (coords + angles) //BP: transform order : scale(rotation_x(rotation_y(translation(v)))) -// Kart features -#define USE_FTRANSFORM_MIRROR - // Vanilla features #define USE_MODEL_NEXTFRAME @@ -118,13 +115,10 @@ typedef struct boolean shearing; // 14042019 angle_t viewaiming; // 17052019 boolean roll; - SINT8 rollflip; FLOAT rollangle; // done to not override USE_FTRANSFORM_ANGLEZ - UINT8 rotaxis; FLOAT centerx, centery; -#ifdef USE_FTRANSFORM_MIRROR + FLOAT rollx, rollz; boolean mirror; // SRB2Kart: Encore Mode -#endif } FTransform; // Transformed vector, as passed to HWR API diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index bc7a673b7..b00ea6440 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5508,6 +5508,8 @@ static void HWR_DrawSkyBackground(player_t *player) fixed_t rol = AngleFixed(player->viewrollangle); dometransform.rollangle = FIXED_TO_FLOAT(rol); dometransform.roll = true; + dometransform.rollx = 1.0f; + dometransform.rollz = 0.0f; } dometransform.splitscreen = r_splitscreen; @@ -5786,6 +5788,8 @@ void HWR_RenderSkyboxView(player_t *player) fixed_t rol = AngleFixed(player->viewrollangle); atransform.rollangle = FIXED_TO_FLOAT(rol); atransform.roll = true; + atransform.rollx = 1.0f; + atransform.rollz = 0.0f; } atransform.splitscreen = r_splitscreen; @@ -5987,6 +5991,8 @@ void HWR_RenderPlayerView(void) fixed_t rol = AngleFixed(player->viewrollangle); atransform.rollangle = FIXED_TO_FLOAT(rol); atransform.roll = true; + atransform.rollx = 1.0f; + atransform.rollz = 0.0f; } atransform.splitscreen = r_splitscreen; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index e8f28d8f5..2ac4e8a9f 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1353,8 +1353,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !(spr->mobj->frame & FF_HORIZONTALFLIP)); spritedef_t *sprdef; spriteframe_t *sprframe; - spriteinfo_t *sprinfo; - angle_t ang; INT32 mod; float finalscale; @@ -1378,12 +1376,10 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) { md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins]; md2->skin = (skin_t*)spr->mobj->skin-skins; - sprinfo = &((skin_t *)spr->mobj->skin)->sprinfo[spr->mobj->sprite2]; } else { md2 = &md2_models[spr->mobj->sprite]; - sprinfo = &spriteinfo[spr->mobj->sprite]; } // texture loading before model init, so it knows if sprite graphics are used, which @@ -1578,31 +1574,22 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) } p.rollangle = 0.0f; - p.rollflip = 1; - p.rotaxis = 0; + if (spr->mobj->rollangle) { + fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know fixed_t anglef = AngleFixed(spr->mobj->rollangle); + p.rollangle = FIXED_TO_FLOAT(anglef); p.roll = true; // rotation pivot - p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2); - p.centery = FIXED_TO_FLOAT(spr->mobj->height/(flip ? -2 : 2)); + p.centerx = FIXED_TO_FLOAT(spr->mobj->radius / 2); + p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2); - // rotation axis - if (sprinfo->available) - p.rotaxis = (UINT8)(sprinfo->pivot[(spr->mobj->frame & FF_FRAMEMASK)].rotaxis); - - // for NiGHTS specifically but should work everywhere else - ang = R_PointToAngle (spr->mobj->x, spr->mobj->y) - (spr->mobj->player ? spr->mobj->player->drawangle : spr->mobj->angle); - if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right - p.rollflip = 1; - else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left - p.rollflip = -1; - - if (flip) - p.rollflip *= -1; + // rotation axes relative to camera + p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); + p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); } p.anglez = FIXED_TO_FLOAT(AngleFixed(spr->mobj->pitch)); @@ -1612,9 +1599,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) finalscale *= FIXED_TO_FLOAT(spr->mobj->scale); p.flip = atransform.flip; -#ifdef USE_FTRANSFORM_MIRROR - p.mirror = atransform.mirror; // from Kart -#endif + p.mirror = atransform.mirror; HWD.pfnSetShader(SHADER_MODEL); // model shader HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 3e97bc807..783466ff8 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2610,7 +2610,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglEnable(GL_CULL_FACE); pglEnable(GL_NORMALIZE); -#ifdef USE_FTRANSFORM_MIRROR // flipped is if the object is vertically flipped // hflipped is if the object is horizontally flipped // pos->flip is if the screen is flipped vertically @@ -2623,17 +2622,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 else pglCullFace(GL_BACK); } -#else - // pos->flip is if the screen is flipped too - if (flipped ^ hflipped ^ pos->flip) // If one or three of these are active, but not two, invert the model's culling - { - pglCullFace(GL_FRONT); - } - else - { - pglCullFace(GL_BACK); - } -#endif pglPushMatrix(); // should be the same as glLoadIdentity //Hurdler: now it seems to work @@ -2649,14 +2637,8 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (pos->roll) { - float roll = (1.0f * pos->rollflip); pglTranslatef(pos->centerx, pos->centery, 0); - if (pos->rotaxis == 2) // Z - pglRotatef(pos->rollangle, 0.0f, 0.0f, roll); - else if (pos->rotaxis == 1) // Y - pglRotatef(pos->rollangle, 0.0f, roll, 0.0f); - else // X - pglRotatef(pos->rollangle, roll, 0.0f, 0.0f); + pglRotatef(pos->rollangle, pos->rollx, 0.0f, pos->rollz); pglTranslatef(-pos->centerx, -pos->centery, 0); } @@ -2829,13 +2811,9 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) if (stransform) { used_fov = stransform->fovxangle; -#ifdef USE_FTRANSFORM_MIRROR - // mirroring from Kart if (stransform->mirror) pglScalef(-stransform->scalex, stransform->scaley, -stransform->scalez); - else -#endif - if (stransform->flip) + else if (stransform->flip) pglScalef(stransform->scalex, -stransform->scaley, -stransform->scalez); else pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez); diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 5e5a1dbc4..7e2445b0c 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -313,8 +313,6 @@ static int PopPivotSubTable(spriteframepivot_t *pivot, lua_State *L, int stk, in pivot[idx].x = (INT32)value; else if (ikey == 2 || (key && fastcmp(key, "y"))) pivot[idx].y = (INT32)value; - else if (ikey == 3 || (key && fastcmp(key, "rotaxis"))) - pivot[idx].rotaxis = (UINT8)value; else if (ikey == -1 && (key != NULL)) FIELDERROR("pivot key", va("invalid option %s", key)); okcool = 1; @@ -579,8 +577,6 @@ static int framepivot_get(lua_State *L) lua_pushinteger(L, framepivot->x); else if (fastcmp("y", field)) lua_pushinteger(L, framepivot->y); - else if (fastcmp("rotaxis", field)) - lua_pushinteger(L, (UINT8)framepivot->rotaxis); else return luaL_error(L, va("Field %s does not exist in spriteframepivot_t", field)); @@ -605,8 +601,6 @@ static int framepivot_set(lua_State *L) framepivot->x = luaL_checkinteger(L, 3); else if (fastcmp("y", field)) framepivot->y = luaL_checkinteger(L, 3); - else if (fastcmp("rotaxis", field)) - framepivot->rotaxis = luaL_checkinteger(L, 3); else return luaL_error(L, va("Field %s does not exist in spriteframepivot_t", field)); From fed0ed98deb9554df47bef15ae703b71ce449b0d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 30 Oct 2020 15:54:58 -0400 Subject: [PATCH 42/99] Add R_SpriteRotationAngle function Gets the rotation angle for the mobj's sprite. Meant for pitch & roll later, but that part is if'd out currently and just returns mobj->rollangle --- src/hardware/hw_main.c | 7 +++++-- src/r_picformats.c | 22 ++++++++++++++++++++++ src/r_picformats.h | 1 + src/r_things.c | 7 +++++-- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b00ea6440..0be2e2c86 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4902,6 +4902,7 @@ static void HWR_ProjectSprite(mobj_t *thing) #ifdef ROTSPRITE patch_t *rotsprite = NULL; INT32 rollangle = 0; + angle_t spriterotangle = 0; #endif if (!thing) @@ -5025,9 +5026,11 @@ static void HWR_ProjectSprite(mobj_t *thing) spr_topoffset = spritecachedinfo[lumpoff].topoffset; #ifdef ROTSPRITE - if (thing->rollangle) + spriterotangle = R_SpriteRotationAngle(thing); + + if (spriterotangle != 0) { - rollangle = R_GetRollAngle(thing->rollangle); + rollangle = R_GetRollAngle(spriterotangle); if (!(sprframe->rotsprite.cached & (1<sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip); rotsprite = sprframe->rotsprite.patch[rot][rollangle]; diff --git a/src/r_picformats.c b/src/r_picformats.c index 95fe23aeb..19079d3b7 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -23,6 +23,7 @@ #include "v_video.h" #include "z_zone.h" #include "w_wad.h" +#include "r_main.h" // R_PointToAngle #ifdef HWRENDER #include "hardware/hw_glob.h" @@ -1605,6 +1606,27 @@ void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps) } #ifdef ROTSPRITE +// +// R_SpriteRotationAngle +// +// Gets the rollangle for the input object. +// +angle_t R_SpriteRotationAngle(mobj_t *mobj) +{ +#if 0 + angle_t viewingAngle = R_PointToAngle(mobj->x, mobj->y); + + fixed_t pitchMul = -FINESINE(viewingAngle >> ANGLETOFINESHIFT); + fixed_t rollMul = FINECOSINE(viewingAngle >> ANGLETOFINESHIFT); + + angle_t rollOrPitch = FixedMul(mobj->pitch, pitchMul) + FixedMul(mobj->roll, rollMul); + + return (rollOrPitch + mobj->rollangle); +#else + return mobj->rollangle; +#endif +} + // // R_GetRollAngle // diff --git a/src/r_picformats.h b/src/r_picformats.h index 3ee76a92f..d677e783b 100644 --- a/src/r_picformats.h +++ b/src/r_picformats.h @@ -122,6 +122,7 @@ void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum); // Sprite rotation #ifdef ROTSPRITE +angle_t R_SpriteRotationAngle(mobj_t *mobj); INT32 R_GetRollAngle(angle_t rollangle); void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip); void R_FreeSingleRotSprite(spritedef_t *spritedef); diff --git a/src/r_things.c b/src/r_things.c index fd200cf87..3110d86bc 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1446,6 +1446,7 @@ static void R_ProjectSprite(mobj_t *thing) #ifdef ROTSPRITE patch_t *rotsprite = NULL; INT32 rollangle = 0; + angle_t spriterotangle = 0; #endif // transform the origin point @@ -1571,9 +1572,11 @@ static void R_ProjectSprite(mobj_t *thing) spr_topoffset = spritecachedinfo[lump].topoffset; #ifdef ROTSPRITE - if (thing->rollangle) + spriterotangle = R_SpriteRotationAngle(thing); + + if (spriterotangle != 0) { - rollangle = R_GetRollAngle(thing->rollangle); + rollangle = R_GetRollAngle(spriterotangle); if (!(sprframe->rotsprite.cached & (1<sprite, frame, sprinfo, sprframe, rot, flip); rotsprite = sprframe->rotsprite.patch[rot][rollangle]; From 6864705b674cdbd77b28f5ab03fdf0b26cc1dbd4 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 30 Oct 2020 19:00:37 -0700 Subject: [PATCH 43/99] Fix fuckup --- src/info.c | 2 +- src/k_collide.c | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/info.c b/src/info.c index d8b814841..4782fb0b5 100644 --- a/src/info.c +++ b/src/info.c @@ -22946,7 +22946,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_DONTENCOREMAP, // flags + MF_SLIDEME|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, diff --git a/src/k_collide.c b/src/k_collide.c index 48b20c8a1..79abdfa94 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -409,6 +409,9 @@ boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) { player_t * player = t2->player; + if (t1->health < 1) + return true; + if (! player) return true; @@ -418,8 +421,8 @@ boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) return true; - player->kartstuff[k_itemtype] = t2->threshold; - player->kartstuff[k_itemamount] += t2->movecount; + player->kartstuff[k_itemtype] = t1->threshold; + player->kartstuff[k_itemamount] += t1->movecount; if (player->kartstuff[k_itemamount] > 255) player->kartstuff[k_itemamount] = 255; @@ -430,6 +433,7 @@ boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) t1->destscale = mapobjectscale>>4; t1->scalespeed <<= 1; - t1->flags &= ~MF_SPECIAL; + t1->health--; + return false; } From 619402666a92bcb4d5e6496c4a91df67466fa8b5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 30 Oct 2020 22:57:42 -0400 Subject: [PATCH 44/99] Better Jawz - More friction in Battle - Throwables take your momz (has been bothering me for an eternity) --- src/k_kart.c | 2 ++ src/p_enemy.c | 2 +- src/p_mobj.c | 7 +++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index bbdc62e82..67859e077 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2889,8 +2889,10 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I } th->angle = an; + th->momx = FixedMul(finalspeed, FINECOSINE(an>>ANGLETOFINESHIFT)); th->momy = FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT)); + th->momz = source->momz; switch (type) { diff --git a/src/p_enemy.c b/src/p_enemy.c index 630e3b29e..790144caa 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8676,7 +8676,7 @@ void A_JawzChase(mobj_t *actor) angle_t angledelta = actor->angle - targetangle; boolean turnclockwise = true; - if ((gametyperules & GTR_CIRCUIT)) + if (gametyperules & GTR_CIRCUIT) { const fixed_t distbarrier = FixedMul(512*mapobjectscale, FRACUNIT + ((gamespeed-1) * (FRACUNIT/4))); const fixed_t distaway = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); diff --git a/src/p_mobj.c b/src/p_mobj.c index e13e9f428..1b53f8072 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1166,10 +1166,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_SINK: if (mo->extravalue2 > 0) gravityadd *= mo->extravalue2; - /* FALLTHRU */ - case MT_ORBINAUT: - case MT_JAWZ: - case MT_JAWZ_DUD: gravityadd = (5*gravityadd)/2; break; case MT_KARMAFIREWORK: @@ -6184,6 +6180,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) K_DoPogoSpring(mobj, 0, 1); + if (!(gametyperules & GTR_CIRCUIT)) + mobj->friction = max(0, 3 * mobj->friction / 4); + break; } case MT_JAWZ_DUD: From 84f027d24425495ec3c56c20b0c9b704d4ba6294 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 30 Oct 2020 23:09:29 -0400 Subject: [PATCH 45/99] Item table changes - Mine: 4 -> 6 - Thunder Shield: 0 -> 4 - Bubble Shield: 0 -> 1 - Sneaker x3: 0 -> 1 - Banana x10: 0 -> 1 2 of the 3 shields added, included some items that normally only appeared for Karma items, and makes Mines much more common --- src/k_kart.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 67859e077..06c963db1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -316,22 +316,22 @@ static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][2] = /*Eggman Monitor*/ { 1, 0 }, // Eggman Monitor /*Orbinaut*/ { 8, 0 }, // Orbinaut /*Jawz*/ { 8, 1 }, // Jawz - /*Mine*/ { 4, 1 }, // Mine + /*Mine*/ { 6, 1 }, // Mine /*Ballhog*/ { 2, 1 }, // Ballhog /*Self-Propelled Bomb*/ { 0, 0 }, // Self-Propelled Bomb /*Grow*/ { 2, 1 }, // Grow /*Shrink*/ { 0, 0 }, // Shrink - /*Thunder Shield*/ { 0, 0 }, // Thunder Shield - /*Bubble Shield*/ { 0, 0 }, // Bubble Shield + /*Thunder Shield*/ { 4, 0 }, // Thunder Shield + /*Bubble Shield*/ { 1, 0 }, // Bubble Shield /*Flame Shield*/ { 0, 0 }, // Flame Shield /*Hyudoro*/ { 2, 0 }, // Hyudoro /*Pogo Spring*/ { 2, 0 }, // Pogo Spring /*Super Ring*/ { 0, 0 }, // Super Ring /*Kitchen Sink*/ { 0, 0 }, // Kitchen Sink /*Sneaker x2*/ { 0, 0 }, // Sneaker x2 - /*Sneaker x3*/ { 0, 1 }, // Sneaker x3 + /*Sneaker x3*/ { 1, 1 }, // Sneaker x3 /*Banana x3*/ { 1, 0 }, // Banana x3 - /*Banana x10*/ { 0, 1 }, // Banana x10 + /*Banana x10*/ { 1, 1 }, // Banana x10 /*Orbinaut x3*/ { 2, 0 }, // Orbinaut x3 /*Orbinaut x4*/ { 1, 1 }, // Orbinaut x4 /*Jawz x2*/ { 2, 1 } // Jawz x2 From 4bdd3c809fb99b682986e9114033959752e31923 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 30 Oct 2020 20:54:21 -0700 Subject: [PATCH 46/99] Major brother moment --- src/p_map.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index bea4849dd..0b8c7f577 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -973,9 +973,9 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->type == MT_FLOATINGITEM) { // see if it went over / under - if (tmthing->z > thing->z + thing->height) + if (tmthing->z - tmthing->height > thing->z + thing->height) return true; // overhead - if (tmthing->z + tmthing->height < thing->z - thing->height) // extended hitbox + if (tmthing->z + tmthing->height < thing->z) // extended hitbox return true; // underneath return K_FloatingItemCollide(tmthing, thing); From 46b1b6db1c28bb084e93765bf993c41172c9ac7d Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 30 Oct 2020 21:09:36 -0700 Subject: [PATCH 47/99] Double paper item height --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 4782fb0b5..1b62c7501 100644 --- a/src/info.c +++ b/src/info.c @@ -22941,7 +22941,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_itpick, // deathsound 0, // speed 48*FRACUNIT, // radius - 32*FRACUNIT, // height + 64*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage From 76e0102b3f7b531952e5255046ca9bc386ccb936 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 30 Oct 2020 21:13:36 -0700 Subject: [PATCH 48/99] Fix paper items not being removed after shrunk --- src/k_collide.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/k_collide.c b/src/k_collide.c index 79abdfa94..282fa0072 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -409,7 +409,7 @@ boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) { player_t * player = t2->player; - if (t1->health < 1) + if (t1->flags2 & MF2_NIGHTSPULL) return true; if (! player) @@ -433,7 +433,5 @@ boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) t1->destscale = mapobjectscale>>4; t1->scalespeed <<= 1; - t1->health--; - return false; } From 91ed67bece1e8dfd7123bf28d775a1bf42111f71 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 1 Nov 2020 23:44:54 -0500 Subject: [PATCH 49/99] Start on Chaos Emeralds Functional! However, you don't drop them yet. --- src/dehacked.c | 47 ++++----- src/doomstat.h | 35 +++++-- src/f_finale.c | 4 +- src/info.c | 241 ++++++---------------------------------------- src/info.h | 31 +++--- src/k_battle.c | 123 ++++++++++++++++++++--- src/k_battle.h | 1 + src/lua_mathlib.c | 4 +- src/m_cheat.c | 8 +- src/m_menu.c | 2 +- src/p_inter.c | 37 ++++++- src/p_mobj.c | 9 +- src/p_mobj.h | 1 - src/p_spec.c | 2 +- 14 files changed, 260 insertions(+), 285 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 73fb81f6c..cbff0adce 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6269,13 +6269,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EMBLEM26", // Chaos Emeralds - "S_CEMG1", - "S_CEMG2", - "S_CEMG3", - "S_CEMG4", - "S_CEMG5", - "S_CEMG6", - "S_CEMG7", + "S_EMERALD_CHAOS1", + "S_EMERALD_CHAOS2", + "S_EMERALD_CHAOS3", + "S_EMERALD_CHAOS4", + "S_EMERALD_CHAOS5", + "S_EMERALD_CHAOS6", + "S_EMERALD_CHAOS7", // Emerald hunt shards "S_SHRD1", @@ -9499,16 +9499,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_REDFLAG", // Red CTF Flag "MT_BLUEFLAG", // Blue CTF Flag "MT_EMBLEM", - "MT_EMERALD1", - "MT_EMERALD2", - "MT_EMERALD3", - "MT_EMERALD4", - "MT_EMERALD5", - "MT_EMERALD6", - "MT_EMERALD7", + "MT_EMERALD", "MT_EMERHUNT", // Emerald Hunt "MT_EMERALDSPAWN", // Emerald spawner w/ delay - "MT_FLINGEMERALD", // Lost emerald // Springs and others "MT_FAN", @@ -11204,13 +11197,23 @@ struct { {"LF2_VISITNEEDED",LF2_VISITNEEDED}, // Emeralds - {"EMERALD1",EMERALD1}, - {"EMERALD2",EMERALD2}, - {"EMERALD3",EMERALD3}, - {"EMERALD4",EMERALD4}, - {"EMERALD5",EMERALD5}, - {"EMERALD6",EMERALD6}, - {"EMERALD7",EMERALD7}, + {"EMERALD_CHAOS1",EMERALD_CHAOS1}, + {"EMERALD_CHAOS2",EMERALD_CHAOS2}, + {"EMERALD_CHAOS3",EMERALD_CHAOS3}, + {"EMERALD_CHAOS4",EMERALD_CHAOS4}, + {"EMERALD_CHAOS5",EMERALD_CHAOS5}, + {"EMERALD_CHAOS6",EMERALD_CHAOS6}, + {"EMERALD_CHAOS7",EMERALD_CHAOS7}, + {"EMERALD_ALLCHAOS",EMERALD_ALLCHAOS}, + {"EMERALD_SUPER1",EMERALD_SUPER1}, + {"EMERALD_SUPER2",EMERALD_SUPER2}, + {"EMERALD_SUPER3",EMERALD_SUPER3}, + {"EMERALD_SUPER4",EMERALD_SUPER4}, + {"EMERALD_SUPER5",EMERALD_SUPER5}, + {"EMERALD_SUPER6",EMERALD_SUPER6}, + {"EMERALD_SUPER7",EMERALD_SUPER7}, + {"EMERALD_ALLSUPER",EMERALD_ALLSUPER}, + {"EMERALD_ALL",EMERALD_ALL}, // SKINCOLOR_ doesn't include these..! {"MAXSKINCOLORS",MAXSKINCOLORS}, diff --git a/src/doomstat.h b/src/doomstat.h index 57738aaa2..2df6caeb5 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -522,15 +522,34 @@ extern UINT32 matchesplayed; extern UINT8 stagefailed; // Emeralds stored as bits to throw savegame hackers off. +typedef enum +{ + EMERALD_CHAOS1 = 1, + EMERALD_CHAOS2 = 1<<1, + EMERALD_CHAOS3 = 1<<2, + EMERALD_CHAOS4 = 1<<3, + EMERALD_CHAOS5 = 1<<4, + EMERALD_CHAOS6 = 1<<5, + EMERALD_CHAOS7 = 1<<6, + EMERALD_ALLCHAOS = EMERALD_CHAOS1|EMERALD_CHAOS2|EMERALD_CHAOS3|EMERALD_CHAOS4|EMERALD_CHAOS5|EMERALD_CHAOS6|EMERALD_CHAOS7, + + EMERALD_SUPER1 = 1<<7, + EMERALD_SUPER2 = 1<<8, + EMERALD_SUPER3 = 1<<9, + EMERALD_SUPER4 = 1<<10, + EMERALD_SUPER5 = 1<<11, + EMERALD_SUPER6 = 1<<12, + EMERALD_SUPER7 = 1<<13, + EMERALD_ALLSUPER = EMERALD_SUPER1|EMERALD_SUPER2|EMERALD_SUPER3|EMERALD_SUPER4|EMERALD_SUPER5|EMERALD_SUPER6|EMERALD_SUPER7, + + EMERALD_ALL = EMERALD_ALLCHAOS|EMERALD_ALLSUPER +} emeraldflags_t; + extern UINT16 emeralds; -#define EMERALD1 1 -#define EMERALD2 2 -#define EMERALD3 4 -#define EMERALD4 8 -#define EMERALD5 16 -#define EMERALD6 32 -#define EMERALD7 64 -#define ALL7EMERALDS(v) ((v & (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) == (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) + +#define ALLCHAOSEMERALDS(v) ((v & EMERALD_ALLCHAOS) == EMERALD_ALLCHAOS) +#define ALLSUPEREMERALDS(v) ((v & EMERALD_ALLSUPER) == EMERALD_ALLSUPER) +#define ALLEMERALDS(v) ((v & EMERALD_ALL) == EMERALD_ALL) #define NUM_LUABANKS 16 // please only make this number go up between versions, never down. you'll break saves otherwise. also, must fit in UINT8 extern INT32 luabanks[NUM_LUABANKS]; diff --git a/src/f_finale.c b/src/f_finale.c index 4355cf231..0d290330c 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -889,7 +889,7 @@ void F_StartGameEvaluation(void) // Just in case they're open ... somehow M_ClearMenus(true); - goodending = (ALL7EMERALDS(emeralds)); + goodending = (ALLCHAOSEMERALDS(emeralds)); gameaction = ga_nothing; paused = false; @@ -1154,7 +1154,7 @@ static void F_CacheEnding(void) endescp[4] = W_CachePatchName("ENDESCP4", PU_PATCH); // so we only need to check once - if ((goodending = ALL7EMERALDS(emeralds))) + if ((goodending = ALLCHAOSEMERALDS(emeralds))) { endfwrk[0] = W_CachePatchName("ENDFWRK3", PU_PATCH); endfwrk[1] = W_CachePatchName("ENDFWRK4", PU_PATCH); diff --git a/src/info.c b/src/info.c index 1b62c7501..6cf3335b2 100644 --- a/src/info.c +++ b/src/info.c @@ -139,7 +139,13 @@ char sprnames[NUMSPRITES + 1][5] = "NCHP", // NiGHTS chip "NSTR", // NiGHTS star "EMBM", // Emblem - "CEMG", // Chaos Emeralds + "EMC1", // Chaos Emeralds + "EMC2", + "EMC3", + "EMC4", + "EMC5", + "EMC6", + "EMC7", "SHRD", // Emerald Hunt // Interactive Objects @@ -1896,13 +1902,13 @@ state_t states[NUMSTATES] = {SPR_EMBM, 25, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM26 // Chaos Emeralds - {SPR_CEMG, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG1 - {SPR_CEMG, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG2 - {SPR_CEMG, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG3 - {SPR_CEMG, FF_FULLBRIGHT|3, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG4 - {SPR_CEMG, FF_FULLBRIGHT|4, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG5 - {SPR_CEMG, FF_FULLBRIGHT|5, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG6 - {SPR_CEMG, FF_FULLBRIGHT|6, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG7 + {SPR_EMC1, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS1 + {SPR_EMC2, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS2 + {SPR_EMC3, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS3 + {SPR_EMC4, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS4 + {SPR_EMC5, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS5 + {SPR_EMC6, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS6 + {SPR_EMC7, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS7 // Emerald hunt shards {SPR_SHRD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD1 @@ -3746,14 +3752,14 @@ state_t states[NUMSTATES] = {SPR_CAPS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGCAPSULE // Orbiting Chaos Emeralds/Ideya for NiGHTS - {SPR_CEMG, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1 - {SPR_CEMG, FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2 - {SPR_CEMG, FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3 - {SPR_CEMG, FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM4}, // S_ORBITEM4 - {SPR_CEMG, FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM5}, // S_ORBITEM5 - {SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 - {SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 - {SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 + {SPR_EMC1, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1 + {SPR_EMC2, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2 + {SPR_EMC3, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3 + {SPR_EMC4, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM4}, // S_ORBITEM4 + {SPR_EMC5, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM5}, // S_ORBITEM5 + {SPR_EMC6, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 + {SPR_EMC7, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 + {SPR_EMC1, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA1}, // S_ORBIDYA1 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA2}, // S_ORBIDYA2 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA3}, // S_ORBIDYA3 @@ -8197,9 +8203,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_EMERALD1 - 313, // doomednum - S_CEMG1, // spawnstate + { // MT_EMERALD + -1, // doomednum + S_EMERALD_CHAOS1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8210,173 +8216,17 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + sfx_s3k2b, // deathsound + 0, // speed + 72*FRACUNIT, // radius + 72*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD2 - 314, // doomednum - S_CEMG2, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD2, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD3 - 315, // doomednum - S_CEMG3, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD3, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD4 - 316, // doomednum - S_CEMG4, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD4, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD5 - 317, // doomednum - S_CEMG5, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD5, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD6 - 318, // doomednum - S_CEMG6, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD6, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD7 - 319, // doomednum - S_CEMG7, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD7, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags + MF_SPECIAL, // flags S_NULL // raisestate }, @@ -8434,33 +8284,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_FLINGEMERALD - -1, // doomednum - S_CEMG1, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - 60*FRACUNIT, // speed - 16*FRACUNIT, // radius - 48*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_FAN 540, // doomednum S_FAN, // spawnstate @@ -19105,7 +18928,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_GOTEMERALD -1, // doomednum - S_CEMG1, // spawnstate + S_EMERALD_CHAOS1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound diff --git a/src/info.h b/src/info.h index e7d21744e..bb8e067be 100644 --- a/src/info.h +++ b/src/info.h @@ -410,7 +410,13 @@ typedef enum sprite SPR_NCHP, // NiGHTS chip SPR_NSTR, // NiGHTS star SPR_EMBM, // Emblem - SPR_CEMG, // Chaos Emeralds + SPR_EMC1, // Chaos Emeralds + SPR_EMC2, + SPR_EMC3, + SPR_EMC4, + SPR_EMC5, + SPR_EMC6, + SPR_EMC7, SPR_SHRD, // Emerald Hunt // Interactive Objects @@ -2111,13 +2117,13 @@ typedef enum state S_EMBLEM26, // Chaos Emeralds - S_CEMG1, - S_CEMG2, - S_CEMG3, - S_CEMG4, - S_CEMG5, - S_CEMG6, - S_CEMG7, + S_EMERALD_CHAOS1, + S_EMERALD_CHAOS2, + S_EMERALD_CHAOS3, + S_EMERALD_CHAOS4, + S_EMERALD_CHAOS5, + S_EMERALD_CHAOS6, + S_EMERALD_CHAOS7, // Emerald hunt shards S_SHRD1, @@ -5381,16 +5387,9 @@ typedef enum mobj_type MT_REDFLAG, // Red CTF Flag MT_BLUEFLAG, // Blue CTF Flag MT_EMBLEM, - MT_EMERALD1, - MT_EMERALD2, - MT_EMERALD3, - MT_EMERALD4, - MT_EMERALD5, - MT_EMERALD6, - MT_EMERALD7, + MT_EMERALD, MT_EMERHUNT, // Emerald Hunt MT_EMERALDSPAWN, // Emerald spawner w/ delay - MT_FLINGEMERALD, // Lost emerald // Springs and others MT_FAN, diff --git a/src/k_battle.c b/src/k_battle.c index 4c13cd9cf..6d73df2eb 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -277,24 +277,85 @@ void K_CheckBumpers(void) P_DoPlayerExit(&players[i]); } +mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType) +{ + boolean validEmerald = true; + mobj_t *emerald = P_SpawnMobjFromMobj(parent, 0, 0, 0, MT_EMERALD); + + emerald->angle = angle; + + P_Thrust(emerald, + FixedAngle(P_RandomFixed() * 180) + angle, + 16*mapobjectscale); + + emerald->momz = flip * 3 * mapobjectscale; + if (emerald->eflags & MFE_UNDERWATER) + emerald->momz = (117 * emerald->momz) / 200; + + emerald->threshold = 10; + + switch (emeraldType) + { + case EMERALD_CHAOS1: + P_SetMobjState(emerald, S_EMERALD_CHAOS1); + break; + case EMERALD_CHAOS2: + P_SetMobjState(emerald, S_EMERALD_CHAOS2); + break; + case EMERALD_CHAOS3: + P_SetMobjState(emerald, S_EMERALD_CHAOS3); + break; + case EMERALD_CHAOS4: + P_SetMobjState(emerald, S_EMERALD_CHAOS4); + break; + case EMERALD_CHAOS5: + P_SetMobjState(emerald, S_EMERALD_CHAOS5); + break; + case EMERALD_CHAOS6: + P_SetMobjState(emerald, S_EMERALD_CHAOS6); + break; + case EMERALD_CHAOS7: + P_SetMobjState(emerald, S_EMERALD_CHAOS7); + break; + default: + CONS_Printf("Invalid emerald type %d\n", emeraldType); + validEmerald = false; + break; + } + + if (validEmerald == true) + { + emerald->extravalue1 = emeraldType; + } + + return emerald; +} + void K_RunPaperItemSpawners(void) { const boolean overtime = (battleovertime.enabled >= 10*TICRATE); tic_t interval = 8*TICRATE; + UINT32 emeraldsSpawned = 0; if (leveltime < starttime) { + // Round hasn't started yet! return; } if ((battleovertime.enabled > 0) && (battleovertime.radius < 256*mapobjectscale)) { + // Barrier has closed in too much return; } if (overtime == true) { + // Double frequency of items interval /= 2; + + // Even if this isn't true, we pretend it is, because it's too late to do anything about it :p + emeraldsSpawned = EMERALD_ALLCHAOS; } if (((leveltime - starttime) % interval) != 0) @@ -315,18 +376,19 @@ void K_RunPaperItemSpawners(void) else { UINT8 pcount = 0; - UINT8 i; + INT16 i; for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i] || players[i].spectator - || players[i].exiting > 0 - || players[i].eliminated) + if (!playeringame[i] || players[i].spectator) { continue; } - if ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0) + emeraldsSpawned |= players[i].powers[pw_emeralds]; + + if ((players[i].exiting > 0 || players[i].eliminated) + || ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0)) { continue; } @@ -337,10 +399,13 @@ void K_RunPaperItemSpawners(void) if (pcount > 0) { #define MAXITEM 64 - UINT16 item = 0; + UINT8 item = 0; mobj_t *spotList[MAXITEM]; boolean spotUsed[MAXITEM]; + UINT32 firstUnspawnedEmerald = 0; + INT16 starti = 0; + thinker_t *th; mobj_t *mo; @@ -348,9 +413,6 @@ void K_RunPaperItemSpawners(void) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (item >= MAXITEM) - break; - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) continue; @@ -358,9 +420,16 @@ void K_RunPaperItemSpawners(void) if (mo->type == MT_PAPERITEMSPOT) { + if (item >= MAXITEM) + continue; + spotList[item] = mo; item++; } + else if (mo->type == MT_EMERALD) + { + emeraldsSpawned |= mo->extravalue1; + } } if (item <= 0) @@ -368,7 +437,19 @@ void K_RunPaperItemSpawners(void) return; } - for (i = 0; i < min(item, pcount); i++) + for (i = 0; i < 7; i++) + { + UINT32 emeraldFlag = (1 << i); + + if (!(emeraldsSpawned & emeraldFlag)) + { + firstUnspawnedEmerald = emeraldFlag; + starti = -1; + break; + } + } + + for (i = starti; i < min(item, pcount); i++) { UINT8 r = P_RandomRange(0, item-1); UINT8 recursion = 0; @@ -387,11 +468,23 @@ void K_RunPaperItemSpawners(void) flip = P_MobjFlip(spotList[r]); - drop = K_CreatePaperItem( - spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip), - FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, - 0, 0 - ); + // When -1, we're spawning a Chaos Emerald. + if (i == -1) + { + drop = K_SpawnChaosEmerald( + spotList[r], + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + firstUnspawnedEmerald + ); + } + else + { + drop = K_CreatePaperItem( + spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip), + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + 0, 0 + ); + } K_FlipFromObject(drop, spotList[r]); spotUsed[r] = true; diff --git a/src/k_battle.h b/src/k_battle.h index 90ee20df7..346e57c48 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -20,6 +20,7 @@ boolean K_IsPlayerWanted(player_t *player); void K_CalculateBattleWanted(void); void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); void K_CheckBumpers(void); +mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType); void K_RunPaperItemSpawners(void); void K_RunBattleOvertime(void); void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj); diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index c6c07fc7e..621f421ea 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -14,7 +14,7 @@ //#include "fastcmp.h" #include "tables.h" #include "p_local.h" -#include "doomstat.h" // for ALL7EMERALDS +#include "doomstat.h" // for ALLCHAOSEMERALDS #include "lua_script.h" #include "lua_libs.h" @@ -162,7 +162,7 @@ static int lib_getsecspecial(lua_State *L) static int lib_all7emeralds(lua_State *L) { - lua_pushboolean(L, ALL7EMERALDS(luaL_checkinteger(L, 1))); + lua_pushboolean(L, ALLCHAOSEMERALDS(luaL_checkinteger(L, 1))); return 1; } diff --git a/src/m_cheat.c b/src/m_cheat.c index ff5f86968..0f39bb643 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -771,12 +771,13 @@ void Command_Savecheckpoint_f(void) } // Like M_GetAllEmeralds() but for console devmode junkies. -/*void Command_Getallemeralds_f(void) +/* +void Command_Getallemeralds_f(void) { REQUIRE_SINGLEPLAYER; REQUIRE_PANDORA; - emeralds = ((EMERALD7)*2)-1; + emeralds = EMERALD_ALL; CONS_Printf(M_GetText("You now have all 7 emeralds.\n")); } @@ -788,7 +789,8 @@ void Command_Resetemeralds_f(void) emeralds = 0; CONS_Printf(M_GetText("Emeralds reset to zero.\n")); -}*/ +} +*/ void Command_Devmode_f(void) { diff --git a/src/m_menu.c b/src/m_menu.c index 7f6f542c6..dcd46b238 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6374,7 +6374,7 @@ static void M_GetAllEmeralds(INT32 choice) { (void)choice; - emeralds = ((EMERALD7)*2)-1; + emeralds = EMERALD_ALL; M_StartMessage(M_GetText("You now have all 7 emeralds.\nUse them wisely.\nWith great power comes great ring drain.\n"),NULL,MM_NOTHING); G_SetGameModified(multiplayer, true); diff --git a/src/p_inter.c b/src/p_inter.c index 08bd29fdf..2b91278df 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -231,7 +231,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetObjectMomZ(player->mo, 12<mo, player->mo->angle, 20<mo, special, special->target, 1, DMG_NORMAL); } return; - /*case MT_EERIEFOG: + case MT_EMERALD: + if (!P_CanPickupItem(player, 0)) + return; + + if (special->threshold > 0) + return; + + player->powers[pw_emeralds] |= special->extravalue1; + + if (ALLCHAOSEMERALDS(player->powers[pw_emeralds])) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + { + continue; + } + + if (&players[i] == player) + { + continue; + } + + players[i].bumpers = 0; + } + + K_CheckBumpers(); + } + break; + /* + case MT_EERIEFOG: special->frame &= ~FF_TRANS80; special->frame |= FF_TRANS90; - return;*/ + return; + */ case MT_SMK_MOLE: if (special->target && !P_MobjWasRemoved(special->target)) return; diff --git a/src/p_mobj.c b/src/p_mobj.c index 1b53f8072..cc3bc3a9b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1130,7 +1130,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_FLINGCOIN: case MT_FLINGBLUESPHERE: case MT_FLINGNIGHTSCHIP: - case MT_FLINGEMERALD: case MT_BOUNCERING: case MT_RAILRING: case MT_INFINITYRING: @@ -2082,6 +2081,7 @@ boolean P_ZMovement(mobj_t *mo) case MT_BALLHOG: case MT_SSMINE: case MT_BUBBLESHIELDTRAP: + case MT_EMERALD: // Remove stuff from death pits. if (P_CheckDeathPitCollide(mo)) { @@ -6384,6 +6384,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj) S_StartSound(mobj, sfx_s3k4e); mobj->health--; break; + case MT_EMERALD: + if (mobj->threshold > 0) + mobj->threshold--; + break; case MT_DRIFTEXPLODE: if (!mobj->target || !mobj->target->health) { @@ -8566,7 +8570,7 @@ void P_MobjThinker(mobj_t *mobj) || mobj->type == MT_FLINGCOIN || mobj->type == MT_FLINGBLUESPHERE || mobj->type == MT_FLINGNIGHTSCHIP - || mobj->type == MT_FLINGEMERALD + || mobj->type == MT_EMERALD || mobj->type == MT_BIGTUMBLEWEED || mobj->type == MT_LITTLETUMBLEWEED || mobj->type == MT_CANNONBALLDECOR @@ -8873,6 +8877,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_SINK: case MT_ROCKETSNEAKER: case MT_SPB: + case MT_EMERALD: thing->shadowscale = 3*FRACUNIT/2; break; case MT_BANANA_SHIELD: diff --git a/src/p_mobj.h b/src/p_mobj.h index 6ffa393aa..9cafcefa7 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -530,7 +530,6 @@ boolean P_ZMovement(mobj_t *mo); void P_RingZMovement(mobj_t *mo); boolean P_SceneryZMovement(mobj_t *mo); void P_PlayerZMovement(mobj_t *mo); -void P_EmeraldManager(void); extern INT32 modulothing; diff --git a/src/p_spec.c b/src/p_spec.c index a86c54c07..f95bbd39d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1612,7 +1612,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller { if (GETSECSPECIAL(caller->special, 2) == 6) { - if (!(ALL7EMERALDS(emeralds))) + if (!(ALLCHAOSEMERALDS(emeralds))) return false; } From a011278dd40f66d862178edb790b826fd947ade4 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 1 Nov 2020 23:46:26 -0500 Subject: [PATCH 50/99] Slight tweaks to item spawn location --- src/k_battle.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index 6d73df2eb..d77ab0432 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -449,19 +449,20 @@ void K_RunPaperItemSpawners(void) } } - for (i = starti; i < min(item, pcount); i++) + for (i = starti; i < min(item + starti, pcount); i++) { - UINT8 r = P_RandomRange(0, item-1); + UINT8 r = P_RandomKey(item); UINT8 recursion = 0; mobj_t *drop = NULL; SINT8 flip = 1; while (spotUsed[r] == true) { - r = P_RandomRange(0, item-1); + r = P_RandomKey(item); - if ((recursion++) > 32) + if ((recursion++) > MAXITEM) { + // roll with it anyway I guess break; } } From 961ff69241c32b22d2fc73ea556baf4b48d2f735 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 00:41:41 -0500 Subject: [PATCH 51/99] You can drop Chaos Emeralds --- src/k_battle.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++---- src/k_battle.h | 2 ++ src/p_inter.c | 37 ++++++++++++++++------------------ src/p_mobj.c | 19 ++++++++++++++++-- 4 files changed, 86 insertions(+), 26 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index d77ab0432..42343002e 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -277,18 +277,45 @@ void K_CheckBumpers(void) P_DoPlayerExit(&players[i]); } +void K_CheckEmeralds(player_t *player) +{ + UINT8 i; + + if (!ALLCHAOSEMERALDS(player->powers[pw_emeralds])) + { + return; + } + + player->marescore++; // lol + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + { + continue; + } + + if (&players[i] == player) + { + continue; + } + + players[i].bumpers = 0; + } + + K_CheckBumpers(); +} + mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType) { boolean validEmerald = true; mobj_t *emerald = P_SpawnMobjFromMobj(parent, 0, 0, 0, MT_EMERALD); - emerald->angle = angle; - P_Thrust(emerald, FixedAngle(P_RandomFixed() * 180) + angle, - 16*mapobjectscale); + 32 * mapobjectscale); - emerald->momz = flip * 3 * mapobjectscale; + emerald->momz = flip * 24 * mapobjectscale; if (emerald->eflags & MFE_UNDERWATER) emerald->momz = (117 * emerald->momz) / 200; @@ -331,6 +358,25 @@ mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 em return emerald; } +void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType) +{ + UINT8 i; + SINT8 flip = P_MobjFlip(player->mo); + + for (i = 0; i < 14; i++) + { + UINT32 emeraldFlag = (1 << i); + + if ((player->powers[pw_emeralds] & emeraldFlag) && (emeraldFlag & emeraldType)) + { + mobj_t *emerald = K_SpawnChaosEmerald(player->mo, player->mo->angle, flip, emeraldFlag); + P_SetTarget(&emerald->target, player->mo); + + player->powers[pw_emeralds] &= ~emeraldFlag; + } + } +} + void K_RunPaperItemSpawners(void) { const boolean overtime = (battleovertime.enabled >= 10*TICRATE); diff --git a/src/k_battle.h b/src/k_battle.h index 346e57c48..c83cd7e04 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -20,7 +20,9 @@ boolean K_IsPlayerWanted(player_t *player); void K_CalculateBattleWanted(void); void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); void K_CheckBumpers(void); +void K_CheckEmeralds(player_t *player); mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType); +void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType); void K_RunPaperItemSpawners(void); void K_RunBattleOvertime(void); void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj); diff --git a/src/p_inter.c b/src/p_inter.c index 2b91278df..e8157543f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -421,26 +421,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; player->powers[pw_emeralds] |= special->extravalue1; - - if (ALLCHAOSEMERALDS(player->powers[pw_emeralds])) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - { - continue; - } - - if (&players[i] == player) - { - continue; - } - - players[i].bumpers = 0; - } - - K_CheckBumpers(); - } + K_CheckEmeralds(player); break; /* case MT_EERIEFOG: @@ -1680,6 +1661,8 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) break; } + K_DropEmeraldsFromPlayer(player, player->powers[pw_emeralds]); + player->pflags &= ~PF_SLIDING; player->powers[pw_carry] = CR_NONE; @@ -1909,9 +1892,23 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { K_PlayHitEmSound(source); K_StealBumper(source->player, player, bumpadd); + + if (damagetype & DMG_STEAL) + { + // Give them ALL of your emeralds :) + source->player->powers[pw_emeralds] |= player->powers[pw_emeralds]; + player->powers[pw_emeralds] = 0; + K_CheckEmeralds(source->player); + } } K_RemoveBumper(player, inflictor, source, bumpadd, false); + + if (!(damagetype & DMG_STEAL)) + { + // Drop all of your emeralds + K_DropEmeraldsFromPlayer(player, player->powers[pw_emeralds]); + } } player->kartstuff[k_sneakertimer] = player->kartstuff[k_numsneakers] = 0; diff --git a/src/p_mobj.c b/src/p_mobj.c index cc3bc3a9b..dd8aef239 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1163,6 +1163,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_EGGMANITEM: case MT_SSMINE: case MT_SINK: + case MT_EMERALD: if (mo->extravalue2 > 0) gravityadd *= mo->extravalue2; gravityadd = (5*gravityadd)/2; @@ -2081,7 +2082,6 @@ boolean P_ZMovement(mobj_t *mo) case MT_BALLHOG: case MT_SSMINE: case MT_BUBBLESHIELDTRAP: - case MT_EMERALD: // Remove stuff from death pits. if (P_CheckDeathPitCollide(mo)) { @@ -2089,6 +2089,7 @@ boolean P_ZMovement(mobj_t *mo) return false; } break; + case MT_REDFLAG: case MT_BLUEFLAG: // Remove from death pits. DON'T FUCKING DESPAWN IT DAMMIT @@ -2099,6 +2100,20 @@ boolean P_ZMovement(mobj_t *mo) } break; + case MT_EMERALD: + if (P_CheckDeathPitCollide(mo)) + { + P_RemoveMobj(mo); + return false; + } + + if (mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz) + { + // Stop when hitting the floor + mo->momx = mo->momy = 0; + } + break; + case MT_RING: // Ignore still rings case MT_BLUESPHERE: case MT_FLINGRING: @@ -8877,7 +8892,6 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_SINK: case MT_ROCKETSNEAKER: case MT_SPB: - case MT_EMERALD: thing->shadowscale = 3*FRACUNIT/2; break; case MT_BANANA_SHIELD: @@ -8904,6 +8918,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_RING: case MT_FLOATINGITEM: case MT_BLUESPHERE: + case MT_EMERALD: thing->shadowscale = FRACUNIT/2; break; case MT_DRIFTCLIP: From ea14d6bb1c30a68e376f42297f4168025c1f719e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 00:51:47 -0500 Subject: [PATCH 52/99] Use Super Emerald collect sound instead for now --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 6cf3335b2..8640268b6 100644 --- a/src/info.c +++ b/src/info.c @@ -8218,7 +8218,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate - sfx_s3k2b, // deathsound + sfx_s3k9c, // deathsound 0, // speed 72*FRACUNIT, // radius 72*FRACUNIT, // height From 7bff7931ede317f79e2ef63770219bbff813cf20 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 01:09:14 -0500 Subject: [PATCH 53/99] Sort wanted players by bumpers & emeralds first --- src/k_battle.c | 68 +++++++++++++++++++++++++++++--------------------- src/k_battle.h | 1 + 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index 42343002e..29b9333c7 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -58,24 +58,19 @@ boolean K_IsPlayerWanted(player_t *player) void K_CalculateBattleWanted(void) { - UINT8 numingame = 0, numplaying = 0, numwanted = 0; - SINT8 bestbumperplayer = -1, bestbumper = -1; + UINT8 numingame = 0, numwanted = 0; SINT8 camppos[MAXPLAYERS]; // who is the biggest camper UINT8 ties = 0, nextcamppos = 0; - boolean setbumper = false; UINT8 i, j; if (!(gametyperules & GTR_WANTED)) { - for (i = 0; i < 4; i++) - battlewanted[i] = -1; + memset(battlewanted, -1, sizeof (battlewanted)); return; } wantedcalcdelay = wantedfrequency; - - for (i = 0; i < MAXPLAYERS; i++) - camppos[i] = -1; // initialize + memset(camppos, -1, sizeof (camppos)); // initialize for (i = 0; i < MAXPLAYERS; i++) { @@ -87,33 +82,38 @@ void K_CalculateBattleWanted(void) if (players[i].exiting) // We're done, don't calculate. return; - numplaying++; - if (players[i].bumpers <= 0) // Not alive, so don't do anything else continue; numingame++; - if (bestbumper == -1 || players[i].bumpers > bestbumper) - { - bestbumper = players[i].bumpers; - bestbumperplayer = i; - } - else if (players[i].bumpers == bestbumper) - bestbumperplayer = -1; // Tie, no one has best bumper. - for (j = 0; j < MAXPLAYERS; j++) { if (!playeringame[j] || players[j].spectator) continue; + if (players[j].bumpers <= 0) continue; + if (j == i) continue; - if (players[j].kartstuff[k_wanted] == players[i].kartstuff[k_wanted] && players[j].marescore > players[i].marescore) + + if (K_NumEmeralds(&players[j]) > K_NumEmeralds(&players[i])) + { position++; + } + else if (players[j].bumpers > players[i].bumpers) + { + position++; + } + else if (players[j].marescore > players[i].marescore) + { + position++; + } else if (players[j].kartstuff[k_wanted] > players[i].kartstuff[k_wanted]) + { position++; + } } position--; // Make zero based @@ -124,7 +124,7 @@ void K_CalculateBattleWanted(void) camppos[position] = i; } - if (numplaying <= 2 || (numingame <= 2 && bestbumper == 1)) // In 1v1s then there's no need for WANTED. In bigger netgames, don't show anyone as WANTED when they're equally matched. + if (numingame <= 2) // In 1v1s then there's no need for WANTED. numwanted = 0; else numwanted = min(4, 1 + ((numingame-2) / 4)); @@ -132,19 +132,11 @@ void K_CalculateBattleWanted(void) for (i = 0; i < 4; i++) { if (i+1 > numwanted) // Not enough players for this slot to be wanted! - battlewanted[i] = -1; - else if (bestbumperplayer != -1 && !setbumper) // If there's a player who has an untied bumper lead over everyone else, they are the first to be wanted. { - battlewanted[i] = bestbumperplayer; - setbumper = true; // Don't set twice + battlewanted[i] = -1; } else { - // Don't accidentally set the same player, if the bestbumperplayer is also a huge camper. - while (bestbumperplayer != -1 && camppos[nextcamppos] != -1 - && bestbumperplayer == camppos[nextcamppos]) - nextcamppos++; - // Do not add *any* more people if there's too many times that are tied with others. // This could theoretically happen very easily if people don't hit each other for a while after the start of a match. // (I will be sincerely impressed if more than 2 people tie after people start hitting each other though) @@ -377,6 +369,24 @@ void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType) } } +UINT8 K_NumEmeralds(player_t *player) +{ + UINT8 i; + UINT8 num = 0; + + for (i = 0; i < 14; i++) + { + UINT32 emeraldFlag = (1 << i); + + if (player->powers[pw_emeralds] & emeraldFlag) + { + num++; + } + } + + return num; +} + void K_RunPaperItemSpawners(void) { const boolean overtime = (battleovertime.enabled >= 10*TICRATE); diff --git a/src/k_battle.h b/src/k_battle.h index c83cd7e04..ddd8a5437 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -23,6 +23,7 @@ void K_CheckBumpers(void); void K_CheckEmeralds(player_t *player); mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType); void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType); +UINT8 K_NumEmeralds(player_t *player); void K_RunPaperItemSpawners(void); void K_RunBattleOvertime(void); void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj); From 56dc08ed88223e06042f92690941ce172fd4b126 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 01:09:38 -0500 Subject: [PATCH 54/99] Shitty temp emeralds hud --- src/k_hud.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/k_hud.c b/src/k_hud.c index ff689f7f2..f6f6cbb47 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4115,4 +4115,9 @@ void K_drawKartHUD(void) } K_DrawWaypointDebugger(); + + if (gametype == GT_BATTLE) + { + V_DrawString(8, 8, V_SPLITSCREEN|V_SNAPTOTOP|V_SNAPTOLEFT, va("Emeralds: %d / 7", K_NumEmeralds(stplyr))); + } } From 2745ea2938303eaca5c15c5561729ef1531b6cc4 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 01:22:41 -0500 Subject: [PATCH 55/99] Drop emeralds in front of the hurt player, instead of to their left --- src/k_battle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_battle.c b/src/k_battle.c index 29b9333c7..cc12851d4 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -361,7 +361,7 @@ void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType) if ((player->powers[pw_emeralds] & emeraldFlag) && (emeraldFlag & emeraldType)) { - mobj_t *emerald = K_SpawnChaosEmerald(player->mo, player->mo->angle, flip, emeraldFlag); + mobj_t *emerald = K_SpawnChaosEmerald(player->mo, player->mo->angle - ANGLE_90, flip, emeraldFlag); P_SetTarget(&emerald->target, player->mo); player->powers[pw_emeralds] &= ~emeraldFlag; From 896b29f002fd07099371ff2ec067a0cc4d96e371 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 1 Nov 2020 22:33:42 -0800 Subject: [PATCH 56/99] Replace special handling for picking up items from below with MF_PICKUPFROMBELOW --- src/info.c | 2 +- src/k_collide.c | 31 ------------------------------- src/k_collide.h | 1 - src/p_inter.c | 38 ++++++++++++++++++++++++++++++++++---- src/p_map.c | 21 --------------------- src/p_mobj.h | 2 ++ 6 files changed, 37 insertions(+), 58 deletions(-) diff --git a/src/info.c b/src/info.c index 8640268b6..b7124449b 100644 --- a/src/info.c +++ b/src/info.c @@ -22769,7 +22769,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_DONTENCOREMAP, // flags + MF_SLIDEME|MF_SPECIAL|MF_PICKUPFROMBELOW|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, diff --git a/src/k_collide.c b/src/k_collide.c index 282fa0072..963ec4e64 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -404,34 +404,3 @@ boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2) K_KartBouncing(t2, t1, false, true); return false; } - -boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) -{ - player_t * player = t2->player; - - if (t1->flags2 & MF2_NIGHTSPULL) - return true; - - if (! player) - return true; - - if (!P_CanPickupItem(player, 3) || (player->kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != t1->threshold)) - return true; - - if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) - return true; - - player->kartstuff[k_itemtype] = t1->threshold; - player->kartstuff[k_itemamount] += t1->movecount; - if (player->kartstuff[k_itemamount] > 255) - player->kartstuff[k_itemamount] = 255; - - S_StartSound(t1, t1->info->deathsound); - - P_SetTarget(&t1->tracer, t2); - t1->flags2 |= MF2_NIGHTSPULL; - t1->destscale = mapobjectscale>>4; - t1->scalespeed <<= 1; - - return false; -} diff --git a/src/k_collide.h b/src/k_collide.h index fed8969d6..86f643b3f 100644 --- a/src/k_collide.h +++ b/src/k_collide.h @@ -12,6 +12,5 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2); boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2); boolean K_FallingRockCollide(mobj_t *t1, mobj_t *t2); boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2); -boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2); #endif diff --git a/src/p_inter.c b/src/p_inter.c index e8157543f..d990a0bb3 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -182,15 +182,24 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (heightcheck) { + fixed_t toucher_bottom = toucher->z; + fixed_t special_bottom = special->z; + + if (toucher->flags & MF_PICKUPFROMBELOW) + toucher_bottom -= toucher->height; + + if (special->flags & MF_PICKUPFROMBELOW) + special_bottom -= special->height; + if (toucher->momz < 0) { - if (toucher->z + toucher->momz > special->z + special->height) + if (toucher_bottom + toucher->momz > special->z + special->height) return; - } else if (toucher->z > special->z + special->height) + } else if (toucher_bottom > special->z + special->height) return; if (toucher->momz > 0) { - if (toucher->z + toucher->height + toucher->momz < special->z) + if (toucher->z + toucher->height + toucher->momz < special_bottom) return; - } else if (toucher->z + toucher->height < special->z) + } else if (toucher->z + toucher->height < special_bottom) return; } @@ -231,6 +240,27 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetObjectMomZ(player->mo, 12<mo, player->mo->angle, 20<kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != special->threshold)) + return; + + if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) + return; + + player->kartstuff[k_itemtype] = special->threshold; + player->kartstuff[k_itemamount] += special->movecount; + if (player->kartstuff[k_itemamount] > 255) + player->kartstuff[k_itemamount] = 255; + + S_StartSound(special, special->info->deathsound); + + P_SetTarget(&special->tracer, toucher); + special->flags2 |= MF2_NIGHTSPULL; + special->destscale = mapobjectscale>>4; + special->scalespeed <<= 1; + + special->flags &= ~MF_SPECIAL; + return; case MT_RANDOMITEM: if (!P_CanPickupItem(player, 1)) return; diff --git a/src/p_map.c b/src/p_map.c index 0b8c7f577..7a0958f7f 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -970,27 +970,6 @@ static boolean PIT_CheckThing(mobj_t *thing) return K_FallingRockCollide(thing, tmthing); } - if (tmthing->type == MT_FLOATINGITEM) - { - // see if it went over / under - if (tmthing->z - tmthing->height > thing->z + thing->height) - return true; // overhead - if (tmthing->z + tmthing->height < thing->z) // extended hitbox - return true; // underneath - - return K_FloatingItemCollide(tmthing, thing); - } - else if (thing->type == MT_FLOATINGITEM) - { - // see if it went over / under - if (tmthing->z > thing->z + thing->height) - return true; // overhead - if (tmthing->z + tmthing->height < thing->z - thing->height) // extended hitbox - return true; // underneath - - return K_FloatingItemCollide(thing, tmthing); - } - //} if ((thing->type == MT_SPRINGSHELL || thing->type == MT_YELLOWSHELL) && thing->health > 0 diff --git a/src/p_mobj.h b/src/p_mobj.h index 9cafcefa7..5c205a758 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -157,6 +157,8 @@ typedef enum MF_RUNSPAWNFUNC = 1<<27, // Don't remap in Encore mode. (Not a drawflag so that it's settable by mobjinfo.) MF_DONTENCOREMAP = 1<<28, + // Hitbox extends just as far below as above. + MF_PICKUPFROMBELOW = 1<<29, // free: to and including 1<<31 } mobjflag_t; From 6370919e0594a37ceea8b1bf954c8e5d9f61b769 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 1 Nov 2020 22:34:14 -0800 Subject: [PATCH 57/99] Pick up emeralds from below --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index b7124449b..1b9f58220 100644 --- a/src/info.c +++ b/src/info.c @@ -8226,7 +8226,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL, // flags + MF_SPECIAL|MF_PICKUPFROMBELOW, // flags S_NULL // raisestate }, From 7304dff3e5dc6605c91234c199ae8f8e3674cdd8 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 02:03:50 -0500 Subject: [PATCH 58/99] Don't let karma players pick anything up --- src/p_inter.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index e8157543f..7ce08cb82 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -108,11 +108,13 @@ void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End) // boolean P_CanPickupItem(player_t *player, UINT8 weapon) { - if (player->exiting || mapreset) + if (player->exiting || mapreset || player->eliminated) return false; - /*if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) // No bumpers in Match - return false;*/ +#ifndef OTHERKARMAMODES + if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) // No bumpers in Match + return false; +#endif if (weapon) { From 4a9a438270b5138c5ebc4cb43869ec808ae0fc62 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 03:51:16 -0500 Subject: [PATCH 59/99] Dummy out wanted system - Remove WANTED hud item - Person in 1st place is the bonus points giver - Sort players by Emeralds > Bumpers > Points --- src/d_clisrv.c | 4 +--- src/d_netcmd.c | 3 +-- src/k_battle.c | 6 ++++++ src/k_collide.c | 3 +-- src/k_hud.c | 5 ++++- src/k_kart.c | 29 ++++++++++++++++++++--------- 6 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 0e1d58098..d7f4af80c 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2992,9 +2992,7 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) } } - if (K_IsPlayerWanted(&players[playernum])) - K_CalculateBattleWanted(); - + K_CalculateBattleWanted(); LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting // don't look through someone's view who isn't there diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 223430e44..d31e9537e 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3469,8 +3469,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) if (gametyperules & GTR_BUMPERS) // SRB2kart { players[playernum].marescore = 0; - if (K_IsPlayerWanted(&players[playernum])) - K_CalculateBattleWanted(); + K_CalculateBattleWanted(); } K_PlayerForfeit(playernum, true); diff --git a/src/k_battle.c b/src/k_battle.c index cc12851d4..a9924b1de 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -41,6 +41,9 @@ INT32 K_StartingBumperCount(void) boolean K_IsPlayerWanted(player_t *player) { +#if 1 + return (player->kartstuff[k_position] == 1); +#else UINT8 i; if (!(gametyperules & GTR_WANTED)) @@ -54,6 +57,7 @@ boolean K_IsPlayerWanted(player_t *player) return true; } return false; +#endif } void K_CalculateBattleWanted(void) @@ -63,7 +67,9 @@ void K_CalculateBattleWanted(void) UINT8 ties = 0, nextcamppos = 0; UINT8 i, j; +#if 0 if (!(gametyperules & GTR_WANTED)) +#endif { memset(battlewanted, -1, sizeof (battlewanted)); return; diff --git a/src/k_collide.c b/src/k_collide.c index 963ec4e64..34c0e2b59 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -30,8 +30,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) if (t2->player) { - if (t2->player->powers[pw_flashing] - && !(t1->type == MT_ORBINAUT || t1->type == MT_JAWZ || t1->type == MT_JAWZ_DUD)) + if (t2->player->powers[pw_flashing] && (t1->type == MT_ORBINAUT_SHIELD || t1->type == MT_JAWZ_SHIELD)) return true; if (t2->player->kartstuff[k_hyudorotimer]) diff --git a/src/k_hud.c b/src/k_hud.c index f6f6cbb47..63f6b1af5 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2143,6 +2143,9 @@ static void K_drawKartWanted(void) UINT8 *colormap = NULL; INT32 basex = 0, basey = 0; + if (!splitscreen) + return; + if (stplyr != &players[displayplayers[0]]) return; @@ -4118,6 +4121,6 @@ void K_drawKartHUD(void) if (gametype == GT_BATTLE) { - V_DrawString(8, 8, V_SPLITSCREEN|V_SNAPTOTOP|V_SNAPTOLEFT, va("Emeralds: %d / 7", K_NumEmeralds(stplyr))); + V_DrawRightAlignedString(BASEVIDWIDTH - 10, BASEVIDHEIGHT - 18, V_SPLITSCREEN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, va("Emeralds: %d / 7", K_NumEmeralds(stplyr))); } } diff --git a/src/k_kart.c b/src/k_kart.c index 06c963db1..8bf94a65c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2454,9 +2454,7 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a } player->bumpers -= amount; - - if (K_IsPlayerWanted(player)) - K_CalculateBattleWanted(); + K_CalculateBattleWanted(); } if (player->bumpers <= 0) @@ -6793,7 +6791,7 @@ void K_KartUpdatePosition(player_t *player) if (!playeringame[i] || players[i].spectator || !players[i].mo) continue; - if (gametype == GT_RACE) + if (gametyperules & GTR_CIRCUIT) { if (player->exiting) // End of match standings { @@ -6812,7 +6810,7 @@ void K_KartUpdatePosition(player_t *player) } } } - else if (gametype == GT_BATTLE) + else { if (player->exiting) // End of match standings { @@ -6822,11 +6820,24 @@ void K_KartUpdatePosition(player_t *player) } else { - // I have less points than but the same bumpers as this player OR - // I have less bumpers than this player - if ((players[i].bumpers == player->bumpers && players[i].marescore > player->marescore) - || (players[i].bumpers > player->bumpers)) + if (K_NumEmeralds(&players[i]) > K_NumEmeralds(player)) + { position++; + } + else if (players[i].bumpers > player->bumpers) + { + position++; + } + else if (players[i].marescore > player->marescore) + { + position++; + } + /* + else if (players[i].kartstuff[k_wanted] > player->kartstuff[k_wanted]) + { + position++; + } + */ } } } From e478d542a0c3600b9f2a06cf89db61a189e064ab Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 04:23:31 -0500 Subject: [PATCH 60/99] Emeralds are on ranking --- src/k_hud.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 63f6b1af5..9b4bf88f7 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -88,6 +88,7 @@ static patch_t *kp_rankbumper; static patch_t *kp_tinybumper[2]; static patch_t *kp_ranknobumpers; static patch_t *kp_rankcapsule; +static patch_t *kp_rankemeralds[7]; static patch_t *kp_battlewin; static patch_t *kp_battlecool; @@ -351,6 +352,13 @@ void K_LoadKartHUDGraphics(void) kp_ranknobumpers = W_CachePatchName("K_NOBLNS", PU_HUDGFX); kp_rankcapsule = W_CachePatchName("K_CAPICO", PU_HUDGFX); + sprintf(buffer, "K_EMERCx"); + for (i = 0; i < 7; i++) + { + buffer[7] = '0'+(i+1); + kp_rankemeralds[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + } + // Battle graphics kp_battlewin = W_CachePatchName("K_BWIN", PU_HUDGFX); kp_battlecool = W_CachePatchName("K_BCOOL", PU_HUDGFX); @@ -1515,7 +1523,7 @@ static boolean K_drawKartPositionFaces(void) INT32 i, j, ranklines, strank = -1; boolean completed[MAXPLAYERS]; INT32 rankplayer[MAXPLAYERS]; - INT32 bumperx, numplayersingame = 0; + INT32 bumperx, emeraldx, numplayersingame = 0; UINT8 *colormap; ranklines = 0; @@ -1596,6 +1604,7 @@ static boolean K_drawKartPositionFaces(void) if (!players[rankplayer[i]].mo) continue; bumperx = FACE_X+19; + emeraldx = FACE_X+16; if (players[rankplayer[i]].mo->color) { @@ -1609,7 +1618,7 @@ static boolean K_drawKartPositionFaces(void) if (LUA_HudEnabled(hud_battlebumpers)) { - if (gametype == GT_BATTLE && players[rankplayer[i]].bumpers > 0) + if ((gametyperules & GTR_BUMPERS) && players[rankplayer[i]].bumpers > 0) { V_DrawMappedPatch(bumperx-2, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[0], colormap); for (j = 1; j < players[rankplayer[i]].bumpers; j++) @@ -1618,7 +1627,18 @@ static boolean K_drawKartPositionFaces(void) V_DrawMappedPatch(bumperx, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[1], colormap); } } - } // A new level of stupidity: checking if lua is enabled to close a bracket. :Fascinating: + } + } + + for (j = 0; j < 7; j++) + { + UINT32 emeraldFlag = (1 << j); + + if (players[rankplayer[i]].powers[pw_emeralds] & emeraldFlag) + { + V_DrawScaledPatch(emeraldx, Y+7, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_rankemeralds[j]); + emeraldx += 7; + } } if (i == strank) From a19ce98350aa1e12bdc6c44f2d99ffc5750ec4fb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 05:15:45 -0500 Subject: [PATCH 61/99] Fix positions tying at 2nd place --- src/k_kart.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 8bf94a65c..29dfe1d67 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6820,24 +6820,30 @@ void K_KartUpdatePosition(player_t *player) } else { - if (K_NumEmeralds(&players[i]) > K_NumEmeralds(player)) + UINT8 myEmeralds = K_NumEmeralds(player); + UINT8 yourEmeralds = K_NumEmeralds(&players[i]); + + if (yourEmeralds > myEmeralds) { + // Emeralds matter above all position++; } - else if (players[i].bumpers > player->bumpers) + else if (yourEmeralds == myEmeralds) { - position++; + // Bumpers are a tie breaker + if (players[i].bumpers > player->bumpers) + { + position++; + } + else if (players[i].bumpers == player->bumpers) + { + // Score is the second tier tie breaker + if (players[i].marescore > player->marescore) + { + position++; + } + } } - else if (players[i].marescore > player->marescore) - { - position++; - } - /* - else if (players[i].kartstuff[k_wanted] > player->kartstuff[k_wanted]) - { - position++; - } - */ } } } From d970747c85979ff3480dfff28271f7b8b4be4736 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 05:19:45 -0500 Subject: [PATCH 62/99] Remove FIN KartZ holdover that Oni never wanted apparently :V --- src/k_hud.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 9b4bf88f7..330bfb8fe 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1925,11 +1925,7 @@ static void K_drawKartLapsAndRings(void) { // Laps V_DrawScaledPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_lapsticker); - - if (stplyr->exiting) - V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, "FIN"); - else - V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->laps, cv_numlaps.value)); + V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->laps, cv_numlaps.value)); // Rings if (!uselives) From 648f1f0958e119978ddaf3d83e57efbdff1d0601 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 00:20:14 -0800 Subject: [PATCH 63/99] Revert "Do not sort sprite in front of plane if plane should render in front of sprite's plane" This reverts commit 0d6f329b1d9ecf3ba754a5affe80c669c56afc07. --- src/r_things.c | 37 ++----------------------------------- src/r_things.h | 1 - 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index df1946ba6..9702c7d3f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1230,32 +1230,6 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) return groundz; } -static void R_SetSpritePlaneHeights(vissprite_t *vis) -{ - ffloor_t *rover; - - fixed_t top; - fixed_t bot; - - vis->pt = vis->sector->floorheight; - vis->pb = vis->sector->ceilingheight; - - for (rover = vis->sector->ffloors; rover; rover = rover->next) - { - if (rover->flags & FF_EXISTS) - { - top = P_GetFFloorTopZAt (rover, vis->gx, vis->gy); - bot = P_GetFFloorBottomZAt (rover, vis->gx, vis->gy); - - if (top <= vis->gzt && top > vis->pt) - vis->pt = top; - - if (bot >= vis->gz && bot < vis->pb) - vis->pb = bot; - } - } -} - static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz) { vissprite_t *shadow; @@ -1344,8 +1318,6 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->xscale = FixedMul(xscale, shadowxscale); //SoM: 4/17/2000 shadow->scale = FixedMul(yscale, shadowyscale); shadow->sector = vis->sector; - shadow->pt = vis->pt; - shadow->pb = vis->pb; shadow->szt = (INT16)((centeryfrac - FixedMul(shadow->gzt - viewz, yscale))>>FRACBITS); shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS); shadow->cut = SC_ISSCALED|SC_SHADOW; //check this @@ -1845,9 +1817,6 @@ static void R_ProjectSprite(mobj_t *thing) vis->sector = thing->subsector->sector; vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS); vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS); - - R_SetSpritePlaneHeights(vis); - vis->cut = cut; if (thing->subsector->sector->numlights) vis->extra_colormap = *thing->subsector->sector->lightlist[light].extra_colormap; @@ -2062,8 +2031,6 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, yscale))>>FRACBITS); vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, yscale))>>FRACBITS); - R_SetSpritePlaneHeights(vis); - iscale = FixedDiv(FRACUNIT, xscale); vis->startfrac = 0; @@ -2443,12 +2410,12 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps // bird: if any part of the sprite peeks in front the plane if (planecameraz < viewz) { - if (rover->pt >= planeobjectz && rover->gzt >= planeobjectz) + if (rover->gzt >= planeobjectz) continue; } else if (planecameraz > viewz) { - if (rover->pb <= planeobjectz && rover->gz <= planeobjectz) + if (rover->gz <= planeobjectz) continue; } diff --git a/src/r_things.h b/src/r_things.h index f95cd5c9e..400a63bcb 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -171,7 +171,6 @@ typedef struct vissprite_s // Precalculated top and bottom screen coords for the sprite. sector_t *sector; // The sector containing the thing. - fixed_t pt, pb; // plane heights, also for sorting against 3D floors INT16 sz, szt; spritecut_e cut; From 131d592bbfa896f131210e79ce458f0efa670d13 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 04:55:01 -0800 Subject: [PATCH 64/99] Do not factor height into sprite thickseg sorting --- src/r_things.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 9702c7d3f..50eb222ae 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2448,7 +2448,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps } else if (r2->thickseg) { - fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz; + //fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz; if (rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1) continue; @@ -2459,6 +2459,11 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if (scale <= rover->sortscale) continue; + // bird: Always sort sprites behind segs. This helps the plane + // sorting above too. Basically if the sprite gets sorted behind + // the seg here, it will be behind the plane too, since planes + // are added after segs in the list. +#if 0 topplaneobjectz = P_GetFFloorTopZAt (r2->ffloor, rover->gx, rover->gy); topplanecameraz = P_GetFFloorTopZAt (r2->ffloor, viewx, viewy); botplaneobjectz = P_GetFFloorBottomZAt(r2->ffloor, rover->gx, rover->gy); @@ -2467,6 +2472,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if ((topplanecameraz > viewz && botplanecameraz < viewz) || (topplanecameraz < viewz && rover->gzt < topplaneobjectz) || (botplanecameraz > viewz && rover->gz > botplaneobjectz)) +#endif { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; From 1a58d0d24bd8a409403d38377d93a476c2c4cc46 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 12 Nov 2020 01:43:37 -0500 Subject: [PATCH 65/99] Try and fix hitlag damage, lightning shield, & punting mines --- src/k_kart.c | 81 +++++++++++++++++++++++++++++---------------------- src/p_enemy.c | 8 +---- src/p_inter.c | 3 +- src/p_mobj.c | 15 +++++----- 4 files changed, 56 insertions(+), 51 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index e35b9ff56..35b9d9481 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2382,10 +2382,15 @@ void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics) INT32 tics1 = tics; INT32 tics2 = tics; + if (tics <= 0) + { + return; + } + if (mo1valid == true && mo2valid == true) { + const INT32 mintics = 1; const fixed_t ticaddfactor = mapobjectscale * 8; - const INT32 mintics = tics; const fixed_t mo1speed = FixedHypot(FixedHypot(mo1->momx, mo1->momy), mo1->momz); const fixed_t mo2speed = FixedHypot(FixedHypot(mo2->momx, mo2->momy), mo2->momz); @@ -2430,12 +2435,12 @@ void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics) if (mo1valid == true) { - mo1->hitlag += tics1; + mo1->hitlag = max(tics1, mo1->hitlag); } if (mo2valid == true) { - mo2->hitlag += tics2; + mo2->hitlag = max(tics2, mo2->hitlag); } } @@ -3568,11 +3573,11 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map else { // Use pre-determined speed for tossing - PROJSPEED = FixedMul(82 << FRACBITS, K_GetKartGameSpeedScalar(gamespeed)); + PROJSPEED = FixedMul(82 * FRACUNIT, K_GetKartGameSpeedScalar(gamespeed)); } - // Scale to map size - PROJSPEED = FixedMul(PROJSPEED, mapobjectscale); + // Scale to player scale + PROJSPEED = FixedMul(PROJSPEED, player->mo->scale); if (altthrow) { @@ -3672,7 +3677,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map if (mo) { angle_t fa = player->mo->angle>>ANGLETOFINESHIFT; - fixed_t HEIGHT = (20 + (dir*10))*FRACUNIT + (player->mo->momz*P_MobjFlip(player->mo)); + fixed_t HEIGHT = ((20 + (dir*10)) * player->mo->scale) + (player->mo->momz*P_MobjFlip(player->mo)); P_SetObjectMomZ(mo, HEIGHT, false); mo->momx = player->mo->momx + FixedMul(FINECOSINE(fa), PROJSPEED*dir); @@ -3777,41 +3782,48 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map return mo; } -void K_PuntMine(mobj_t *thismine, mobj_t *punter) +void K_PuntMine(mobj_t *origMine, mobj_t *punter) { - angle_t fa = K_MomentumAngle(punter) >> ANGLETOFINESHIFT; - fixed_t z = 30*mapobjectscale + punter->momz; + angle_t fa = K_MomentumAngle(punter); + fixed_t z = punter->momz + (30 * punter->scale); fixed_t spd; mobj_t *mine; - if (!thismine || P_MobjWasRemoved(thismine)) + if (!origMine || P_MobjWasRemoved(origMine)) return; - //This guarantees you hit a mine being dragged - if (thismine->type == MT_SSMINE_SHIELD) // Create a new mine, and clean up the old one + if (punter->hitlag > 0) + return; + + // This guarantees you hit a mine being dragged + if (origMine->type == MT_SSMINE_SHIELD) // Create a new mine, and clean up the old one { - mine = P_SpawnMobj(thismine->x, thismine->y, thismine->z, MT_SSMINE); - P_SetTarget(&mine->target, thismine->target); - mine->angle = thismine->angle; - mine->flags2 = thismine->flags2; - mine->floorz = thismine->floorz; - mine->ceilingz = thismine->ceilingz; + mobj_t *mineOwner = origMine->target; - //Since we aren't using P_KillMobj, we need to clean up the hnext reference + mine = P_SpawnMobj(origMine->x, origMine->y, origMine->z, MT_SSMINE); + + P_SetTarget(&mine->target, mineOwner); + mine->angle = origMine->angle; + mine->flags2 = origMine->flags2; + mine->floorz = origMine->floorz; + mine->ceilingz = origMine->ceilingz; + + // Since we aren't using P_KillMobj, we need to clean up the hnext reference + P_SetTarget(&mineOwner->hnext, NULL); + mineOwner->player->kartstuff[k_bananadrag] = 0; + mineOwner->player->kartstuff[k_itemheld] = 0; + + if (--mineOwner->player->kartstuff[k_itemamount] <= 0) { - P_SetTarget(&thismine->target->hnext, NULL); //target is the player who owns the mine - thismine->target->player->kartstuff[k_bananadrag] = 0; - thismine->target->player->kartstuff[k_itemheld] = 0; - - if (--thismine->target->player->kartstuff[k_itemamount] <= 0) - thismine->target->player->kartstuff[k_itemtype] = KITEM_NONE; + mineOwner->player->kartstuff[k_itemtype] = KITEM_NONE; } - P_RemoveMobj(thismine); - + P_RemoveMobj(origMine); } else - mine = thismine; + { + mine = origMine; + } if (!mine || P_MobjWasRemoved(mine)) return; @@ -3819,21 +3831,20 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter) if (mine->threshold > 0 || mine->hitlag > 0) return; - spd = (82 + ((gamespeed-1) * 14))*mapobjectscale; // Avg Speed is 41 in Normal + spd = FixedMul(82 * punter->scale, K_GetKartGameSpeedScalar(gamespeed)); // Avg Speed is 41 in Normal mine->flags |= MF_NOCLIPTHING; P_SetMobjState(mine, S_SSMINE_AIR1); mine->threshold = 10; - mine->extravalue1 = 0; mine->reactiontime = mine->info->reactiontime; - K_SetHitLagForObjects(punter, mine, 5); - - mine->momx = punter->momx + FixedMul(FINECOSINE(fa), spd); - mine->momy = punter->momy + FixedMul(FINESINE(fa), spd); + mine->momx = punter->momx + FixedMul(FINECOSINE(fa >> ANGLETOFINESHIFT), spd); + mine->momy = punter->momy + FixedMul(FINESINE(fa >> ANGLETOFINESHIFT), spd); mine->momz = P_MobjFlip(mine) * z; + //K_SetHitLagForObjects(punter, mine, 5); + mine->flags &= ~MF_NOCLIPTHING; } diff --git a/src/p_enemy.c b/src/p_enemy.c index bc925d4aa..3e8e0ba7d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4457,9 +4457,6 @@ void A_GrenadeRing(mobj_t *actor) if (actor->flags2 & MF2_DEBRIS) return; - if (actor->hitlag > 0) - return; - if (actor->state == &states[S_SSMINE_DEPLOY8]) explodedist = (3*explodedist)/2; @@ -4484,7 +4481,7 @@ static inline boolean PIT_MineExplode(mobj_t *thing) if (!grenade || P_MobjWasRemoved(grenade)) return false; // There's the possibility these can chain react onto themselves after they've already died if there are enough all in one spot - if (grenade->flags2 & MF2_DEBRIS) // don't explode twice + if (grenade->flags2 & MF2_DEBRIS) // don't explode twice return false; if (thing == grenade || thing->type == MT_MINEEXPLOSIONSOUND) // Don't explode yourself! Endless loop! @@ -4527,9 +4524,6 @@ void A_SSMineExplode(mobj_t *actor) if (actor->flags2 & MF2_DEBRIS) return; - if (actor->hitlag > 0) - return; - type = (mobjtype_t)locvar1; // Use blockmap to check for nearby shootables diff --git a/src/p_inter.c b/src/p_inter.c index efa3d3eaa..ebf7895bd 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1797,8 +1797,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (!(target->flags & MF_SHOOTABLE)) return false; // shouldn't happen... - // Make sure that boxes cannot be popped by enemies, red rings, etc. - if (target->flags & MF_MONITOR && ((!source || !source->player) || (inflictor && !inflictor->player))) + if (target->hitlag > 0) return false; } diff --git a/src/p_mobj.c b/src/p_mobj.c index ae09c87e1..d8bf7e289 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6348,7 +6348,8 @@ static boolean P_MobjRegularThink(mobj_t *mobj) ghost->colorized = true; // already has color! } - if (P_IsObjectOnGround(mobj) && (mobj->state == &states[S_SSMINE_AIR1] || mobj->state == &states[S_SSMINE_AIR2])) + if (P_IsObjectOnGround(mobj) && (mobj->momz * P_MobjFlip(mobj)) <= 0 + && (mobj->state == &states[S_SSMINE_AIR1] || mobj->state == &states[S_SSMINE_AIR2])) { if (mobj->extravalue1 > 0) mobj->extravalue1--; @@ -8397,12 +8398,6 @@ void P_MobjThinker(mobj_t *mobj) I_Assert(mobj != NULL); I_Assert(!P_MobjWasRemoved(mobj)); - if (mobj->flags & MF_NOTHINK) - return; - - if ((mobj->flags & MF_BOSS) && mobj->spawnpoint && (bossdisabled & (1<spawnpoint->extrainfo))) - return; - // Remove dead target/tracer. if (mobj->target && P_MobjWasRemoved(mobj->target)) P_SetTarget(&mobj->target, NULL); @@ -8413,6 +8408,12 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->hprev && P_MobjWasRemoved(mobj->hprev)) P_SetTarget(&mobj->hprev, NULL); + if (mobj->flags & MF_NOTHINK) + return; + + if ((mobj->flags & MF_BOSS) && mobj->spawnpoint && (bossdisabled & (1<spawnpoint->extrainfo))) + return; + // Don't run any thinker code while in hitlag if (mobj->hitlag > 0) { From 827a1b5fcabf1d16b5ad424b85f5a28854dacdb0 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 15 Nov 2020 06:25:38 -0500 Subject: [PATCH 66/99] Refactor stealing & destroying bumpers - Prevents being able to farm extra bumpers off of karma players - Paves the way for bumper destroy animation later --- src/d_clisrv.c | 4 +- src/d_clisrv.h | 2 +- src/d_player.h | 2 +- src/dehacked.c | 1 + src/k_kart.c | 260 +++++++++++++++++++++++++++------------------- src/k_kart.h | 7 +- src/lua_baselib.c | 6 +- src/p_inter.c | 49 ++++++--- src/p_local.h | 1 + src/p_mobj.c | 42 +++++--- src/p_saveg.c | 4 +- 11 files changed, 229 insertions(+), 149 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 43bb54538..11d603cae 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -617,7 +617,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->airtime = (tic_t)LONG(players[i].airtime); - rsp->bumpers = SHORT(players[i].bumpers); + rsp->bumpers = players[i].bumpers; rsp->karmadelay = SHORT(players[i].karmadelay); rsp->eliminated = players[i].eliminated; @@ -765,7 +765,7 @@ static void resynch_read_player(resynch_pak *rsp) players[i].airtime = (tic_t)LONG(rsp->airtime); - players[i].bumpers = SHORT(rsp->bumpers); + players[i].bumpers = rsp->bumpers; players[i].karmadelay = SHORT(rsp->karmadelay); players[i].eliminated = rsp->eliminated; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index c5f69d9df..ab08f0bdb 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -281,7 +281,7 @@ typedef struct // SRB2kart INT32 kartstuff[NUMKARTSTUFF]; tic_t airtime; - INT16 bumpers; + UINT8 bumpers; INT16 karmadelay; boolean eliminated; diff --git a/src/d_player.h b/src/d_player.h index a9330ffc8..f9159e8b7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -524,7 +524,7 @@ typedef struct player_s waypoint_t *nextwaypoint; respawnvars_t respawn; // Respawn info tic_t airtime; // Keep track of how long you've been in the air - INT16 bumpers; + UINT8 bumpers; INT16 karmadelay; boolean eliminated; diff --git a/src/dehacked.c b/src/dehacked.c index 49b34e8bc..ae9ab561a 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -11313,6 +11313,7 @@ struct { {"DMG_EXPLODE",DMG_EXPLODE}, {"DMG_SQUISH",DMG_SQUISH}, {"DMG_STING",DMG_STING}, + {"DMG_KARMA",DMG_KARMA}, //// Death types {"DMG_INSTAKILL",DMG_INSTAKILL}, {"DMG_DEATHPIT",DMG_DEATHPIT}, diff --git a/src/k_kart.c b/src/k_kart.c index ecdb32f5d..cf45256ac 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2461,93 +2461,51 @@ void K_DoInstashield(player_t *player) P_SetTarget(&layerb->target, player->mo); } -void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted) +void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved) { - if (reducewanted == false) - points = 1; // Force to 1 + UINT8 points = 1; + boolean trapItem = false; + + if (player == NULL || victim == NULL) + { + // Invalid player or victim + return; + } + + if (player == victim) + { + // You cannot give yourself points + return; + } + + if ((inflictor && !P_MobjWasRemoved(inflictor)) && (inflictor->type == MT_BANANA && inflictor->health > 1)) + { + trapItem = true; + } + + // Only apply score bonuses to non-bananas + if (trapItem == false) + { + if (K_IsPlayerWanted(victim)) + { + // +3 points for hitting a wanted player + points = 3; + } + else if (gametyperules & GTR_BUMPERS) + { + if ((victim->bumpers > 0) && (victim->bumpers <= bumpersRemoved)) + { + // +2 points for finishing off a player + points = 2; + } + } + } if (gametyperules & GTR_POINTLIMIT) { P_AddPlayerScore(player, points); K_SpawnBattlePoints(player, victim, points); } - - if ((gametyperules & GTR_WANTED) && (reducewanted == true)) - { - // Seems a little backwards, but the WANTED system is meant to prevent camping. - // If you don't want people to go after you, then be proactive! - player->kartstuff[k_wanted] -= wantedreduce; - victim->kartstuff[k_wanted] -= (wantedreduce/2); - } -} - -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount, boolean force) -{ - UINT8 score = 1; - boolean trapitem = false; - - if (amount <= 0) - return; - - if (!(gametyperules & GTR_BUMPERS)) - return; - - if (force == false) - { - if (player->powers[pw_flashing] || P_PlayerInPain(player)) - return; - } - - if (inflictor && !P_MobjWasRemoved(inflictor)) - { - if (inflictor->type == MT_BANANA && inflictor->health <= 1) - { - trapitem = true; - } - } - - if (gametyperules & GTR_POINTLIMIT) - { - if (K_IsPlayerWanted(player)) - score = 3; - else if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= amount)) - score = 2; - } - - if (source && source->player && player != source->player) - { - K_BattleHitPlayer(source->player, player, score, trapitem); - } - - if (player->bumpers > 0) - { - if (player->bumpers <= amount) - { - mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); // Player hitbox is too small!! - P_SetTarget(&karmahitbox->target, player->mo); - karmahitbox->destscale = player->mo->scale; - P_SetScale(karmahitbox, player->mo->scale); - CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); - } - - player->bumpers -= amount; - K_CalculateBattleWanted(); - } - - if (player->bumpers <= 0) - { - player->bumpers = 0; - player->karmadelay = comebacktime; - - if (player->kartstuff[k_comebackmode] == 2) - { - mobj_t *poof = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EXPLODE); - S_StartSound(poof, mobjinfo[MT_KARMAHITBOX].seesound); - player->kartstuff[k_comebackmode] = 0; - } - } - - K_CheckBumpers(); } void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type) @@ -2660,30 +2618,110 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source) P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); } -void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) +void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers) { - INT32 intendedamount = player->bumpers + amount; - INT32 newbumper; - angle_t newangle, diff; - fixed_t newx, newy; - mobj_t *newmo; - - if (amount <= 0) + if (!(gametyperules & GTR_BUMPERS)) + { + // Bumpers aren't being used return; + } + + // TODO: replace all console text print-outs with a real visual + + if (player->bumpers > 0 && prevBumpers == 0) + { + if (player->kartstuff[k_comebackmode] == 2) + { + mobj_t *poof = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EXPLODE); + S_StartSound(poof, mobjinfo[MT_KARMAHITBOX].seesound); + } + + player->kartstuff[k_comebackmode] = 0; + + if (netgame) + { + CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]); + } + } + else if (player->bumpers == 0 && prevBumpers > 0) + { + mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); + P_SetTarget(&karmahitbox->target, player->mo); + + karmahitbox->destscale = player->mo->destscale; + P_SetScale(karmahitbox, player->mo->scale); + + if (netgame) + { + CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); + } + } + + player->karmadelay = comebacktime; + K_CalculateBattleWanted(); + K_CheckBumpers(); +} + +void K_DestroyBumpers(player_t *player, UINT8 amount) +{ + UINT8 oldBumpers = player->bumpers; if (!(gametyperules & GTR_BUMPERS)) - return; - - if (netgame && player->bumpers <= 0) - CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]); - - while (player->bumpers < intendedamount) { - newbumper = player->bumpers; + return; + } + + amount = min(amount, player->bumpers); + + if (amount == 0) + { + return; + } + + player->bumpers -= amount; + + // TODO: Store a bumperlist on the player mobj, + // that way we can do a bumper destruction animation + + K_HandleBumperChanges(player, oldBumpers); +} + +void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount) +{ + UINT8 oldPlayerBumpers = player->bumpers; + UINT8 oldVictimBumpers = victim->bumpers; + + UINT8 tookBumpers = 0; + + if (!(gametyperules & GTR_BUMPERS)) + { + return; + } + + amount = min(amount, victim->bumpers); + + if (amount == 0) + { + return; + } + + while ((tookBumpers < amount) && (victim->bumpers > 0)) + { + UINT8 newbumper = player->bumpers; + + angle_t newangle, diff; + fixed_t newx, newy; + + mobj_t *newmo; + if (newbumper <= 1) + { diff = 0; + } else + { diff = FixedAngle(360*FRACUNIT/newbumper); + } newangle = player->mo->angle; newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); @@ -2691,36 +2729,42 @@ void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) newmo = P_SpawnMobj(newx, newy, player->mo->z, MT_BATTLEBUMPER); newmo->threshold = newbumper; + P_SetTarget(&newmo->tracer, victim->mo); P_SetTarget(&newmo->target, player->mo); + newmo->angle = (diff * (newbumper-1)); newmo->color = victim->skincolor; if (newbumper+1 < 2) + { P_SetMobjState(newmo, S_BATTLEBUMPER3); + } else if (newbumper+1 < 3) + { P_SetMobjState(newmo, S_BATTLEBUMPER2); + } else + { P_SetMobjState(newmo, S_BATTLEBUMPER1); + } player->bumpers++; + victim->bumpers--; + tookBumpers++; } + if (tookBumpers == 0) + { + // No change occured. + return; + } + + // Play steal sound S_StartSound(player->mo, sfx_3db06); - player->powers[pw_flashing] = K_GetKartFlashing(player); - player->karmadelay = comebacktime; - - /* - victim->powers[pw_flashing] = K_GetKartFlashing(victim); - victim->karmadelay = comebacktime; - */ - - victim->kartstuff[k_instashield] = 15; - if (cv_kartdebughuddrop.value && !modeattacking) - K_DropItems(victim); - else - K_DropHnextList(victim, false); + K_HandleBumperChanges(player, oldPlayerBumpers); + K_HandleBumperChanges(victim, oldVictimBumpers); } // source is the mobj that originally threw the bomb that exploded etc. diff --git a/src/k_kart.h b/src/k_kart.h index ce3300b52..cadb8b772 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -42,13 +42,14 @@ void K_KartPlayerAfterThink(player_t *player); angle_t K_MomentumAngle(mobj_t *mo); void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics); void K_DoInstashield(player_t *player); -void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted); -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount, boolean force); +void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_DebtStingPlayer(player_t *player, mobj_t *source); -void K_StealBumper(player_t *player, player_t *victim, UINT8 amount); +void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers); +void K_DestroyBumpers(player_t *player, UINT8 amount); +void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount); void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source); void K_SpawnMineExplosion(mobj_t *source, UINT8 color); UINT16 K_DriftSparkColor(player_t *player, INT32 charge); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index a9d09dd58..d689dc848 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3432,7 +3432,7 @@ static int lib_kExplodePlayer(lua_State *L) return 0; } -static int lib_kStealBumper(lua_State *L) +static int lib_kTakeBumpersFromPlayer(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *victim = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); @@ -3442,7 +3442,7 @@ static int lib_kStealBumper(lua_State *L) return LUA_ErrInvalid(L, "player_t"); if (!victim) return LUA_ErrInvalid(L, "player_t"); - K_StealBumper(player, victim, amount); + K_TakeBumpersFromPlayer(player, victim, amount); return 0; } @@ -3919,7 +3919,7 @@ static luaL_Reg lib[] = { {"K_SpinPlayer",lib_kSpinPlayer}, {"K_SquishPlayer",lib_kSquishPlayer}, {"K_ExplodePlayer",lib_kExplodePlayer}, - {"K_StealBumper",lib_kStealBumper}, + {"K_TakeBumpersFromPlayer",lib_kTakeBumpersFromPlayer}, {"K_SpawnKartExplosion",lib_kSpawnKartExplosion}, {"K_SpawnMineExplosion",lib_kSpawnMineExplosion}, {"K_SpawnBoostTrail",lib_kSpawnBoostTrail}, diff --git a/src/p_inter.c b/src/p_inter.c index 9b71eac0d..39dfe7404 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -305,7 +305,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { mobj_t *boom; - if (P_DamageMobj(toucher, special, special->target, 1, DMG_EXPLODE) == false) + if (P_DamageMobj(toucher, special, special->target, 1, DMG_KARMA) == false) { return; } @@ -323,9 +323,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(boom, special->info->attacksound); - K_StealBumper(special->target->player, player, max(1, player->bumpers-1)); // bumpers-1 to slowly remove bumpers from the economy - K_RemoveBumper(player, special->target, special->target, player->bumpers, true); - special->target->player->karthud[khud_yougotem] = 2*TICRATE; special->target->player->karmadelay = comebacktime; } @@ -1692,7 +1689,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, { case DMG_DEATHPIT: // Respawn kill types - K_RemoveBumper(player, NULL, NULL, 1, true); + K_DestroyBumpers(player, 1); K_DoIngameRespawn(player); return false; default: @@ -1733,7 +1730,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, P_SetTarget(&boom->target, player->mo); } - K_RemoveBumper(player, NULL, NULL, player->bumpers, true); + K_DestroyBumpers(player, player->bumpers); player->eliminated = true; } @@ -1923,31 +1920,54 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } } - // We successfully hit 'em! + // We successfully damaged them! Give 'em some bumpers! if (type != DMG_STING) { - UINT8 bumpadd = 1; + UINT8 takeBumpers = 1; if (damagetype & DMG_STEAL) { - bumpadd = 2; + takeBumpers = 2; + + if (type == DMG_KARMA) + { + takeBumpers = player->bumpers; + } + } + else + { + if (type == DMG_KARMA) + { + // Take half of their bumpers for karma comeback damage + takeBumpers = max(1, player->bumpers / 2); + } } if (source && source != player->mo && source->player) { K_PlayHitEmSound(source); - K_StealBumper(source->player, player, bumpadd); + + K_BattleAwardHit(source->player, player, inflictor, takeBumpers); + K_TakeBumpersFromPlayer(source->player, player, takeBumpers); + + if (type == DMG_KARMA) + { + // Destroy any remainder bumpers from the player for karma comeback damage + K_DestroyBumpers(player, player->bumpers); + } if (damagetype & DMG_STEAL) { - // Give them ALL of your emeralds :) + // Give them ALL of your emeralds instantly :) source->player->powers[pw_emeralds] |= player->powers[pw_emeralds]; player->powers[pw_emeralds] = 0; K_CheckEmeralds(source->player); } } - - K_RemoveBumper(player, inflictor, source, bumpadd, false); + else + { + K_DestroyBumpers(player, takeBumpers); + } if (!(damagetype & DMG_STEAL)) { @@ -1968,6 +1988,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da ringburst = 0; break; case DMG_EXPLODE: + case DMG_KARMA: K_ExplodePlayer(player, inflictor, source); break; case DMG_WIPEOUT: @@ -1997,7 +2018,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da K_PlayPainSound(player->mo); - if ((type == DMG_EXPLODE) || (cv_kartdebughuddrop.value && !modeattacking)) + if ((type == DMG_EXPLODE || type == DMG_KARMA) || (cv_kartdebughuddrop.value && !modeattacking)) { K_DropItems(player); } diff --git a/src/p_local.h b/src/p_local.h index bdc28075a..b577f3cef 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -467,6 +467,7 @@ typedef struct BasicFF_s #define DMG_EXPLODE 0x02 #define DMG_SQUISH 0x03 #define DMG_STING 0x04 +#define DMG_KARMA 0x05 // Karma Bomb explosion -- works like DMG_EXPLODE, but steals half of their bumpers & deletes the rest //// Death types - cannot be combined with damage types #define DMG_INSTAKILL 0x80 #define DMG_DEATHPIT 0x81 diff --git a/src/p_mobj.c b/src/p_mobj.c index 42bbecb1e..090977559 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5278,15 +5278,23 @@ static void P_MobjSceneryThink(mobj_t *mobj) } break; case MT_BATTLEBUMPER: - if (mobj->health > 0 && mobj->target && mobj->target->player - && mobj->target->health > 0 && !mobj->target->player->spectator) + if (mobj->health <= 0) { + // DO EXPLODE ANIMATION HERE + //CONS_Printf("bumper explosion\n"); + P_RemoveMobj(mobj); + return; + } + else if (mobj->target && mobj->target->player && mobj->target->health > 0 && !mobj->target->player->spectator) + { + // Following a player + fixed_t rad = 32*mobj->target->scale; fixed_t offz; angle_t ang, diff; if (!((mobj->target->player-players) & 1)) - ang = (FixedAngle(mobj->info->speed) * -1); + ang = -FixedAngle(mobj->info->speed); else ang = FixedAngle(mobj->info->speed); @@ -5341,21 +5349,20 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_SetThingPosition(mobj); } - // Was this so hard? if (mobj->target->player->bumpers <= mobj->threshold) { + // Sliently remove P_RemoveMobj(mobj); return; } } - else if ((mobj->health > 0 - && (!mobj->target || !mobj->target->player || !mobj->target->player->mo || mobj->target->health <= 0 || mobj->target->player->spectator)) - || (mobj->health <= 0 && P_IsObjectOnGround(mobj)) - || P_CheckDeathPitCollide(mobj)) // When in death state + else { + // Sliently remove P_RemoveMobj(mobj); return; } + break; case MT_PLAYERARROW: if (mobj->target && mobj->target->health @@ -10167,20 +10174,25 @@ void P_SpawnPlayer(INT32 playernum) P_SetScale(mobj, mobj->destscale); P_FlashPal(p, 0, 0); // Resets - if ((gametyperules & GTR_BUMPERS)) // SRB2kart + if (gametyperules & GTR_BUMPERS) { mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height + 16*FRACUNIT, MT_PLAYERARROW); P_SetTarget(&overheadarrow->target, mobj); overheadarrow->drawflags |= MFD_DONTDRAW; P_SetScale(overheadarrow, mobj->destscale); - if (p->spectator && pcount > 1) // HEY! No being cheap... - p->bumpers = 0; - else if (p->bumpers > 0 || leveltime < 1 - || (p->jointime <= 1 && pcount <= 1)) + if (p->spectator) { - if (leveltime < 1 || (p->jointime <= 1 && pcount <= 1)) // Start of the map? - p->bumpers = K_StartingBumperCount(); // Reset those bumpers! + // HEY! No being cheap... + p->bumpers = 0; + } + else if ((p->bumpers > 0) || (leveltime < starttime) || (pcount <= 1)) + { + if ((leveltime < starttime) || (pcount <= 1)) // Start of the map? + { + // Reset those bumpers! + p->bumpers = K_StartingBumperCount(); + } if (p->bumpers) { diff --git a/src/p_saveg.c b/src/p_saveg.c index 1b02f39a7..afc08ffdb 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -257,7 +257,7 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); WRITEUINT32(save_p, players[i].airtime); - WRITEINT16(save_p, players[i].bumpers); + WRITEUINT8(save_p, players[i].bumpers); WRITEINT16(save_p, players[i].karmadelay); WRITEUINT8(save_p, players[i].eliminated); @@ -447,7 +447,7 @@ static void P_NetUnArchivePlayers(void) players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p); players[i].airtime = READUINT32(save_p); - players[i].bumpers = READINT16(save_p); + players[i].bumpers = READUINT8(save_p); players[i].karmadelay = READINT16(save_p); players[i].eliminated = (boolean)READUINT8(save_p); From 42f411399aa42abcb6efb73d730a350e3b43175d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 15 Nov 2020 12:56:03 -0500 Subject: [PATCH 67/99] Add bumper explosion effect --- src/dehacked.c | 24 +++++++++++++++ src/info.c | 34 ++++++++++++++++++--- src/info.h | 26 ++++++++++++++++ src/k_kart.c | 4 --- src/p_inter.c | 53 ++++++++++++++++++++++++++------ src/p_mobj.c | 82 ++++++++++++++++++++++++++++++++++++++++---------- 6 files changed, 190 insertions(+), 33 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index ae9ab561a..e361bbc8e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8720,6 +8720,30 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BATTLEBUMPER2", "S_BATTLEBUMPER3", + "S_BATTLEBUMPER_EXCRYSTALA1", + "S_BATTLEBUMPER_EXCRYSTALA2", + "S_BATTLEBUMPER_EXCRYSTALA3", + "S_BATTLEBUMPER_EXCRYSTALA4", + + "S_BATTLEBUMPER_EXCRYSTALB1", + "S_BATTLEBUMPER_EXCRYSTALB2", + "S_BATTLEBUMPER_EXCRYSTALB3", + "S_BATTLEBUMPER_EXCRYSTALB4", + + "S_BATTLEBUMPER_EXCRYSTALC1", + "S_BATTLEBUMPER_EXCRYSTALC2", + "S_BATTLEBUMPER_EXCRYSTALC3", + "S_BATTLEBUMPER_EXCRYSTALC4", + + "S_BATTLEBUMPER_EXSHELLA1", + "S_BATTLEBUMPER_EXSHELLA2", + + "S_BATTLEBUMPER_EXSHELLB1", + "S_BATTLEBUMPER_EXSHELLB2", + + "S_BATTLEBUMPER_EXSHELLC1", + "S_BATTLEBUMPER_EXSHELLC2", + // DEZ respawn laser "S_DEZLASER", "S_DEZLASER_TRAIL1", diff --git a/src/info.c b/src/info.c index 5409bf41a..bedf6e69e 100644 --- a/src/info.c +++ b/src/info.c @@ -563,6 +563,8 @@ char sprnames[NUMSPRITES + 1][5] = "SINK", // Kitchen Sink "SITR", // Kitchen Sink Trail "KBLN", // Battle Mode Bumper + "BEXC", // Battle Bumper Explosion: Crystal + "BEXS", // Battle Bumper Explosion: Shell "DEZL", // DEZ Laser respawn @@ -4402,9 +4404,33 @@ state_t states[NUMSTATES] = {SPR_SITR, 1, 5, {NULL}, 0, 0, S_SINKTRAIL3}, // S_SINKTRAIL2 {SPR_SITR, 2, 3, {NULL}, 0, 0, S_NULL}, // S_SINKTRAIL3 - {SPR_KBLN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_BATTLEBUMPER1}, // S_BATTLEBUMPER1 - {SPR_KBLN, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_BATTLEBUMPER2}, // S_BATTLEBUMPER2 - {SPR_KBLN, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_BATTLEBUMPER3}, // S_BATTLEBUMPER3 + {SPR_KBLN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER1 + {SPR_KBLN, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER2 + {SPR_KBLN, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER3 + + {SPR_BEXC, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA2}, // S_BATTLEBUMPER_EXCRYSTALA1 + {SPR_BEXC, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA3}, // S_BATTLEBUMPER_EXCRYSTALA2 + {SPR_BEXC, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA4}, // S_BATTLEBUMPER_EXCRYSTALA3 + {SPR_BEXC, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA1}, // S_BATTLEBUMPER_EXCRYSTALA4 + + {SPR_BEXC, FF_SEMIBRIGHT|3, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB2}, // S_BATTLEBUMPER_EXCRYSTALB1 + {SPR_BEXC, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB3}, // S_BATTLEBUMPER_EXCRYSTALB2 + {SPR_BEXC, FF_SEMIBRIGHT|3, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB4}, // S_BATTLEBUMPER_EXCRYSTALB3 + {SPR_BEXC, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB1}, // S_BATTLEBUMPER_EXCRYSTALB4 + + {SPR_BEXC, FF_SEMIBRIGHT|6, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC2}, // S_BATTLEBUMPER_EXCRYSTALC1 + {SPR_BEXC, FF_FULLBRIGHT|7, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC3}, // S_BATTLEBUMPER_EXCRYSTALC2 + {SPR_BEXC, FF_SEMIBRIGHT|6, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC4}, // S_BATTLEBUMPER_EXCRYSTALC3 + {SPR_BEXC, FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC1}, // S_BATTLEBUMPER_EXCRYSTALC4 + + {SPR_BEXS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLA2}, // S_BATTLEBUMPER_EXSHELLA1 + {SPR_BEXS, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLA1}, // S_BATTLEBUMPER_EXSHELLA2 + + {SPR_BEXS, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLB2}, // S_BATTLEBUMPER_EXSHELLB1 + {SPR_BEXS, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLB1}, // S_BATTLEBUMPER_EXSHELLB2 + + {SPR_BEXS, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLC2}, // S_BATTLEBUMPER_EXSHELLC1 + {SPR_BEXS, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLC1}, // S_BATTLEBUMPER_EXSHELLC2 {SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER {SPR_DEZL, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL2}, // S_DEZLASER_TRAIL1 @@ -24061,7 +24087,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_BATTLEBUMPER_EXCRYSTALA1, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 4*FRACUNIT, // speed diff --git a/src/info.h b/src/info.h index 483706c90..84ea30757 100644 --- a/src/info.h +++ b/src/info.h @@ -834,6 +834,8 @@ typedef enum sprite SPR_SINK, // Kitchen Sink SPR_SITR, // Kitchen Sink Trail SPR_KBLN, // Battle Mode Bumper + SPR_BEXC, // Battle Bumper Explosion: Crystal + SPR_BEXS, // Battle Bumper Explosion: Shell SPR_DEZL, // DEZ Laser respawn @@ -4571,6 +4573,30 @@ typedef enum state S_BATTLEBUMPER2, S_BATTLEBUMPER3, + S_BATTLEBUMPER_EXCRYSTALA1, + S_BATTLEBUMPER_EXCRYSTALA2, + S_BATTLEBUMPER_EXCRYSTALA3, + S_BATTLEBUMPER_EXCRYSTALA4, + + S_BATTLEBUMPER_EXCRYSTALB1, + S_BATTLEBUMPER_EXCRYSTALB2, + S_BATTLEBUMPER_EXCRYSTALB3, + S_BATTLEBUMPER_EXCRYSTALB4, + + S_BATTLEBUMPER_EXCRYSTALC1, + S_BATTLEBUMPER_EXCRYSTALC2, + S_BATTLEBUMPER_EXCRYSTALC3, + S_BATTLEBUMPER_EXCRYSTALC4, + + S_BATTLEBUMPER_EXSHELLA1, + S_BATTLEBUMPER_EXSHELLA2, + + S_BATTLEBUMPER_EXSHELLB1, + S_BATTLEBUMPER_EXSHELLB2, + + S_BATTLEBUMPER_EXSHELLC1, + S_BATTLEBUMPER_EXSHELLC2, + // DEZ Laser respawn S_DEZLASER, S_DEZLASER_TRAIL1, diff --git a/src/k_kart.c b/src/k_kart.c index cf45256ac..e36845ef7 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2679,10 +2679,6 @@ void K_DestroyBumpers(player_t *player, UINT8 amount) } player->bumpers -= amount; - - // TODO: Store a bumperlist on the player mobj, - // that way we can do a bumper destruction animation - K_HandleBumperChanges(player, oldBumpers); } diff --git a/src/p_inter.c b/src/p_inter.c index 39dfe7404..29c4cb887 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1065,12 +1065,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget { mobj_t *mo; - //if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL)) - // P_SetTarget(&target->tracer, inflictor); - - if (G_IsSpecialStage(gamemap) && target->player && target->player->nightstime > 6) - target->player->nightstime = 6; // Just let P_Ticker take care of the rest. - if (target->flags & (MF_ENEMY|MF_BOSS)) target->momx = target->momy = target->momz = 0; @@ -1096,7 +1090,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SPECIAL); target->flags2 &= ~(MF2_SKULLFLY|MF2_NIGHTSPULL); target->health = 0; // This makes it easy to check if something's dead elsewhere. - target->shadowscale = 0; + + if (target->type != MT_BATTLEBUMPER) + { + target->shadowscale = 0; + } if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) return; @@ -1219,7 +1217,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } } - if ((gametyperules & GTR_BUMPERS)) + if (gametyperules & GTR_BUMPERS) K_CheckBumpers(); target->player->kartstuff[k_pogospring] = 0; @@ -1449,6 +1447,42 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } break; + case MT_BATTLEBUMPER: + { + mobj_t *owner = target->target; + mobj_t *overlay; + + target->flags &= ~MF_NOGRAVITY; + + target->destscale = (3 * target->destscale) / 2; + target->scalespeed = FRACUNIT/100; + + if (owner && !P_MobjWasRemoved(owner)) + { + /* + target->momx = owner->momx / 2; + target->momy = owner->momy / 2; + target->momz = owner->momz / 2; + */ + + P_Thrust(target, R_PointToAngle2(owner->x, owner->y, target->x, target->y), 4 * target->scale); + } + + target->momz += (24 * target->scale) * P_MobjFlip(target); + + target->shadowscale *= 3; + target->fuse = 16; + + overlay = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_OVERLAY); + + P_SetTarget(&target->tracer, overlay); + P_SetTarget(&overlay->target, target); + + overlay->color = target->color; + P_SetMobjState(overlay, S_BATTLEBUMPER_EXSHELLA1); + } + break; + default: break; } @@ -1685,11 +1719,12 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, return false; } + K_DestroyBumpers(player, 1); + switch (type) { case DMG_DEATHPIT: // Respawn kill types - K_DestroyBumpers(player, 1); K_DoIngameRespawn(player); return false; default: diff --git a/src/p_mobj.c b/src/p_mobj.c index 090977559..3c0df40fe 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1157,6 +1157,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) break; case MT_WATERDROP: case MT_CYBRAKDEMON: + case MT_BATTLEBUMPER: gravityadd /= 2; break; case MT_BANANA: @@ -1165,7 +1166,10 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_SINK: case MT_EMERALD: if (mo->extravalue2 > 0) + { gravityadd *= mo->extravalue2; + } + gravityadd = (5*gravityadd)/2; break; case MT_KARMAFIREWORK: @@ -5280,15 +5284,52 @@ static void P_MobjSceneryThink(mobj_t *mobj) case MT_BATTLEBUMPER: if (mobj->health <= 0) { - // DO EXPLODE ANIMATION HERE - //CONS_Printf("bumper explosion\n"); - P_RemoveMobj(mobj); - return; - } - else if (mobj->target && mobj->target->player && mobj->target->health > 0 && !mobj->target->player->spectator) - { - // Following a player + mobj->fuse--; + if (mobj->fuse <= 0) + { + statenum_t curState = (mobj->state - states); + + if (curState >= S_BATTLEBUMPER_EXCRYSTALA1 && curState <= S_BATTLEBUMPER_EXCRYSTALA4) + { + P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALB1); + + if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) + { + P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLB1); + } + + mobj->shadowscale *= 3; + mobj->fuse = 24; + break; + } + else if (curState >= S_BATTLEBUMPER_EXCRYSTALB1 && curState <= S_BATTLEBUMPER_EXCRYSTALB4) + { + P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALC1); + + if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) + { + P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLC1); + } + + mobj->shadowscale *= 3; + mobj->fuse = 32; + break; + } + else + { + // TODO: confetti goes here + P_RemoveMobj(mobj); + return; + } + } + + break; + } + + if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player + && mobj->target->health > 0 && !mobj->target->player->spectator) + { fixed_t rad = 32*mobj->target->scale; fixed_t offz; angle_t ang, diff; @@ -5320,15 +5361,23 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->drawflags = (mobj->target->drawflags & MFD_DONTDRAW); if (mobj->target->eflags & MFE_VERTICALFLIP) + { offz += 4*FRACUNIT; + } else + { offz -= 4*FRACUNIT; + } - if (mobj->tracer && mobj->tracer->player && mobj->tracer->player->mo + if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer) && mobj->tracer->player && mobj->tracer->health > 0 && !mobj->tracer->player->spectator) // STOLEN - mobj->color = mobj->tracer->player->skincolor; // don't do star flashing for stolen bumpers + { + mobj->color = mobj->tracer->color; + } else - mobj->color = mobj->target->color; // but do so if it belongs to you :B + { + mobj->color = mobj->target->color; + } if (mobj->target->player->bumpers < 2) P_SetMobjState(mobj, S_BATTLEBUMPER3); @@ -5338,11 +5387,11 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_SetMobjState(mobj, S_BATTLEBUMPER1); // Shrink your items if the player shrunk too. - mobj->scale = mobj->target->scale; + P_SetScale(mobj, mobj->target->scale); P_UnsetThingPosition(mobj); { - const angle_t fa = ang>>ANGLETOFINESHIFT; + const angle_t fa = ang >> ANGLETOFINESHIFT; mobj->x = mobj->target->x + FixedMul(FINECOSINE(fa), rad); mobj->y = mobj->target->y + FixedMul(FINESINE(fa), rad); mobj->z = mobj->target->z + offz; @@ -5351,9 +5400,9 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (mobj->target->player->bumpers <= mobj->threshold) { - // Sliently remove - P_RemoveMobj(mobj); - return; + // Do bumper destruction + P_KillMobj(mobj, NULL, NULL, DMG_NORMAL); + break; } } else @@ -8366,6 +8415,7 @@ static boolean P_FuseThink(mobj_t *mobj) if (mobj->threshold == 70) newmobj->threshold = 70; } + P_RemoveMobj(mobj); // make sure they disappear return false; case MT_SMK_ICEBLOCK: From 0882fe2b014fd389a2ad6231c1f287fcd14efb65 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 15 Nov 2020 12:59:05 -0500 Subject: [PATCH 68/99] Change overtime center hitbox --- src/info.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index bedf6e69e..d32980537 100644 --- a/src/info.c +++ b/src/info.c @@ -28333,8 +28333,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 48< Date: Sun, 15 Nov 2020 15:11:13 -0500 Subject: [PATCH 69/99] More finalized Chaos Emerald visuals --- src/dehacked.c | 116 ++++++++++++++++++++++++------------------------- src/doomdef.h | 8 ++++ src/info.c | 48 ++++++++++---------- src/info.h | 18 ++------ src/k_battle.c | 20 ++++++--- src/k_hud.c | 51 +++++++++++++++++----- 6 files changed, 145 insertions(+), 116 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index e361bbc8e..142a14efc 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6269,13 +6269,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EMBLEM26", // Chaos Emeralds - "S_EMERALD_CHAOS1", - "S_EMERALD_CHAOS2", - "S_EMERALD_CHAOS3", - "S_EMERALD_CHAOS4", - "S_EMERALD_CHAOS5", - "S_EMERALD_CHAOS6", - "S_EMERALD_CHAOS7", + "S_CHAOSEMERALD1", + "S_CHAOSEMERALD2", + "S_CHAOSEMERALD_UNDER", // Emerald hunt shards "S_SHRD1", @@ -10775,67 +10771,67 @@ static const char *COLOR_ENUMS[] = { // Rejigged for Kart. // Special super colors // Super Sonic Yellow - "SUPER1", // SKINCOLOR_SUPER1 - "SUPER2", // SKINCOLOR_SUPER2, - "SUPER3", // SKINCOLOR_SUPER3, - "SUPER4", // SKINCOLOR_SUPER4, - "SUPER5", // SKINCOLOR_SUPER5, + "SUPERSILVER1", + "SUPERSILVER2", + "SUPERSILVER3", + "SUPERSILVER4", + "SUPERSILVER5", - // Super Tails Orange - "TSUPER1", // SKINCOLOR_TSUPER1, - "TSUPER2", // SKINCOLOR_TSUPER2, - "TSUPER3", // SKINCOLOR_TSUPER3, - "TSUPER4", // SKINCOLOR_TSUPER4, - "TSUPER5", // SKINCOLOR_TSUPER5, + "SUPERRED1", + "SUPERRED2", + "SUPERRED3", + "SUPERRED4", + "SUPERRED5", - // Super Knuckles Red - "KSUPER1", // SKINCOLOR_KSUPER1, - "KSUPER2", // SKINCOLOR_KSUPER2, - "KSUPER3", // SKINCOLOR_KSUPER3, - "KSUPER4", // SKINCOLOR_KSUPER4, - "KSUPER5", // SKINCOLOR_KSUPER5, + "SUPERORANGE1", + "SUPERORANGE2", + "SUPERORANGE3", + "SUPERORANGE4", + "SUPERORANGE5", - // Hyper Sonic Pink - "PSUPER1", // SKINCOLOR_PSUPER1, - "PSUPER2", // SKINCOLOR_PSUPER2, - "PSUPER3", // SKINCOLOR_PSUPER3, - "PSUPER4", // SKINCOLOR_PSUPER4, - "PSUPER5", // SKINCOLOR_PSUPER5, + "SUPERGOLD1", + "SUPERGOLD2", + "SUPERGOLD3", + "SUPERGOLD4", + "SUPERGOLD5", - // Hyper Sonic Blue - "BSUPER1", // SKINCOLOR_BSUPER1, - "BSUPER2", // SKINCOLOR_BSUPER2, - "BSUPER3", // SKINCOLOR_BSUPER3, - "BSUPER4", // SKINCOLOR_BSUPER4, - "BSUPER5", // SKINCOLOR_BSUPER5, + "SUPERPERIDOT1", + "SUPERPERIDOT2", + "SUPERPERIDOT3", + "SUPERPERIDOT4", + "SUPERPERIDOT5", - // Aqua Super - "ASUPER1", // SKINCOLOR_ASUPER1, - "ASUPER2", // SKINCOLOR_ASUPER2, - "ASUPER3", // SKINCOLOR_ASUPER3, - "ASUPER4", // SKINCOLOR_ASUPER4, - "ASUPER5", // SKINCOLOR_ASUPER5, + "SUPERSKY1", + "SUPERSKY2", + "SUPERSKY3", + "SUPERSKY4", + "SUPERSKY5", - // Hyper Sonic Green - "GSUPER1", // SKINCOLOR_GSUPER1, - "GSUPER2", // SKINCOLOR_GSUPER2, - "GSUPER3", // SKINCOLOR_GSUPER3, - "GSUPER4", // SKINCOLOR_GSUPER4, - "GSUPER5", // SKINCOLOR_GSUPER5, + "SUPERPURPLE1", + "SUPERPURPLE2", + "SUPERPURPLE3", + "SUPERPURPLE4", + "SUPERPURPLE5", - // Hyper Sonic White - "WSUPER1", // SKINCOLOR_WSUPER1, - "WSUPER2", // SKINCOLOR_WSUPER2, - "WSUPER3", // SKINCOLOR_WSUPER3, - "WSUPER4", // SKINCOLOR_WSUPER4, - "WSUPER5", // SKINCOLOR_WSUPER5, + "SUPERRUST1", + "SUPERRUST2", + "SUPERRUST3", + "SUPERRUST4", + "SUPERRUST5", - // Creamy Super (Shadow?) - "CSUPER1", // SKINCOLOR_CSUPER1, - "CSUPER2", // SKINCOLOR_CSUPER2, - "CSUPER3", // SKINCOLOR_CSUPER3, - "CSUPER4", // SKINCOLOR_CSUPER4, - "CSUPER5" // SKINCOLOR_CSUPER5, + "SUPERTAN1", + "SUPERTAN2", + "SUPERTAN3", + "SUPERTAN4", + "SUPERTAN5", + + "CHAOSEMERALD1", + "CHAOSEMERALD2", + "CHAOSEMERALD3", + "CHAOSEMERALD4", + "CHAOSEMERALD5", + "CHAOSEMERALD6", + "CHAOSEMERALD7" }; static const char *const POWERS_LIST[] = { diff --git a/src/doomdef.h b/src/doomdef.h index c301640ad..c51cf4a5f 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -386,6 +386,14 @@ typedef enum SKINCOLOR_SUPERTAN4, SKINCOLOR_SUPERTAN5, + SKINCOLOR_CHAOSEMERALD1, + SKINCOLOR_CHAOSEMERALD2, + SKINCOLOR_CHAOSEMERALD3, + SKINCOLOR_CHAOSEMERALD4, + SKINCOLOR_CHAOSEMERALD5, + SKINCOLOR_CHAOSEMERALD6, + SKINCOLOR_CHAOSEMERALD7, + SKINCOLOR_FIRSTFREESLOT, SKINCOLOR_LASTFREESLOT = SKINCOLOR_FIRSTFREESLOT + NUMCOLORFREESLOTS - 1, diff --git a/src/info.c b/src/info.c index d32980537..2f9b1faf1 100644 --- a/src/info.c +++ b/src/info.c @@ -139,13 +139,7 @@ char sprnames[NUMSPRITES + 1][5] = "NCHP", // NiGHTS chip "NSTR", // NiGHTS star "EMBM", // Emblem - "EMC1", // Chaos Emeralds - "EMC2", - "EMC3", - "EMC4", - "EMC5", - "EMC6", - "EMC7", + "EMRC", // Chaos Emeralds "SHRD", // Emerald Hunt // Interactive Objects @@ -1907,13 +1901,9 @@ state_t states[NUMSTATES] = {SPR_EMBM, 25, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM26 // Chaos Emeralds - {SPR_EMC1, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS1 - {SPR_EMC2, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS2 - {SPR_EMC3, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS3 - {SPR_EMC4, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS4 - {SPR_EMC5, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS5 - {SPR_EMC6, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS6 - {SPR_EMC7, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS7 + {SPR_EMRC, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_CHAOSEMERALD2}, // S_CHAOSEMERALD1 + {SPR_EMRC, FF_FULLBRIGHT|FF_TRANSADD, 1, {NULL}, 0, 0, S_CHAOSEMERALD1}, // S_CHAOSEMERALD2 + {SPR_EMRC, FF_FULLBRIGHT|1, -1, {NULL}, 1, 0, S_NULL}, // S_CHAOSEMERALD_UNDER // Emerald hunt shards {SPR_SHRD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD1 @@ -3757,14 +3747,14 @@ state_t states[NUMSTATES] = {SPR_CAPS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGCAPSULE // Orbiting Chaos Emeralds/Ideya for NiGHTS - {SPR_EMC1, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1 - {SPR_EMC2, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2 - {SPR_EMC3, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3 - {SPR_EMC4, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM4}, // S_ORBITEM4 - {SPR_EMC5, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM5}, // S_ORBITEM5 - {SPR_EMC6, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 - {SPR_EMC7, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 - {SPR_EMC1, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM4}, // S_ORBITEM4 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM5}, // S_ORBITEM5 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA1}, // S_ORBIDYA1 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA2}, // S_ORBIDYA2 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA3}, // S_ORBIDYA3 @@ -8237,7 +8227,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_EMERALD -1, // doomednum - S_EMERALD_CHAOS1, // spawnstate + S_CHAOSEMERALD1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -18960,7 +18950,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_GOTEMERALD -1, // doomednum - S_EMERALD_CHAOS1, // spawnstate + S_CHAOSEMERALD1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -28805,7 +28795,15 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Super Tan 2", {0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5}, SKINCOLOR_BROWN, 13, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN2 {"Super Tan 3", {0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9}, SKINCOLOR_BROWN, 12, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN3 {"Super Tan 4", {0x51, 0x52, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed}, SKINCOLOR_BROWN, 11, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN4 - {"Super Tan 5", {0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef}, SKINCOLOR_BROWN, 10, V_BROWNMAP, false} // SKINCOLOR_SUPERTAN5 + {"Super Tan 5", {0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef}, SKINCOLOR_BROWN, 10, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN5 + + {"Chaos Emerald 1", { 0, 88, 188, 98, 114, 116, 117, 119, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD1 + {"Chaos Emerald 2", { 0, 80, 82, 74, 65, 52, 56, 60, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD2 + {"Chaos Emerald 3", { 0, 252, 201, 179, 182, 183, 185, 187, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD3 + {"Chaos Emerald 4", { 0, 144, 146, 147, 149, 165, 167, 169, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD4 + {"Chaos Emerald 5", { 0, 1, 144, 4, 9, 170, 14, 21, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD5 + {"Chaos Emerald 6", { 0, 208, 50, 32, 34, 37, 40, 44, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD6 + {"Chaos Emerald 7", { 0, 120, 121, 140, 133, 135, 149, 156, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false} // SKINCOLOR_CHAOSEMERALD7 }; /** Patches the mobjinfo, state, and skincolor tables. diff --git a/src/info.h b/src/info.h index 84ea30757..1bcd03b56 100644 --- a/src/info.h +++ b/src/info.h @@ -410,13 +410,7 @@ typedef enum sprite SPR_NCHP, // NiGHTS chip SPR_NSTR, // NiGHTS star SPR_EMBM, // Emblem - SPR_EMC1, // Chaos Emeralds - SPR_EMC2, - SPR_EMC3, - SPR_EMC4, - SPR_EMC5, - SPR_EMC6, - SPR_EMC7, + SPR_EMRC, // Chaos Emeralds SPR_SHRD, // Emerald Hunt // Interactive Objects @@ -2122,13 +2116,9 @@ typedef enum state S_EMBLEM26, // Chaos Emeralds - S_EMERALD_CHAOS1, - S_EMERALD_CHAOS2, - S_EMERALD_CHAOS3, - S_EMERALD_CHAOS4, - S_EMERALD_CHAOS5, - S_EMERALD_CHAOS6, - S_EMERALD_CHAOS7, + S_CHAOSEMERALD1, + S_CHAOSEMERALD2, + S_CHAOSEMERALD_UNDER, // Emerald hunt shards S_SHRD1, diff --git a/src/k_battle.c b/src/k_battle.c index a9924b1de..1f0db486c 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -308,6 +308,7 @@ mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 em { boolean validEmerald = true; mobj_t *emerald = P_SpawnMobjFromMobj(parent, 0, 0, 0, MT_EMERALD); + mobj_t *overlay; P_Thrust(emerald, FixedAngle(P_RandomFixed() * 180) + angle, @@ -322,25 +323,25 @@ mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 em switch (emeraldType) { case EMERALD_CHAOS1: - P_SetMobjState(emerald, S_EMERALD_CHAOS1); + emerald->color = SKINCOLOR_CHAOSEMERALD1; break; case EMERALD_CHAOS2: - P_SetMobjState(emerald, S_EMERALD_CHAOS2); + emerald->color = SKINCOLOR_CHAOSEMERALD2; break; case EMERALD_CHAOS3: - P_SetMobjState(emerald, S_EMERALD_CHAOS3); + emerald->color = SKINCOLOR_CHAOSEMERALD3; break; case EMERALD_CHAOS4: - P_SetMobjState(emerald, S_EMERALD_CHAOS4); + emerald->color = SKINCOLOR_CHAOSEMERALD4; break; case EMERALD_CHAOS5: - P_SetMobjState(emerald, S_EMERALD_CHAOS5); + emerald->color = SKINCOLOR_CHAOSEMERALD5; break; case EMERALD_CHAOS6: - P_SetMobjState(emerald, S_EMERALD_CHAOS6); + emerald->color = SKINCOLOR_CHAOSEMERALD6; break; case EMERALD_CHAOS7: - P_SetMobjState(emerald, S_EMERALD_CHAOS7); + emerald->color = SKINCOLOR_CHAOSEMERALD7; break; default: CONS_Printf("Invalid emerald type %d\n", emeraldType); @@ -353,6 +354,11 @@ mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 em emerald->extravalue1 = emeraldType; } + overlay = P_SpawnMobjFromMobj(emerald, 0, 0, 0, MT_OVERLAY); + P_SetTarget(&overlay->target, emerald); + P_SetMobjState(overlay, S_CHAOSEMERALD_UNDER); + overlay->color = emerald->color; + return emerald; } diff --git a/src/k_hud.c b/src/k_hud.c index 330bfb8fe..dac19ffa6 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -88,7 +88,7 @@ static patch_t *kp_rankbumper; static patch_t *kp_tinybumper[2]; static patch_t *kp_ranknobumpers; static patch_t *kp_rankcapsule; -static patch_t *kp_rankemeralds[7]; +static patch_t *kp_rankemerald; static patch_t *kp_battlewin; static patch_t *kp_battlecool; @@ -351,13 +351,7 @@ void K_LoadKartHUDGraphics(void) kp_tinybumper[1] = W_CachePatchName("K_BLNB", PU_HUDGFX); kp_ranknobumpers = W_CachePatchName("K_NOBLNS", PU_HUDGFX); kp_rankcapsule = W_CachePatchName("K_CAPICO", PU_HUDGFX); - - sprintf(buffer, "K_EMERCx"); - for (i = 0; i < 7; i++) - { - buffer[7] = '0'+(i+1); - kp_rankemeralds[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); - } + kp_rankemerald = W_CachePatchName("K_EMERC", PU_HUDGFX); // Battle graphics kp_battlewin = W_CachePatchName("K_BWIN", PU_HUDGFX); @@ -1633,10 +1627,12 @@ static boolean K_drawKartPositionFaces(void) for (j = 0; j < 7; j++) { UINT32 emeraldFlag = (1 << j); + UINT16 emeraldColor = SKINCOLOR_CHAOSEMERALD1 + j; if (players[rankplayer[i]].powers[pw_emeralds] & emeraldFlag) { - V_DrawScaledPatch(emeraldx, Y+7, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_rankemeralds[j]); + colormap = R_GetTranslationColormap(TC_DEFAULT, emeraldColor, GTC_CACHE); + V_DrawMappedPatch(emeraldx, Y+7, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_rankemerald, colormap); emeraldx += 7; } } @@ -1661,6 +1657,41 @@ static boolean K_drawKartPositionFaces(void) return false; } +static void K_drawKartEmeralds(void) +{ + static const INT32 emeraldOffsets[7][2] = { + {27, 0}, + {18, 15}, + {36, 15}, + {9, 0}, + {45, 0}, + {0, 15}, + {54, 15} + }; + + const INT32 startx = BASEVIDWIDTH - 88; + const INT32 starty = BASEVIDHEIGHT - 32; + + UINT8 *colormap; + INT32 i; + + for (i = 0; i < 7; i++) + { + UINT32 emeraldFlag = (1 << i); + UINT16 emeraldColor = SKINCOLOR_CHAOSEMERALD1 + i; + + if (stplyr->powers[pw_emeralds] & emeraldFlag) + { + colormap = R_GetTranslationColormap(TC_DEFAULT, emeraldColor, GTC_CACHE); + V_DrawMappedPatch( + startx + emeraldOffsets[i][0], starty + emeraldOffsets[i][1], + V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, + kp_rankemerald, colormap + ); + } + } +} + // // HU_DrawTabRankings -- moved here to take advantage of kart stuff! // @@ -4137,6 +4168,6 @@ void K_drawKartHUD(void) if (gametype == GT_BATTLE) { - V_DrawRightAlignedString(BASEVIDWIDTH - 10, BASEVIDHEIGHT - 18, V_SPLITSCREEN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, va("Emeralds: %d / 7", K_NumEmeralds(stplyr))); + K_drawKartEmeralds(); } } From 0db31e0fcd3d616e3758535a4fba80e51e3e3879 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 00:17:40 -0500 Subject: [PATCH 70/99] HUD polish - Emeralds have background & white flashing - Blue sphere meter has shading - V_SLIDEIN works off of lt_exitticker instead of introtime --- src/k_hud.c | 55 ++++++++++++++++++++++++++++++++++++-------------- src/st_stuff.c | 6 ++---- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index dac19ffa6..43c3718a1 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -89,6 +89,8 @@ static patch_t *kp_tinybumper[2]; static patch_t *kp_ranknobumpers; static patch_t *kp_rankcapsule; static patch_t *kp_rankemerald; +static patch_t *kp_rankemeraldflash; +static patch_t *kp_rankemeraldback; static patch_t *kp_battlewin; static patch_t *kp_battlecool; @@ -352,6 +354,8 @@ void K_LoadKartHUDGraphics(void) kp_ranknobumpers = W_CachePatchName("K_NOBLNS", PU_HUDGFX); kp_rankcapsule = W_CachePatchName("K_CAPICO", PU_HUDGFX); kp_rankemerald = W_CachePatchName("K_EMERC", PU_HUDGFX); + kp_rankemeraldflash = W_CachePatchName("K_EMERW", PU_HUDGFX); + kp_rankemeraldback = W_CachePatchName("K_EMERBK", PU_HUDGFX); // Battle graphics kp_battlewin = W_CachePatchName("K_BWIN", PU_HUDGFX); @@ -733,11 +737,12 @@ void K_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du if (options & V_SLIDEIN) { - tic_t length = TICRATE/2; + const tic_t length = TICRATE/2; + const tic_t end = (lt_endtime + length); - if (leveltime < introtime + length) + if (lt_ticker < end) { - INT32 offset = screenwidth - (((leveltime - introtime) * screenwidth) / length); + INT32 offset = screenwidth - ((lt_exitticker * screenwidth) / length); boolean slidefromright = false; if (r_splitscreen > 1) @@ -1660,21 +1665,22 @@ static boolean K_drawKartPositionFaces(void) static void K_drawKartEmeralds(void) { static const INT32 emeraldOffsets[7][2] = { - {27, 0}, - {18, 15}, - {36, 15}, - {9, 0}, - {45, 0}, - {0, 15}, - {54, 15} + {34, 0}, + {25, 8}, + {43, 8}, + {16, 0}, + {52, 0}, + {7, 8}, + {61, 8} }; - const INT32 startx = BASEVIDWIDTH - 88; - const INT32 starty = BASEVIDHEIGHT - 32; + const INT32 startx = BASEVIDWIDTH - 77 - 8; + const INT32 starty = BASEVIDHEIGHT - 29 - 8; - UINT8 *colormap; INT32 i; + V_DrawScaledPatch(startx, starty, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, kp_rankemeraldback); + for (i = 0; i < 7; i++) { UINT32 emeraldFlag = (1 << i); @@ -1682,12 +1688,29 @@ static void K_drawKartEmeralds(void) if (stplyr->powers[pw_emeralds] & emeraldFlag) { + boolean whiteFlash = (leveltime & 1); + UINT8 *colormap; + + if (i & 1) + { + whiteFlash = !whiteFlash; + } + colormap = R_GetTranslationColormap(TC_DEFAULT, emeraldColor, GTC_CACHE); V_DrawMappedPatch( startx + emeraldOffsets[i][0], starty + emeraldOffsets[i][1], V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, kp_rankemerald, colormap ); + + if (whiteFlash == true) + { + V_DrawScaledPatch( + startx + emeraldOffsets[i][0], starty + emeraldOffsets[i][1], + V_HUDTRANSHALF|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, + kp_rankemeraldflash + ); + } } } } @@ -2051,7 +2074,7 @@ static void K_drawBlueSphereMeter(void) const UINT8 sphere = max(min(stplyr->spheres, 40), 0); UINT8 numBars = min((sphere / 10), maxBars); - UINT8 color = segColors[(sphere * sizeof(segColors)) / (40 + 1)]; + UINT8 colorIndex = (sphere * sizeof(segColors)) / (40 + 1); INT32 x = LAPS_X + 25; UINT8 i; @@ -2066,7 +2089,9 @@ static void K_drawBlueSphereMeter(void) segLen = (sphere % 10); } - V_DrawFill(x, LAPS_Y - 16, segLen, 6, color | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN); + V_DrawFill(x, LAPS_Y - 16, segLen, 3, segColors[max(colorIndex-1, 0)] | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN); + V_DrawFill(x, LAPS_Y - 15, segLen, 1, segColors[max(colorIndex-2, 0)] | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN); + V_DrawFill(x, LAPS_Y - 13, segLen, 3, segColors[colorIndex] | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN); x += 15; } diff --git a/src/st_stuff.c b/src/st_stuff.c index a8e7d2434..d6f80a9f5 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -673,10 +673,8 @@ void ST_preDrawTitleCard(void) if (lt_ticker >= (lt_endtime + TICRATE)) return; - if (!lt_exitticker) - st_translucency = 0; - else - st_translucency = max(0, min((INT32)lt_exitticker-4, cv_translucenthud.value)); + // Kart: nothing + st_translucency = cv_translucenthud.value; } // From ae5d5abe245a7e6d7edcc74c8e46e095cb11f9d5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 00:51:00 -0500 Subject: [PATCH 71/99] Chaos Emeralds now sparkle --- src/dehacked.c | 9 +++++++++ src/info.c | 40 ++++++++++++++++++++++++++++++++++++++-- src/info.h | 10 ++++++++++ src/p_mobj.c | 16 ++++++++++++++++ 4 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 142a14efc..23359b705 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6273,6 +6273,14 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_CHAOSEMERALD2", "S_CHAOSEMERALD_UNDER", + "S_EMERALDSPARK1", + "S_EMERALDSPARK2", + "S_EMERALDSPARK3", + "S_EMERALDSPARK4", + "S_EMERALDSPARK5", + "S_EMERALDSPARK6", + "S_EMERALDSPARK7", + // Emerald hunt shards "S_SHRD1", "S_SHRD2", @@ -9523,6 +9531,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_BLUEFLAG", // Blue CTF Flag "MT_EMBLEM", "MT_EMERALD", + "MT_EMERALDSPARK", "MT_EMERHUNT", // Emerald Hunt "MT_EMERALDSPAWN", // Emerald spawner w/ delay diff --git a/src/info.c b/src/info.c index 2f9b1faf1..4331e66b0 100644 --- a/src/info.c +++ b/src/info.c @@ -140,6 +140,7 @@ char sprnames[NUMSPRITES + 1][5] = "NSTR", // NiGHTS star "EMBM", // Emblem "EMRC", // Chaos Emeralds + "ESPK", "SHRD", // Emerald Hunt // Interactive Objects @@ -1901,10 +1902,18 @@ state_t states[NUMSTATES] = {SPR_EMBM, 25, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM26 // Chaos Emeralds - {SPR_EMRC, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_CHAOSEMERALD2}, // S_CHAOSEMERALD1 + {SPR_EMRC, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_CHAOSEMERALD2}, // S_CHAOSEMERALD1 {SPR_EMRC, FF_FULLBRIGHT|FF_TRANSADD, 1, {NULL}, 0, 0, S_CHAOSEMERALD1}, // S_CHAOSEMERALD2 {SPR_EMRC, FF_FULLBRIGHT|1, -1, {NULL}, 1, 0, S_NULL}, // S_CHAOSEMERALD_UNDER + {SPR_ESPK, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EMERALDSPARK2}, // S_EMERALDSPARK1 + {SPR_ESPK, FF_FULLBRIGHT|1, 3, {NULL}, 0, 0, S_EMERALDSPARK3}, // S_EMERALDSPARK2 + {SPR_ESPK, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_EMERALDSPARK4}, // S_EMERALDSPARK3 + {SPR_ESPK, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_EMERALDSPARK5}, // S_EMERALDSPARK4 + {SPR_ESPK, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_EMERALDSPARK6}, // S_EMERALDSPARK5 + {SPR_ESPK, FF_FULLBRIGHT|5, 3, {NULL}, 0, 0, S_EMERALDSPARK7}, // S_EMERALDSPARK6 + {SPR_ESPK, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_NULL}, // S_EMERALDSPARK7 + // Emerald hunt shards {SPR_SHRD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD1 {SPR_SHRD, 1, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD2 @@ -8248,7 +8257,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_PICKUPFROMBELOW, // flags + MF_SPECIAL|MF_PICKUPFROMBELOW|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_EMERALDSPARK + -1, // doomednum + S_EMERALDSPARK1,// 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 + 0, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, diff --git a/src/info.h b/src/info.h index 1bcd03b56..d5946e8e6 100644 --- a/src/info.h +++ b/src/info.h @@ -411,6 +411,7 @@ typedef enum sprite SPR_NSTR, // NiGHTS star SPR_EMBM, // Emblem SPR_EMRC, // Chaos Emeralds + SPR_ESPK, SPR_SHRD, // Emerald Hunt // Interactive Objects @@ -2120,6 +2121,14 @@ typedef enum state S_CHAOSEMERALD2, S_CHAOSEMERALD_UNDER, + S_EMERALDSPARK1, + S_EMERALDSPARK2, + S_EMERALDSPARK3, + S_EMERALDSPARK4, + S_EMERALDSPARK5, + S_EMERALDSPARK6, + S_EMERALDSPARK7, + // Emerald hunt shards S_SHRD1, S_SHRD2, @@ -5410,6 +5419,7 @@ typedef enum mobj_type MT_BLUEFLAG, // Blue CTF Flag MT_EMBLEM, MT_EMERALD, + MT_EMERALDSPARK, MT_EMERHUNT, // Emerald Hunt MT_EMERALDSPAWN, // Emerald spawner w/ delay diff --git a/src/p_mobj.c b/src/p_mobj.c index 3c0df40fe..0b0661a60 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6460,7 +6460,23 @@ static boolean P_MobjRegularThink(mobj_t *mobj) break; case MT_EMERALD: if (mobj->threshold > 0) + { mobj->threshold--; + } + + if (leveltime % 3 == 0) + { + mobj_t *sparkle = P_SpawnMobjFromMobj( + mobj, + P_RandomRange(-48, 48) * FRACUNIT, + P_RandomRange(-48, 48) * FRACUNIT, + P_RandomRange(0, 64) * FRACUNIT, + MT_EMERALDSPARK + ); + + sparkle->color = mobj->color; + sparkle->momz += 8 * mobj->scale * P_MobjFlip(mobj); + } break; case MT_DRIFTEXPLODE: if (!mobj->target || !mobj->target->health) From 8c5abf41ea700abef567cca862b6cae0fb23dadd Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 01:20:55 -0500 Subject: [PATCH 72/99] Bumper destruction starts with the normal bumper sprite before transitioning into the giant bumper --- src/info.c | 2 +- src/p_inter.c | 6 ++---- src/p_mobj.c | 18 +++++++++++++++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/info.c b/src/info.c index 4331e66b0..e9376c607 100644 --- a/src/info.c +++ b/src/info.c @@ -24113,7 +24113,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BATTLEBUMPER_EXCRYSTALA1, // deathstate + S_BATTLEBUMPER1, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 4*FRACUNIT, // speed diff --git a/src/p_inter.c b/src/p_inter.c index 29c4cb887..3a97433a1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1469,9 +1469,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } target->momz += (24 * target->scale) * P_MobjFlip(target); - - target->shadowscale *= 3; - target->fuse = 16; + target->fuse = 8; overlay = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_OVERLAY); @@ -1479,7 +1477,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget P_SetTarget(&overlay->target, target); overlay->color = target->color; - P_SetMobjState(overlay, S_BATTLEBUMPER_EXSHELLA1); + P_SetMobjState(overlay, S_INVISIBLE); } break; diff --git a/src/p_mobj.c b/src/p_mobj.c index 0b0661a60..348059be3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5290,7 +5290,19 @@ static void P_MobjSceneryThink(mobj_t *mobj) { statenum_t curState = (mobj->state - states); - if (curState >= S_BATTLEBUMPER_EXCRYSTALA1 && curState <= S_BATTLEBUMPER_EXCRYSTALA4) + if (curState == S_BATTLEBUMPER1) + { + P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALA1); + + if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) + { + P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLA1); + } + + mobj->shadowscale *= 2; + mobj->fuse = 12; + } + else if (curState >= S_BATTLEBUMPER_EXCRYSTALA1 && curState <= S_BATTLEBUMPER_EXCRYSTALA4) { P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALB1); @@ -5299,7 +5311,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLB1); } - mobj->shadowscale *= 3; + mobj->shadowscale *= 2; mobj->fuse = 24; break; } @@ -5312,7 +5324,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLC1); } - mobj->shadowscale *= 3; + mobj->shadowscale *= 2; mobj->fuse = 32; break; } From 0dc567973c1f2dd5946889ec59e8cb927a1fcc6e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 01:29:09 -0500 Subject: [PATCH 73/99] Overtime: Chaos Emeralds get deleted by the barrier, and respawn in the middle --- src/k_battle.c | 120 +++++++++++++++++++++++++++++++------------------ src/k_battle.h | 2 +- src/p_mobj.c | 39 ++++++++++------ 3 files changed, 103 insertions(+), 58 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index 1f0db486c..84ac61b62 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -304,10 +304,10 @@ void K_CheckEmeralds(player_t *player) K_CheckBumpers(); } -mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType) +mobj_t *K_SpawnChaosEmerald(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT32 emeraldType) { boolean validEmerald = true; - mobj_t *emerald = P_SpawnMobjFromMobj(parent, 0, 0, 0, MT_EMERALD); + mobj_t *emerald = P_SpawnMobj(x, y, z, MT_EMERALD); mobj_t *overlay; P_Thrust(emerald, @@ -373,7 +373,7 @@ void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType) if ((player->powers[pw_emeralds] & emeraldFlag) && (emeraldFlag & emeraldType)) { - mobj_t *emerald = K_SpawnChaosEmerald(player->mo, player->mo->angle - ANGLE_90, flip, emeraldFlag); + mobj_t *emerald = K_SpawnChaosEmerald(player->mo->x, player->mo->y, player->mo->z, player->mo->angle - ANGLE_90, flip, emeraldFlag); P_SetTarget(&emerald->target, player->mo); player->powers[pw_emeralds] &= ~emeraldFlag; @@ -403,7 +403,15 @@ void K_RunPaperItemSpawners(void) { const boolean overtime = (battleovertime.enabled >= 10*TICRATE); tic_t interval = 8*TICRATE; + UINT32 emeraldsSpawned = 0; + UINT32 firstUnspawnedEmerald = 0; + + thinker_t *th; + mobj_t *mo; + + UINT8 pcount = 0; + INT16 i; if (leveltime < starttime) { @@ -411,19 +419,16 @@ void K_RunPaperItemSpawners(void) return; } - if ((battleovertime.enabled > 0) && (battleovertime.radius < 256*mapobjectscale)) - { - // Barrier has closed in too much - return; - } - if (overtime == true) { + if (battleovertime.radius < 512*mapobjectscale) + { + // Barrier has closed in too much + return; + } + // Double frequency of items interval /= 2; - - // Even if this isn't true, we pretend it is, because it's too late to do anything about it :p - emeraldsSpawned = EMERALD_ALLCHAOS; } if (((leveltime - starttime) % interval) != 0) @@ -431,39 +436,72 @@ void K_RunPaperItemSpawners(void) return; } + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + { + continue; + } + + emeraldsSpawned |= players[i].powers[pw_emeralds]; + + if ((players[i].exiting > 0 || players[i].eliminated) + || ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0)) + { + continue; + } + + pcount++; + } + if (overtime == true) { SINT8 flip = 1; - K_CreatePaperItem( - battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip), - FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, - 0, 0 - ); + // Just find emeralds, no paper spots + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo = (mobj_t *)th; + + if (mo->type == MT_EMERALD) + { + emeraldsSpawned |= mo->extravalue1; + } + } + + for (i = 0; i < 7; i++) + { + UINT32 emeraldFlag = (1 << i); + + if (!(emeraldsSpawned & emeraldFlag)) + { + firstUnspawnedEmerald = emeraldFlag; + break; + } + } + + if (firstUnspawnedEmerald != 0) + { + K_SpawnChaosEmerald( + battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip), + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + firstUnspawnedEmerald + ); + } + else + { + K_CreatePaperItem( + battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip), + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + 0, 0 + ); + } } else { - UINT8 pcount = 0; - INT16 i; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - { - continue; - } - - emeraldsSpawned |= players[i].powers[pw_emeralds]; - - if ((players[i].exiting > 0 || players[i].eliminated) - || ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0)) - { - continue; - } - - pcount++; - } - if (pcount > 0) { #define MAXITEM 64 @@ -471,12 +509,8 @@ void K_RunPaperItemSpawners(void) mobj_t *spotList[MAXITEM]; boolean spotUsed[MAXITEM]; - UINT32 firstUnspawnedEmerald = 0; INT16 starti = 0; - thinker_t *th; - mobj_t *mo; - memset(spotUsed, false, sizeof(spotUsed)); for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) @@ -541,7 +575,7 @@ void K_RunPaperItemSpawners(void) if (i == -1) { drop = K_SpawnChaosEmerald( - spotList[r], + spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip), FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, firstUnspawnedEmerald ); diff --git a/src/k_battle.h b/src/k_battle.h index ddd8a5437..4b1508cbf 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -21,7 +21,7 @@ void K_CalculateBattleWanted(void); void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); void K_CheckBumpers(void); void K_CheckEmeralds(player_t *player); -mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType); +mobj_t *K_SpawnChaosEmerald(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT32 emeraldType); void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType); UINT8 K_NumEmeralds(player_t *player); void K_RunPaperItemSpawners(void); diff --git a/src/p_mobj.c b/src/p_mobj.c index 348059be3..dd69a9036 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6471,23 +6471,34 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->health--; break; case MT_EMERALD: - if (mobj->threshold > 0) { - mobj->threshold--; - } + if (battleovertime.enabled >= 10*TICRATE) + { + fixed_t distance = R_PointToDist2(mobj->x, mobj->y, battleovertime.x, battleovertime.y); - if (leveltime % 3 == 0) - { - mobj_t *sparkle = P_SpawnMobjFromMobj( - mobj, - P_RandomRange(-48, 48) * FRACUNIT, - P_RandomRange(-48, 48) * FRACUNIT, - P_RandomRange(0, 64) * FRACUNIT, - MT_EMERALDSPARK - ); + if (distance > battleovertime.radius) + { + // Delete emeralds to let them reappear + P_KillMobj(mobj, NULL, NULL, DMG_NORMAL); + } + } - sparkle->color = mobj->color; - sparkle->momz += 8 * mobj->scale * P_MobjFlip(mobj); + if (leveltime % 3 == 0) + { + mobj_t *sparkle = P_SpawnMobjFromMobj( + mobj, + P_RandomRange(-48, 48) * FRACUNIT, + P_RandomRange(-48, 48) * FRACUNIT, + P_RandomRange(0, 64) * FRACUNIT, + MT_EMERALDSPARK + ); + + sparkle->color = mobj->color; + sparkle->momz += 8 * mobj->scale * P_MobjFlip(mobj); + } + + if (mobj->threshold > 0) + mobj->threshold--; } break; case MT_DRIFTEXPLODE: From ef0da6ce9cca3ad1b4682c7e1f120a81245a5e31 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 02:38:13 -0500 Subject: [PATCH 74/99] Finished bumper destruction --- src/dehacked.c | 16 ++++++++++++ src/info.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/info.h | 18 +++++++++++++ src/p_mobj.c | 57 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 160 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 23359b705..b04ccd92f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8748,6 +8748,20 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BATTLEBUMPER_EXSHELLC1", "S_BATTLEBUMPER_EXSHELLC2", + "S_BATTLEBUMPER_EXDEBRIS1", + "S_BATTLEBUMPER_EXDEBRIS2", + + "S_BATTLEBUMPER_EXBLAST1", + "S_BATTLEBUMPER_EXBLAST2", + "S_BATTLEBUMPER_EXBLAST3", + "S_BATTLEBUMPER_EXBLAST4", + "S_BATTLEBUMPER_EXBLAST5", + "S_BATTLEBUMPER_EXBLAST6", + "S_BATTLEBUMPER_EXBLAST7", + "S_BATTLEBUMPER_EXBLAST8", + "S_BATTLEBUMPER_EXBLAST9", + "S_BATTLEBUMPER_EXBLAST10", + // DEZ respawn laser "S_DEZLASER", "S_DEZLASER_TRAIL1", @@ -10228,6 +10242,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_SINKTRAIL", "MT_BATTLEBUMPER", // Battle Mode bumper + "MT_BATTLEBUMPER_DEBRIS", + "MT_BATTLEBUMPER_BLAST", "MT_DEZLASER", diff --git a/src/info.c b/src/info.c index e9376c607..ae7e58b8e 100644 --- a/src/info.c +++ b/src/info.c @@ -560,6 +560,8 @@ char sprnames[NUMSPRITES + 1][5] = "KBLN", // Battle Mode Bumper "BEXC", // Battle Bumper Explosion: Crystal "BEXS", // Battle Bumper Explosion: Shell + "BDEB", // Battle Bumper Explosion: Debris + "BEXB", // Battle Bumper Explosion: Blast "DEZL", // DEZ Laser respawn @@ -4431,6 +4433,20 @@ state_t states[NUMSTATES] = {SPR_BEXS, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLC2}, // S_BATTLEBUMPER_EXSHELLC1 {SPR_BEXS, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLC1}, // S_BATTLEBUMPER_EXSHELLC2 + {SPR_BDEB, FF_FULLBRIGHT|FF_ANIMATE, 84, {NULL}, 13, 6, S_BATTLEBUMPER_EXDEBRIS2}, // S_BATTLEBUMPER_EXDEBRIS1 + {SPR_BDEB, FF_FULLBRIGHT|13, 20, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER_EXDEBRIS2 + + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST2}, // S_BATTLEBUMPER_EXBLAST1 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS10, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST3}, // S_BATTLEBUMPER_EXBLAST2 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS20, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST4}, // S_BATTLEBUMPER_EXBLAST3 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS30, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST5}, // S_BATTLEBUMPER_EXBLAST4 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS40, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST6}, // S_BATTLEBUMPER_EXBLAST5 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS50, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST7}, // S_BATTLEBUMPER_EXBLAST6 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS60, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST8}, // S_BATTLEBUMPER_EXBLAST7 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS70, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST9}, // S_BATTLEBUMPER_EXBLAST8 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS80, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST10}, // S_BATTLEBUMPER_EXBLAST9 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS90, 2, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER_EXBLAST10 + {SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER {SPR_DEZL, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL2}, // S_DEZLASER_TRAIL1 {SPR_DEZL, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL3}, // S_DEZLASER_TRAIL2 @@ -24127,6 +24143,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_BATTLEBUMPER_DEBRIS + -1, // doomednum + S_BATTLEBUMPER_EXDEBRIS1,// 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 + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_BATTLEBUMPER_BLAST + -1, // doomednum + S_BATTLEBUMPER_EXBLAST1, // 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 + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_DEZLASER -1, // doomednum S_DEZLASER, // spawnstate diff --git a/src/info.h b/src/info.h index d5946e8e6..d51267587 100644 --- a/src/info.h +++ b/src/info.h @@ -831,6 +831,8 @@ typedef enum sprite SPR_KBLN, // Battle Mode Bumper SPR_BEXC, // Battle Bumper Explosion: Crystal SPR_BEXS, // Battle Bumper Explosion: Shell + SPR_BDEB, // Battle Bumper Explosion: Debris + SPR_BEXB, // Battle Bumper Explosion: Blast SPR_DEZL, // DEZ Laser respawn @@ -4596,6 +4598,20 @@ typedef enum state S_BATTLEBUMPER_EXSHELLC1, S_BATTLEBUMPER_EXSHELLC2, + S_BATTLEBUMPER_EXDEBRIS1, + S_BATTLEBUMPER_EXDEBRIS2, + + S_BATTLEBUMPER_EXBLAST1, + S_BATTLEBUMPER_EXBLAST2, + S_BATTLEBUMPER_EXBLAST3, + S_BATTLEBUMPER_EXBLAST4, + S_BATTLEBUMPER_EXBLAST5, + S_BATTLEBUMPER_EXBLAST6, + S_BATTLEBUMPER_EXBLAST7, + S_BATTLEBUMPER_EXBLAST8, + S_BATTLEBUMPER_EXBLAST9, + S_BATTLEBUMPER_EXBLAST10, + // DEZ Laser respawn S_DEZLASER, S_DEZLASER_TRAIL1, @@ -6116,6 +6132,8 @@ typedef enum mobj_type MT_SINKTRAIL, MT_BATTLEBUMPER, // Battle Mode bumpers + MT_BATTLEBUMPER_DEBRIS, + MT_BATTLEBUMPER_BLAST, MT_DEZLASER, diff --git a/src/p_mobj.c b/src/p_mobj.c index dd69a9036..b74380517 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5330,7 +5330,54 @@ static void P_MobjSceneryThink(mobj_t *mobj) } else { - // TODO: confetti goes here + const INT16 spacing = 64; + UINT8 i; + + for (i = 0; i < 10; i++) + { + mobj_t *debris = P_SpawnMobjFromMobj( + mobj, + P_RandomRange(-spacing, spacing) * FRACUNIT, + P_RandomRange(-spacing, spacing) * FRACUNIT, + P_RandomRange(-spacing, spacing) * FRACUNIT, + MT_BATTLEBUMPER_DEBRIS + ); + + P_SetScale(debris, (debris->destscale *= 2)); + debris->color = mobj->color; + + debris->momz = -debris->scale * P_MobjFlip(debris); + } + + for (i = 0; i < 2; i++) + { + mobj_t *blast = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BATTLEBUMPER_BLAST); + + blast->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy) + ANGLE_45; + blast->destscale *= 4; + + if (i & 1) + { + blast->angle += ANGLE_90; + } + } + + for (i = 0; i < 10; i++) + { + mobj_t *puff = P_SpawnMobjFromMobj( + mobj, + P_RandomRange(-spacing, spacing) * FRACUNIT, + P_RandomRange(-spacing, spacing) * FRACUNIT, + P_RandomRange(-spacing, spacing) * FRACUNIT, + MT_SPINDASHDUST + ); + + P_SetScale(puff, (puff->destscale *= 5)); + puff->momz = puff->scale * P_MobjFlip(puff); + + P_Thrust(puff, R_PointToAngle2(mobj->x, mobj->y, puff->x, puff->y), puff->scale); + } + P_RemoveMobj(mobj); return; } @@ -5425,6 +5472,14 @@ static void P_MobjSceneryThink(mobj_t *mobj) } break; + + case MT_BATTLEBUMPER_DEBRIS: + if (mobj->state == states + S_BATTLEBUMPER_EXDEBRIS2) + { + mobj->drawflags ^= MFD_DONTDRAW; + } + break; + case MT_PLAYERARROW: if (mobj->target && mobj->target->health && mobj->target->player && !mobj->target->player->spectator From c31efd8631fc02585e7d04617e3c4fe819c3e899 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 02:59:41 -0500 Subject: [PATCH 75/99] Give bumper destruction some sound effects --- src/p_inter.c | 7 +------ src/p_mobj.c | 6 ++++++ src/sounds.c | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 3a97433a1..a16705741 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1452,6 +1452,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget mobj_t *owner = target->target; mobj_t *overlay; + S_StartSound(target, sfx_kc52); target->flags &= ~MF_NOGRAVITY; target->destscale = (3 * target->destscale) / 2; @@ -1459,12 +1460,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (owner && !P_MobjWasRemoved(owner)) { - /* - target->momx = owner->momx / 2; - target->momy = owner->momy / 2; - target->momz = owner->momz / 2; - */ - P_Thrust(target, R_PointToAngle2(owner->x, owner->y, target->x, target->y), 4 * target->scale); } diff --git a/src/p_mobj.c b/src/p_mobj.c index b74380517..e04c90fea 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5286,6 +5286,11 @@ static void P_MobjSceneryThink(mobj_t *mobj) { mobj->fuse--; + if (!S_SoundPlaying(mobj, sfx_cdfm71)) + { + S_StartSound(mobj, sfx_cdfm71); + } + if (mobj->fuse <= 0) { statenum_t curState = (mobj->state - states); @@ -5359,6 +5364,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (i & 1) { blast->angle += ANGLE_90; + S_StartSound(blast, sfx_cdfm64); } } diff --git a/src/sounds.c b/src/sounds.c index d06e521d0..dc777a088 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -740,14 +740,14 @@ sfxinfo_t S_sfx[NUMSFX] = {"cdfm61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Speed boost"}, {"cdfm63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"cdfm64", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"cdfm64", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm65", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm70", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"cdfm71", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"cdfm71", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm72", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm73", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm74", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, @@ -808,7 +808,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"kc4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc51", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"kc52", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"kc52", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc53", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc54", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc55", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, From 082d253553fdd0b6670d12455f40a747b83371e1 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 17:00:21 -0500 Subject: [PATCH 76/99] Remove bot friction Not convinced this fixes anything anymore --- src/k_bot.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/k_bot.c b/src/k_bot.c index a32a554e1..899a70eb1 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -473,6 +473,10 @@ fixed_t K_BotTopSpeedRubberband(player_t *player) --------------------------------------------------*/ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) { +#if 1 + (void)player; + return frict; +#else fixed_t rubberband = K_BotRubberband(player) - FRACUNIT; fixed_t newfrict; @@ -490,6 +494,7 @@ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) newfrict = FRACUNIT; return newfrict; +#endif } /*-------------------------------------------------- From 6a4eb721bd5798d3150a31e2699efa711a3604bf Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 18:35:07 -0500 Subject: [PATCH 77/99] The real problem --- src/k_bot.c | 5 ----- src/p_user.c | 5 ----- 2 files changed, 10 deletions(-) diff --git a/src/k_bot.c b/src/k_bot.c index 899a70eb1..a32a554e1 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -473,10 +473,6 @@ fixed_t K_BotTopSpeedRubberband(player_t *player) --------------------------------------------------*/ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) { -#if 1 - (void)player; - return frict; -#else fixed_t rubberband = K_BotRubberband(player) - FRACUNIT; fixed_t newfrict; @@ -494,7 +490,6 @@ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) newfrict = FRACUNIT; return newfrict; -#endif } /*-------------------------------------------------- diff --git a/src/p_user.c b/src/p_user.c index 6c6c0578a..8065ae13b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1941,11 +1941,6 @@ static void P_3dMovement(player_t *player) totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward); totalthrust.y += P_ReturnThrustY(player->mo, movepushangle, movepushforward); - - if (K_PlayerUsesBotMovement(player) == true) - { - K_MomentumToFacing(player); - } } if ((totalthrust.x || totalthrust.y) From f4e763ed722dd1481029b5f3271bf1ccbeba84ff Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 17 Nov 2020 18:49:14 -0500 Subject: [PATCH 78/99] Use additive/subtractive on models --- src/hardware/hw_drv.h | 2 +- src/hardware/hw_md2.c | 12 +++++++++--- src/hardware/r_opengl/r_opengl.c | 8 ++++---- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 1480ee839..613005421 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -50,7 +50,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void); EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value); //Hurdler: added for new development -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface); +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface, FBITFIELD blendmode); EXPORT void HWRAPI(CreateModelVBOs) (model_t *model); EXPORT void HWRAPI(SetTransform) (FTransform *stransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index f68771a1b..25c0589c6 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1357,6 +1357,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) angle_t ang; INT32 mod; float finalscale; + FBITFIELD blendmode = PF_Masked; // hitlag vibrating if (spr->mobj->hitlag > 0) @@ -1378,12 +1379,17 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) //durs = tics; if (spr->mobj->drawflags & MFD_TRANSMASK) - HWR_TranstableToAlpha((spr->mobj->drawflags & MFD_TRANSMASK)>>MFD_TRANSSHIFT, &Surf); + blendmode = HWR_TranstableToAlpha((spr->mobj->drawflags & MFD_TRANSMASK)>>MFD_TRANSSHIFT, &Surf); else if (spr->mobj->frame & FF_TRANSMASK) - HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf); + blendmode = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf); else Surf.PolyColor.s.alpha = 0xFF; + if (blendmode == PF_Masked) + { + blendmode |= PF_Occlude; + } + // dont forget to enabled the depth test because we can't do this like // before: polygons models are not sorted @@ -1646,7 +1652,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) #endif HWD.pfnSetShader(SHADER_MODEL); // model shader - HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf); + HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf, blendmode); } return true; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 942d3d3de..1f1fcdbd5 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2513,7 +2513,7 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) #define BUFFER_OFFSET(i) ((void*)(i)) -static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) +static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface, FBITFIELD blendmode) { static GLRGBAFloat poly = {0,0,0,0}; static GLRGBAFloat tint = {0,0,0,0}; @@ -2593,7 +2593,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 else pglColor4ubv((GLubyte*)&Surface->PolyColor.s); - SetBlend((poly.alpha < 1 ? PF_Translucent : (PF_Masked|PF_Occlude))|PF_Modulated); + SetBlend(blendmode|PF_Modulated); tint.red = byte2float[Surface->TintColor.s.red]; tint.green = byte2float[Surface->TintColor.s.green]; @@ -2812,9 +2812,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 // -----------------+ // HWRAPI DrawModel : Draw a model // -----------------+ -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface, FBITFIELD blendmode) { - DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface); + DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface, blendmode); } // -----------------+ From a4cd61d226985ee48fd911b128692c262d305d36 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 18 Nov 2020 17:08:54 -0500 Subject: [PATCH 79/99] Make i consistent with orbs variable --- src/k_battle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_battle.c b/src/k_battle.c index 84ac61b62..7a3d43967 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -709,7 +709,7 @@ void K_RunBattleOvertime(void) fixed_t size = FixedMul(mobjinfo[MT_OVERTIME_PARTICLE].radius, scale); fixed_t posOffset = max(battleovertime.radius - size, 0); - UINT32 i; + INT32 i; for (i = 0; i < orbs; i++) { From 931bcb3c2a3b908abbe7e648c5e1210ccd9e3af7 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 18 Nov 2020 17:10:48 -0500 Subject: [PATCH 80/99] Fix laps counter after finishing --- src/d_netcmd.c | 6 +++--- src/k_hud.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 6ce0b6df9..373f4f4f2 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -461,9 +461,9 @@ static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"}, consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange); static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {0, NULL}}; consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange); -static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, NULL}}; -consvar_t cv_numlaps = CVAR_INIT ("numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange); -static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}}; +static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}}; +consvar_t cv_numlaps = CVAR_INIT ("numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange); +static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, "Map default"}, {0, NULL}}; consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange); // Point and time limits for every gametype diff --git a/src/k_hud.c b/src/k_hud.c index 43c3718a1..36577ced5 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1979,7 +1979,7 @@ static void K_drawKartLapsAndRings(void) { // Laps V_DrawScaledPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_lapsticker); - V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->laps, cv_numlaps.value)); + V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", min(stplyr->laps, cv_numlaps.value), cv_numlaps.value)); // Rings if (!uselives) From 350a8bd5c44103beb3b77f37ea0a8bf43e8625ef Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 18 Nov 2020 17:24:03 -0500 Subject: [PATCH 81/99] We can bring this back now --- src/d_clisrv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3374bbae0..30ab8e7ab 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -6240,12 +6240,12 @@ void NetUpdate(void) firstticstosend = gametic; for (i = 0; i < MAXNETNODES; i++) if (nodeingame[i] && nettics[i] < firstticstosend) - //{ + { firstticstosend = nettics[i]; - //if (maketic + 1 >= nettics[i] + BACKUPTICS) - //Net_ConnectionTimeout(i); - //} + if (maketic + 1 >= nettics[i] + BACKUPTICS) + Net_ConnectionTimeout(i); + } // Don't erase tics not acknowledged counts = realtics; From 6f6e87f9df7d74ef7c0abc26576ae7e52f51fd42 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 27 Nov 2020 17:32:04 +0000 Subject: [PATCH 82/99] Fix replays not being accessible via menus. --- src/m_menu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 7f6f542c6..56c5585b4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8139,11 +8139,11 @@ static void M_ReplayTimeAttack(INT32 choice) break; case 3: // guest // srb2/replay/main/map01-guest.lmp - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); + G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); return; } // srb2/replay/main/map01-sonic-time-best.lmp - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which)); + G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which)); } /*else if (currentMenu == &SP_NightsReplayDef) { @@ -8165,13 +8165,13 @@ static void M_ReplayTimeAttack(INT32 choice) break; } // srb2/replay/main/map01-score-best.lmp - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which)); + G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which)); }*/ } static void M_EraseGuest(INT32 choice) { - const char *rguest = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); + const char *rguest = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); (void)choice; if (FIL_FileExists(rguest)) remove(rguest); @@ -8186,10 +8186,10 @@ static void M_EraseGuest(INT32 choice) static void M_OverwriteGuest(const char *which) { - char *rguest = Z_StrDup(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); + char *rguest = Z_StrDup(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); UINT8 *buf; size_t len; - len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which), &buf); + len = FIL_ReadFile(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which), &buf); if (!len) { return; } @@ -8258,7 +8258,7 @@ static void M_SetGuestReplay(INT32 choice) M_StartMessage(M_GetText("Are you sure you want to\ndelete the guest replay data?\n\n(Press 'Y' to confirm)\n"),M_EraseGuest,MM_YESNO); return; } - if (FIL_FileExists(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)))) + if (FIL_FileExists(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)))) M_StartMessage(M_GetText("Are you sure you want to\noverwrite the guest replay data?\n\n(Press 'Y' to confirm)\n"),which,MM_YESNO); else which(0); From 9c0edb097f728c87ed214bebbd32671e753ea6dc Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 27 Nov 2020 17:59:57 +0000 Subject: [PATCH 83/99] Fix demos doing incomprehensibly nasty bullshit; now they only desync for a handful of easier-to-hammer-down cases. --- src/g_demo.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 7c2f9f25c..9b5687750 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1205,9 +1205,6 @@ void G_GhostTicker(void) g->p += 12; // kartitem, kartamount, kartbumpers } - if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this - skippedghosttic: // Tick ghost colors (Super and Mario Invincibility flashing) switch(g->color) @@ -1294,6 +1291,7 @@ skippedghosttic: P_RemoveMobj(follow); P_SetTarget(&follow, NULL); } + // Demo ends after ghost data. if (*g->p == DEMOMARKER) { @@ -1314,6 +1312,10 @@ skippedghosttic: Z_Free(g); continue; } + + if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. + I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this + p = g; #undef follow } @@ -1899,7 +1901,8 @@ void G_BeginRecording(void) if (encoremode) demoflags |= DF_ENCORE; - demoflags |= DF_LUAVARS; + if (multiplayer) + demoflags |= DF_LUAVARS; // Setup header. M_Memcpy(demo_p, DEMOHEADER, 12); demo_p += 12; @@ -2033,9 +2036,8 @@ void G_BeginRecording(void) WRITEUINT8(demo_p, 0xFF); // Denote the end of the player listing // player lua vars, always saved even if empty - LUA_Archive(&demo_p); - - WRITEUINT32(demo_p,P_GetInitSeed()); + if (demoflags & DF_LUAVARS) + LUA_Archive(&demo_p); memset(&oldcmd,0,sizeof(oldcmd)); memset(&oldghost,0,sizeof(oldghost)); @@ -3145,6 +3147,14 @@ void G_AddGhost(char *defdemoname) return; } + if (flags & DF_LUAVARS) // can't be arsed to add support for grinding away ported lua material + { + CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Replay data contains luavars, cannot continue.\n"), pdemoname); + Z_Free(pdemoname); + Z_Free(buffer); + return; + } + p++; // gametype G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts. From f72108c4faa6ec5abb06b1f788f78d646202b764 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 27 Nov 2020 20:30:28 +0000 Subject: [PATCH 84/99] A whole bunch of cleanup to get most record attack/replay stuff reasonably functional. * Fix the screen being stuck black at the very start of start record attack. * Bump up the demoversion to 7, because I want all previous v2 demos to be guaranteed kaput (it was previously 4, but 7 is a nice number). * Fix a ton MORE shitcausing misalignments in the replay system, this time specifically focused on getting ghosts functional. * Plug a few holes in the "best lap" record implementation that allowed for stupidly easy records due to the way v2's finish lines work. * Make a few follower-related things sane, to prevent spurious console prints that were getting in the way of my test prints. --- src/d_netcmd.c | 15 ++---- src/g_demo.c | 127 +++++++++++++++++++++++++------------------------ src/p_spec.c | 17 +++---- src/p_tick.c | 4 +- src/p_user.c | 4 +- src/r_skins.c | 5 ++ 6 files changed, 85 insertions(+), 87 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a87d04cb5..46ecc1b97 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -289,10 +289,10 @@ consvar_t cv_skin[MAXSPLITSCREENPLAYERS] = { // player's followers. Also saved. consvar_t cv_follower[MAXSPLITSCREENPLAYERS] = { - CVAR_INIT ("follower", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower_OnChange), - CVAR_INIT ("follower2", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower2_OnChange), - CVAR_INIT ("follower3", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower3_OnChange), - CVAR_INIT ("follower4", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower4_OnChange) + CVAR_INIT ("follower", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower_OnChange), + CVAR_INIT ("follower2", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower2_OnChange), + CVAR_INIT ("follower3", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower3_OnChange), + CVAR_INIT ("follower4", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower4_OnChange) }; // player's follower colors... Also saved... @@ -2858,13 +2858,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) memset(&luabanks, 0, sizeof(luabanks)); } - if (modeattacking) - { - SetPlayerSkinByNum(0, cv_chooseskin.value-1); - players[0].skincolor = skins[players[0].skin].prefcolor; - CV_StealthSetValue(&cv_playercolor[0], players[0].skincolor); - } - mapnumber = M_MapNumber(mapname[3], mapname[4]); LUAh_MapChange(mapnumber); diff --git a/src/g_demo.c b/src/g_demo.c index 9b5687750..69c8fb760 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -104,7 +104,7 @@ demoghost *ghosts = NULL; // DEMO RECORDING // -#define DEMOVERSION 0x0004 +#define DEMOVERSION 0x0007 #define DEMOHEADER "\xF0" "KartReplay" "\x0F" #define DF_GHOST 0x01 // This demo contains ghost data too! @@ -112,7 +112,7 @@ demoghost *ghosts = NULL; #define DF_BREAKTHECAPSULES 0x04 // This demo is from Break the Capsules and contains its final completion time! #define DF_ATTACKMASK 0x06 // This demo is from ??? attack and contains ??? -#define DF_LUAVARS 0x20 // this demo contains extra lua vars; this is mostly used for backwards compability +#define DF_LUAVARS 0x20 // this demo contains extra lua vars #define DF_ATTACKSHIFT 1 #define DF_ENCORE 0x40 @@ -419,7 +419,10 @@ void G_WriteDemoExtraData(void) { // write follower memset(name, 0, 16); - strncpy(name, followers[players[i].followerskin].skinname, 16); + if (players[i].followerskin == -1) + strncpy(name, "None", 16); + else + strncpy(name, followers[players[i].followerskin].skinname, 16); M_Memcpy(demo_p, name, 16); demo_p += 16; @@ -619,13 +622,21 @@ void G_WriteAllGhostTics(void) counter++; - if (counter % cv_netdemosyncquality.value != 0) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size. + if (multiplayer && (counter % cv_netdemosyncquality.value != 0)) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size. continue; WRITEUINT8(demo_p, i); G_WriteGhostTic(players[i].mo, i); } WRITEUINT8(demo_p, 0xFF); + + // attention here for the ticcmd size! + // latest demos with mouse aiming byte in ticcmd + if (demo_p >= demoend - (13 + 9 + 9)) + { + G_CheckDemoStatus(); // no more space + return; + } } void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) @@ -722,26 +733,22 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) ghostext[playernum].flags |= EZT_SPRITE; } + if (ghost->player && ( + ghostext[playernum].kartitem != ghost->player->kartstuff[k_itemtype] || + ghostext[playernum].kartamount != ghost->player->kartstuff[k_itemamount] || + ghostext[playernum].kartbumpers != ghost->player->kartstuff[k_bumper] + )) + { + ghostext[playernum].flags |= EZT_KART; + ghostext[playernum].kartitem = ghost->player->kartstuff[k_itemtype]; + ghostext[playernum].kartamount = ghost->player->kartstuff[k_itemamount]; + ghostext[playernum].kartbumpers = ghost->player->kartstuff[k_bumper]; + } + if (ghostext[playernum].flags) { ziptic |= GZT_EXTRA; - if (ghost->player) - { - if ( - ghostext[playernum].kartitem != ghost->player->kartstuff[k_itemtype] || - ghostext[playernum].kartamount != ghost->player->kartstuff[k_itemamount] || - ghostext[playernum].kartbumpers != ghost->player->kartstuff[k_bumper] - ) - { - ghostext[playernum].flags |= EZT_KART; - ghostext[playernum].kartitem = ghost->player->kartstuff[k_itemtype]; - ghostext[playernum].kartamount = ghost->player->kartstuff[k_itemamount]; - ghostext[playernum].kartbumpers = ghost->player->kartstuff[k_bumper]; - - } - } - if (ghostext[playernum].color == ghostext[playernum].lastcolor) ghostext[playernum].flags &= ~EZT_COLOR; if (ghostext[playernum].scale == ghostext[playernum].lastscale) @@ -836,14 +843,6 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) oldghost[playernum].flags2 &= ~MF2_AMBUSH; *ziptic_p = ziptic; - - // attention here for the ticcmd size! - // latest demos with mouse aiming byte in ticcmd - if (demo_p >= demoend - (13 + 9 + 9)) - { - G_CheckDemoStatus(); // no more space - return; - } } void G_ConsAllGhostTics(void) @@ -1067,16 +1066,18 @@ void G_GhostTicker(void) if (ziptic & DXD_FOLLOWER) g->p += 32; // ok (32 because there's both the skin and the colour) if (ziptic & DXD_PLAYSTATE && READUINT8(g->p) != DXD_PST_PLAYING) - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this + I_Error("Ghost is not a record attack ghost PLAYSTATE"); //@TODO lmao don't blow up like this } else if (ziptic == DW_RNG) g->p += 4; // RNG seed else - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this + I_Error("Ghost is not a record attack ghost DXD"); //@TODO lmao don't blow up like this ziptic = READUINT8(g->p); } + ziptic = READUINT8(g->p); + if (ziptic & ZT_FWD) g->p++; if (ziptic & ZT_TURNING) @@ -1086,9 +1087,9 @@ void G_GhostTicker(void) if (ziptic & ZT_AIMING) g->p += 2; if (ziptic & ZT_LATENCY) - g->p += 1; + g->p++; if (ziptic & ZT_FLAGS) - g->p += 1; + g->p++; // Grab ghost data. ziptic = READUINT8(g->p); @@ -1096,7 +1097,7 @@ void G_GhostTicker(void) if (ziptic == 0xFF) goto skippedghosttic; // Didn't write ghost info this frame else if (ziptic != 0) - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this + I_Error("Ghost is not a record attack ghost ZIPTIC"); //@TODO lmao don't blow up like this ziptic = READUINT8(g->p); if (ziptic & GZT_XYZ) @@ -1109,17 +1110,17 @@ void G_GhostTicker(void) { if (ziptic & GZT_MOMXY) { - g->oldmo.momx = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); - g->oldmo.momy = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); + g->oldmo.momx = READFIXED(g->p); + g->oldmo.momy = READFIXED(g->p); } if (ziptic & GZT_MOMZ) - g->oldmo.momz = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); + g->oldmo.momz = READFIXED(g->p); g->oldmo.x += g->oldmo.momx; g->oldmo.y += g->oldmo.momy; g->oldmo.z += g->oldmo.momz; } if (ziptic & GZT_ANGLE) - g->mo->angle = READUINT8(g->p)<<24; + g->oldmo.angle = READUINT8(g->p)<<24; if (ziptic & GZT_FRAME) g->oldmo.frame = READUINT8(g->p); if (ziptic & GZT_SPR2) @@ -1205,27 +1206,6 @@ void G_GhostTicker(void) g->p += 12; // kartitem, kartamount, kartbumpers } -skippedghosttic: - // Tick ghost colors (Super and Mario Invincibility flashing) - switch(g->color) - { - case GHC_SUPER: // Super (P_DoSuperStuff) - if (g->mo->skin) - { - skin_t *skin = (skin_t *)g->mo->skin; - g->mo->color = skin->supercolor; - } - else - g->mo->color = SKINCOLOR_SUPERGOLD1; - g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); - break; - case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) - g->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (FIRSTSUPERCOLOR - SKINCOLOR_RUBY))); // Passes through all saturated colours - break; - default: - break; - } - #define follow g->mo->tracer if (ziptic & GZT_FOLLOW) { // Even more... @@ -1292,6 +1272,30 @@ skippedghosttic: P_SetTarget(&follow, NULL); } +skippedghosttic: + // Tick ghost colors (Super and Mario Invincibility flashing) + switch(g->color) + { + case GHC_SUPER: // Super (P_DoSuperStuff) + if (g->mo->skin) + { + skin_t *skin = (skin_t *)g->mo->skin; + g->mo->color = skin->supercolor; + } + else + g->mo->color = SKINCOLOR_SUPERGOLD1; + g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); + break; + case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) + g->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (FIRSTSUPERCOLOR - SKINCOLOR_RUBY))); // Passes through all saturated colours + break; + default: + break; + } + + if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. + I_Error("Ghost is not a record attack ghost GHOSTEND"); //@TODO lmao don't blow up like this + // Demo ends after ghost data. if (*g->p == DEMOMARKER) { @@ -1313,9 +1317,6 @@ skippedghosttic: continue; } - if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this - p = g; #undef follow } @@ -2714,7 +2715,6 @@ void G_DoPlayDemo(char *defdemoname) demo.version = READUINT16(demo_p); switch(demo.version) { - case 0x000d: case DEMOVERSION: // latest always supported break; // too old, cannot support. @@ -3103,7 +3103,6 @@ void G_AddGhost(char *defdemoname) ghostversion = READUINT16(p); switch(ghostversion) { - case 0x000d: case DEMOVERSION: // latest always supported break; // too old, cannot support. @@ -3221,6 +3220,8 @@ void G_AddGhost(char *defdemoname) kartspeed = READUINT8(p); kartweight = READUINT8(p); + p += 4; // followitem (maybe change later) + if (READUINT8(p) != 0xFF) { CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname); diff --git a/src/p_spec.c b/src/p_spec.c index 3d0eddd2e..519f21cd4 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2028,6 +2028,14 @@ static void K_HandleLapIncrement(player_t *player) player->karthud[khud_laphand] = 0; // No hands in FREE PLAY player->karthud[khud_lapanimation] = 80; + + // save best lap for record attack + if (player == &players[consoleplayer]) + { + if (curlap < bestlap || bestlap == 0) + bestlap = curlap; + curlap = 0; + } } if (rainbowstartavailable == true) @@ -2041,14 +2049,6 @@ static void K_HandleLapIncrement(player_t *player) if (netgame && player->laps >= (UINT8)cv_numlaps.value) CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players])); - // SRB2Kart: save best lap for record attack - if (player == &players[consoleplayer]) - { - if (curlap < bestlap || bestlap == 0) - bestlap = curlap; - curlap = 0; - } - player->starpostnum = 0; if (P_IsDisplayPlayer(player)) @@ -2133,6 +2133,7 @@ static void K_HandleLapDecrement(player_t *player) { player->starpostnum = numstarposts; player->laps--; + curlap = UINT32_MAX; } } } diff --git a/src/p_tick.c b/src/p_tick.c index 79e71c655..9d7a6ac5c 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -613,9 +613,7 @@ void P_Ticker(boolean run) if (run) leveltime++; - // as this is mostly used for HUD stuff, add the record attack specific hack to it as well! - if (!(modeattacking && !demo.playback) || leveltime >= starttime - TICRATE*4) - timeinmap++; + timeinmap++; if (G_GametypeHasTeams()) P_DoTeamStuff(); diff --git a/src/p_user.c b/src/p_user.c index f03c63464..10b2c9a97 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2644,7 +2644,7 @@ static void P_DeathThink(player_t *player) { if (player->spectator || !circuitmap) curlap = 0; - else + else if (curlap != UINT32_MAX) curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V } } @@ -4385,7 +4385,7 @@ void P_PlayerThink(player_t *player) { if (player->spectator || !circuitmap) curlap = 0; - else + else if (curlap != UINT32_MAX) curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V } } diff --git a/src/r_skins.c b/src/r_skins.c index 951eeaad6..135221ea6 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -876,6 +876,11 @@ boolean SetPlayerFollower(INT32 playernum, const char *skinname) INT32 i; player_t *player = &players[playernum]; + if (stricmp("None", skinname) == 0) + { + SetFollower(playernum, -1); // reminder that -1 is nothing + return true; + } for (i = 0; i < numfollowers; i++) { // search in the skin list From c2447154ecec27e0a6e9e1ab7acf5ee077f99004 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 28 Nov 2020 11:32:29 +0000 Subject: [PATCH 85/99] Bracketing fix for Sryder. --- src/g_demo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_demo.c b/src/g_demo.c index 69c8fb760..773c0119e 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -622,7 +622,7 @@ void G_WriteAllGhostTics(void) counter++; - if (multiplayer && (counter % cv_netdemosyncquality.value != 0)) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size. + if (multiplayer && ((counter % cv_netdemosyncquality.value) != 0)) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size. continue; WRITEUINT8(demo_p, i); From 495e4896dcef5a4e9f0d911cdac5cfcc751e575e Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 28 Nov 2020 11:45:25 +0000 Subject: [PATCH 86/99] Fixed Chengi's sprite2 bug, and started on (but haven't nailed down) the rewind crash. --- src/g_demo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/g_demo.c b/src/g_demo.c index 773c0119e..aebc447f2 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1439,8 +1439,11 @@ void G_PreviewRewind(tic_t previewtime) players[i].drawangle = info->playerinfo[i].player.drawangle + FixedMul((INT32) (next_info->playerinfo[i].player.drawangle - info->playerinfo[i].player.drawangle), tweenvalue); players[i].mo->sprite = info->playerinfo[i].mobj.sprite; + players[i].mo->sprite2 = info->playerinfo[i].mobj.sprite2; players[i].mo->frame = info->playerinfo[i].mobj.frame; + players[i].mo->hitlag = info->playerinfo[i].mobj.hitlag; + players[i].realtime = info->playerinfo[i].player.realtime; for (j = 0; j < NUMKARTSTUFF; j++) players[i].kartstuff[j] = info->playerinfo[i].player.kartstuff[j]; From 762dfd3063f50854399a46865fe9b34379f18b08 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 28 Nov 2020 12:31:16 +0000 Subject: [PATCH 87/99] When resuming from a rewind, don't: * run wipes again * run titlecards again * stop the music --- src/g_demo.c | 2 +- src/g_game.c | 2 +- src/p_setup.c | 60 +++++++++++++++++++++++++-------------------------- src/p_tick.c | 2 ++ 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index aebc447f2..693a4f095 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1468,7 +1468,7 @@ void G_ConfirmRewind(tic_t rewindtime) if (rewindtime <= starttime) { - demo.rewinding = false; + demo.rewinding = true; // this doesn't APPEAR to cause any misery, and it allows us to prevent running all the wipes again G_DoPlayDemo(NULL); // Restart the current demo } else diff --git a/src/g_game.c b/src/g_game.c index 0151783e9..1f17fc181 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1252,7 +1252,7 @@ void G_StartTitleCard(void) { // The title card has been disabled for this map. // Oh well. - if (!G_IsTitleCardAvailable()) + if (!G_IsTitleCardAvailable() || demo.rewinding) { WipeStageTitle = false; return; diff --git a/src/p_setup.c b/src/p_setup.c index 50f39c5fa..15e6767a5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3924,40 +3924,40 @@ boolean P_LoadLevel(boolean fromnetsave) } */ - // Make sure all sounds are stopped before Z_FreeTags. - S_StopSounds(); - S_ClearSfx(); - - // Fade out music here. Deduct 2 tics so the fade volume actually reaches 0. - // But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug. - if (!titlemapinaction) - S_FadeMusic(0, FixedMul( - FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE)); - - // Reset the palette now all fades have been done - if (rendermode != render_none) - V_SetPaletteLump(GetPalette()); // Set the level palette - - if (!titlemapinaction) - { - if (ranspecialwipe == 2) - { - pausedelay = -3; // preticker plus one - S_StartSound(NULL, sfx_s3k73); - } - - // As oddly named as this is, this handles music only. - // We should be fine starting it here. - // Don't do this during titlemap, because the menu code handles music by itself. - S_Start(); - } - - levelfadecol = (encoremode ? 0 : 31); - // Let's fade to white here // But only if we didn't do the encore startup wipe if (!demo.rewinding) { + // Make sure all sounds are stopped before Z_FreeTags. + S_StopSounds(); + S_ClearSfx(); + + // Fade out music here. Deduct 2 tics so the fade volume actually reaches 0. + // But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug. + if (!titlemapinaction) + S_FadeMusic(0, FixedMul( + FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE)); + + // Reset the palette now all fades have been done + if (rendermode != render_none) + V_SetPaletteLump(GetPalette()); // Set the level palette + + if (!titlemapinaction) + { + if (ranspecialwipe == 2) + { + pausedelay = -3; // preticker plus one + S_StartSound(NULL, sfx_s3k73); + } + + // As oddly named as this is, this handles music only. + // We should be fine starting it here. + // Don't do this during titlemap, because the menu code handles music by itself. + S_Start(); + } + + levelfadecol = (encoremode ? 0 : 31); + if (rendermode != render_none) { F_WipeStartScreen(); diff --git a/src/p_tick.c b/src/p_tick.c index 9d7a6ac5c..cef59ea8d 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -516,6 +516,8 @@ void P_Ticker(boolean run) if (demo.rewinding && leveltime > 0) { leveltime = (leveltime-1) & ~3; + if (timeinmap > 0) + timeinmap = (timeinmap-1) & ~3; G_PreviewRewind(leveltime); } else if (demo.freecam && democam.cam) // special case: allow freecam to MOVE during pause! From 891f14dd26848fa4b4abbbdf3a395f18d7e20974 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 28 Nov 2020 17:29:28 +0000 Subject: [PATCH 88/99] Don't show post-race bot inputs on input display UI. --- src/k_hud.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 42c7fd7c2..056beb408 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -3523,7 +3523,7 @@ static void K_drawInput(void) #define BUTTH 11 #define drawbutt(xoffs, butt, symb)\ - if (stplyr->cmd.buttons & butt)\ + if (!stplyr->exiting && (cmd->buttons & butt))\ {\ offs = 2;\ col = accent1;\ @@ -3549,7 +3549,7 @@ static void K_drawInput(void) y -= 1; - if (!cmd->turning) // no turn + if (stplyr->exiting || !cmd->turning) // no turn target = 0; else // turning of multiple strengths! { From a7621f4e96f7b3c450ddf710dfc87b7c5a2d56fe Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Nov 2020 16:41:48 -0800 Subject: [PATCH 89/99] Fix compiler warning --- src/k_hud.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index fa4c86f9a..ec80a8f96 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2166,8 +2166,8 @@ static void K_drawKartBumpersOrKarma(void) if (stplyr->bumpers > 9 || maxbumper > 9) { UINT8 ln[2]; - ln[0] = ((abs(stplyr->bumpers) / 10) % 10); - ln[1] = (abs(stplyr->bumpers) % 10); + ln[0] = (stplyr->bumpers / 10 % 10); + ln[1] = (stplyr->bumpers % 10); V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); From 52e5de2bdc58cad9a9ac6e49459c39c731c50dd0 Mon Sep 17 00:00:00 2001 From: SteelT Date: Thu, 24 Dec 2020 14:49:30 -0500 Subject: [PATCH 90/99] Fix rain sound not playing. Also fixed snow precip not picking any random state. --- src/info.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/info.c b/src/info.c index ae7e58b8e..5776877ae 100644 --- a/src/info.c +++ b/src/info.c @@ -18573,22 +18573,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 1*FRACUNIT, // radius 8*FRACUNIT, // height 0, // display offset - 4, // mass + 80, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags @@ -18601,7 +18601,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 @@ -18615,8 +18615,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 4*FRACUNIT, // radius 4*FRACUNIT, // height 0, // display offset - 4, // mass - 0, // damage + 0, // mass + 2, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags S_NULL // raisestate From 90507126e47cdd5d4ecf8273f5f6b74e0ea82ffa Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 4 Jan 2021 17:34:10 -0800 Subject: [PATCH 91/99] Move block line checks to a single function --- src/p_map.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index d3e9aaa80..b60d243e2 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1624,6 +1624,22 @@ static boolean PIT_CheckCameraLine(line_t *ld) return true; } +static boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing) +{ + // missiles can cross uncrossable lines + if ((thing->flags & MF_MISSILE)) + return false; + else + { + return + ( + (ld->flags & ML_IMPASSABLE) || // block objects from moving through this linedef. + (thing->player && !thing->player->spectator && + ld->flags & ML_BLOCKPLAYERS) // SRB2Kart: Only block players, not items + ); + } +} + // // PIT_CheckLine // Adjusts tmfloorz and tmceilingz as lines are contacted @@ -1699,14 +1715,8 @@ static boolean PIT_CheckLine(line_t *ld) return false; } - // missiles can cross uncrossable lines - if (!(tmthing->flags & MF_MISSILE)) - { - if (ld->flags & ML_IMPASSABLE) // block objects from moving through this linedef. - return false; - if (tmthing->player && !tmthing->player->spectator && ld->flags & ML_BLOCKPLAYERS) - return false; // SRB2Kart: Only block players, not items - } + if (P_IsLineBlocking(ld, tmthing)) + return false; // set openrange, opentop, openbottom P_LineOpening(ld, tmthing); @@ -3172,14 +3182,8 @@ static boolean PTR_LineIsBlocking(line_t *li) if (!li->backsector) return !P_PointOnLineSide(slidemo->x, slidemo->y, li); - if (!(slidemo->flags & MF_MISSILE)) - { - if (li->flags & ML_IMPASSABLE) - return true; - - if (slidemo->player && !slidemo->player->spectator && li->flags & ML_BLOCKPLAYERS) - return true; - } + if (P_IsLineBlocking(li, slidemo)) + return true; // set openrange, opentop, openbottom P_LineOpening(li, slidemo); From 6070d14fa5772398a8977be1f8346f60b5c0d0c4 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 4 Jan 2021 17:40:06 -0800 Subject: [PATCH 92/99] Line special 11: block monsters for this line --- src/p_map.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index b60d243e2..d6a3044cb 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1635,7 +1635,8 @@ static boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing) ( (ld->flags & ML_IMPASSABLE) || // block objects from moving through this linedef. (thing->player && !thing->player->spectator && - ld->flags & ML_BLOCKPLAYERS) // SRB2Kart: Only block players, not items + ld->flags & ML_BLOCKPLAYERS) || // SRB2Kart: Only block players, not items + ((thing->flags & (MF_ENEMY|MF_BOSS)) && ld->special == 11) // case 11: block monsters only ); } } From c76ae9a4fd878826312202697b38ac2210fd14d2 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 4 Jan 2021 18:55:33 -0800 Subject: [PATCH 93/99] Actually put it on line type 81 --- 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 d6a3044cb..898ee0a49 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1636,7 +1636,7 @@ static boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing) (ld->flags & ML_IMPASSABLE) || // block objects from moving through this linedef. (thing->player && !thing->player->spectator && ld->flags & ML_BLOCKPLAYERS) || // SRB2Kart: Only block players, not items - ((thing->flags & (MF_ENEMY|MF_BOSS)) && ld->special == 11) // case 11: block monsters only + ((thing->flags & (MF_ENEMY|MF_BOSS)) && ld->special == 81) // case 81: block monsters only ); } } From fe4d9ce8895da6242d02b148778c76efc84d82a5 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Wed, 6 Jan 2021 21:20:28 +0100 Subject: [PATCH 94/99] New trick panel shit (but only the gameplay part) --- src/d_clisrv.c | 20 +++++--- src/d_clisrv.h | 5 +- src/d_player.h | 14 ++++-- src/k_kart.c | 116 ++++++++++++++++++++++++++++++++------------ src/lua_playerlib.c | 12 +++++ src/p_inter.c | 2 +- src/p_map.c | 4 +- src/p_mobj.c | 6 +-- src/p_saveg.c | 14 ++++-- src/p_spec.c | 2 +- 10 files changed, 142 insertions(+), 53 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 610152d90..3c4c087df 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -617,7 +617,10 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->airtime = (tic_t)LONG(players[i].airtime); rsp->trickpanel = (UINT8)players[i].trickpanel; - rsp->trickdelay = (tic_t)LONG(players[i].trickdelay); + rsp->trickdelay = (boolean)players[i].trickdelay; + rsp->trickmomx = (fixed_t)LONG(players[i].trickmomx); + rsp->trickmomy = (fixed_t)LONG(players[i].trickmomy); + rsp->trickmomz = (fixed_t)LONG(players[i].trickmomz); rsp->bumpers = players[i].bumpers; rsp->karmadelay = SHORT(players[i].karmadelay); @@ -767,7 +770,10 @@ static void resynch_read_player(resynch_pak *rsp) players[i].airtime = (tic_t)LONG(rsp->airtime); players[i].trickpanel = (UINT8)rsp->trickpanel; - players[i].trickdelay = (tic_t)LONG(rsp->trickdelay); + players[i].trickdelay = (boolean)rsp->trickdelay; + players[i].trickmomx = (fixed_t)LONG(rsp->trickmomx); + players[i].trickmomy = (fixed_t)LONG(rsp->trickmomy); + players[i].trickmomz = (fixed_t)LONG(rsp->trickmomz); players[i].bumpers = rsp->bumpers; players[i].karmadelay = SHORT(rsp->karmadelay); @@ -1260,7 +1266,7 @@ static inline void CL_DrawConnectionStatus(void) cltext = M_GetText("Server full, waiting for a slot..."); else cltext = M_GetText("Requesting to join..."); - + break; #ifdef HAVE_CURL case CL_PREPAREHTTPFILES: @@ -2129,7 +2135,7 @@ void CL_UpdateServerList (void) static void M_ConfirmConnect(event_t *ev) { -#ifndef NONET +#ifndef NONET if (ev->type == ev_keydown) { if (ev->data1 == ' ' || ev->data1 == 'y' || ev->data1 == KEY_ENTER || ev->data1 == gamecontrol[0][gc_accelerate][0] || ev->data1 == gamecontrol[0][gc_accelerate][1]) @@ -2152,7 +2158,7 @@ static void M_ConfirmConnect(event_t *ev) } else cl_mode = CL_LOADFILES; - + M_ClearMenus(true); } else if (ev->data1 == 'n' || ev->data1 == KEY_ESCAPE|| ev->data1 == gamecontrol[0][gc_brake][0] || ev->data1 == gamecontrol[0][gc_brake][1]) @@ -2400,7 +2406,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic { boolean waitmore; INT32 i; - + #ifdef NONET (void)tmpsave; #endif @@ -2437,7 +2443,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic { curl_transfers++; } - + cl_mode = CL_DOWNLOADHTTPFILES; } break; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 365059c3d..ae9e59e7a 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -282,7 +282,10 @@ typedef struct INT32 kartstuff[NUMKARTSTUFF]; tic_t airtime; UINT8 trickpanel; - tic_t trickdelay; + boolean trickdelay; + fixed_t trickmomx; + fixed_t trickmomy; + fixed_t trickmomz; UINT8 bumpers; INT16 karmadelay; diff --git a/src/d_player.h b/src/d_player.h index 07eecc54d..89679e9f1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -449,6 +449,10 @@ typedef enum // QUICKLY GET RING TOTAL, INCLUDING RINGS CURRENTLY IN THE PICKUP ANIMATION #define RINGTOTAL(p) (p->rings + p->kartstuff[k_pickuprings]) +// CONSTANTS FOR TRICK PANELS +#define TRICKMOMZRAMP (30) +#define TRICKLAG (9) + //} // player_t struct for all respawn variables @@ -523,9 +527,13 @@ typedef struct player_s UINT32 distancetofinish; waypoint_t *nextwaypoint; respawnvars_t respawn; // Respawn info - tic_t airtime; // Keep track of how long you've been in the air - UINT8 trickpanel; // Trick panel state - tic_t trickdelay; + tic_t airtime; // Keep track of how long you've been in the air + + UINT8 trickpanel; // Trick panel state + boolean trickdelay; // Prevent tricks until control stick is neutral + fixed_t trickmomx; + fixed_t trickmomy; + fixed_t trickmomz; // Instead of stupid auxiliary variables let's... just make some ourselves. UINT8 bumpers; INT16 karmadelay; diff --git a/src/k_kart.c b/src/k_kart.c index a94dce177..6a05c50d5 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2052,7 +2052,7 @@ INT16 K_GetSpindashChargeTime(player_t *player) { // more charge time for higher speed // Tails = 2s, Mighty = 3s, Fang = 4s, Metal = 4s - return (player->kartspeed + 4) * (TICRATE/3); + return (player->kartspeed + 4) * (TICRATE/3); } fixed_t K_GetSpindashChargeSpeed(player_t *player) @@ -4209,6 +4209,8 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) { thrust = FixedMul(thrust, 9*FRACUNIT/8); } + + mo->player->trickmomx = mo->player->trickmomy = mo->player->trickmomz = 0; // Reset post-hitlag momentums. } mo->momz = FixedMul(thrust, vscale); @@ -7830,7 +7832,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_PlayBoostTaunt(player->mo); K_DoPogoSpring(player->mo, 32<trickpanel = 1; - player->trickdelay = TICRATE/2; + player->trickdelay = 1; player->kartstuff[k_itemamount]--; } break; @@ -7944,49 +7946,101 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->drawflags &= ~(MFD_TRANSMASK|MFD_BRIGHTMASK); } - if (player->trickpanel == 1 && player->trickdelay <= 0) + if (player->trickpanel == 1) { const angle_t lr = ANGLE_45; - fixed_t speed = P_AproxDistance(player->mo->momx, player->mo->momy); + fixed_t momz = FixedDiv(player->mo->momz, mapobjectscale); // bring momz back to scale... + fixed_t speedmult = max(0, FRACUNIT - abs(momz)/TRICKMOMZRAMP); // TRICKMOMZRAMP momz is minimum speed (Should be 20) + fixed_t basespeed = P_AproxDistance(player->mo->momx, player->mo->momy); // at WORSE, keep your normal speed when tricking. + fixed_t speed = FixedMul(speedmult, P_AproxDistance(player->mo->momx, player->mo->momy)); - if (cmd->turning > 0) + // debug shit + //CONS_Printf("%d\n", player->mo->momz / mapobjectscale); + + if (player->trickdelay <= 0) { - P_InstaThrust(player->mo, player->mo->angle + lr, speed*2); - player->trickpanel = 2; - } - else if (cmd->turning < 0) - { - P_InstaThrust(player->mo, player->mo->angle - lr, speed*2); - player->trickpanel = 3; - } - else if (player->kartstuff[k_throwdir] == 1) - { - if (player->mo->momz * P_MobjFlip(player->mo) > 0) + + if (cmd->turning > 0) { + P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*2)); + + player->trickmomx = player->mo->momx; + player->trickmomy = player->mo->momy; + player->trickmomz = player->mo->momz; + P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) player->mo->momz = 0; + + player->trickpanel = 2; + player->mo->hitlag = TRICKLAG; } - - P_InstaThrust(player->mo, player->mo->angle, speed*3); - player->trickpanel = 2; - } - else if (player->kartstuff[k_throwdir] == -1) - { - boolean relative = true; - - player->mo->momx /= 3; - player->mo->momy /= 3; - - if (player->mo->momz * P_MobjFlip(player->mo) <= 0) + else if (cmd->turning < 0) { - relative = false; + P_InstaThrust(player->mo, player->mo->angle - lr, max(basespeed, speed*2)); + + player->trickmomx = player->mo->momx; + player->trickmomy = player->mo->momy; + player->trickmomz = player->mo->momz; + P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) + player->mo->momz = 0; + + player->trickpanel = 3; + player->mo->hitlag = TRICKLAG; } + else if (player->kartstuff[k_throwdir] == 1) + { + if (player->mo->momz * P_MobjFlip(player->mo) > 0) + { + player->mo->momz = 0; + } - P_SetObjectMomZ(player->mo, 48*FRACUNIT, relative); + P_InstaThrust(player->mo, player->mo->angle, max(basespeed, speed*3)); - player->trickpanel = 3; + player->trickmomx = player->mo->momx; + player->trickmomy = player->mo->momy; + player->trickmomz = player->mo->momz; + P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) + player->mo->momz = 0; + + player->trickpanel = 2; + player->mo->hitlag = TRICKLAG; + } + else if (player->kartstuff[k_throwdir] == -1) + { + boolean relative = true; + + player->mo->momx /= 3; + player->mo->momy /= 3; + + if (player->mo->momz * P_MobjFlip(player->mo) <= 0) + { + relative = false; + } + + P_SetObjectMomZ(player->mo, 48*FRACUNIT, relative); + + player->trickmomx = player->mo->momx; + player->trickmomy = player->mo->momy; + player->trickmomz = player->mo->momz; + P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) + player->mo->momz = 0; + + player->trickpanel = 3; + player->mo->hitlag = TRICKLAG; + } } } + // After hitlag, we will get here and will be able to apply the desired momentums! + else if (player->trickmomx || player->trickmomy || player->trickmomz) + { + player->mo->momx = player->trickmomx; + player->mo->momy = player->trickmomy; + player->mo->momz = player->trickmomz; + player->trickmomx = player->trickmomy = player->trickmomz = 0; + + } + + // Wait until we let go off the control stick to remove the delay if (player->trickdelay > 0) { player->trickdelay--; diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index f28987700..daf1666c8 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -218,6 +218,12 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->trickpanel); else if (fastcmp(field,"trickdelay")) lua_pushinteger(L, plr->trickdelay); + else if (fastcmp(field,"trickmomx")) + lua_pushfixed(L, plr->trickmomx); + else if (fastcmp(field,"trickmomy")) + lua_pushfixed(L, plr->trickmomy); + else if (fastcmp(field,"trickmomz")) + lua_pushfixed(L, plr->trickmomz); else if (fastcmp(field,"pflags")) lua_pushinteger(L, plr->pflags); else if (fastcmp(field,"panim")) @@ -511,6 +517,12 @@ static int player_set(lua_State *L) plr->trickpanel = luaL_checkinteger(L, 3); else if (fastcmp(field,"trickdelay")) plr->trickdelay = (tic_t)luaL_checkinteger(L, 3); + else if (fastcmp(field,"trickmomx")) + plr->trickmomx = (fixed_t)luaL_checkfixed(L, 3); + else if (fastcmp(field,"trickmomy")) + plr->trickmomy = (fixed_t)luaL_checkfixed(L, 3); + else if (fastcmp(field,"trickmomz")) + plr->trickmomz = (fixed_t)luaL_checkfixed(L, 3); else if (fastcmp(field,"kartspeed")) plr->kartspeed = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"kartweight")) diff --git a/src/p_inter.c b/src/p_inter.c index 7aa25c25d..4a798d4d0 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -30,7 +30,7 @@ #include "f_finale.h" // SRB2kart -#include "k_kart.h" +#include "k_kart.h" #include "k_battle.h" #include "k_pwrlv.h" #include "k_grandprix.h" diff --git a/src/p_map.c b/src/p_map.c index 2309ac260..31df0e09b 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -449,7 +449,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) if (object->player) { object->player->trickpanel = 1; - object->player->trickdelay = TICRATE/2; + object->player->trickdelay = 1; } K_DoPogoSpring(object, 32<color = K_RainbowColor( (SKINCOLOR_PURPLE - SKINCOLOR_PINK) // Smoothly transition into the other state + ((mobj->fuse - 32) * 2) // Make the color flashing slow down while it runs out - ); + ); switch (mobj->extravalue1) { @@ -10243,7 +10243,7 @@ void P_SpawnPlayer(INT32 playernum) /* if (bonusgame || specialstage) { - // Bots should avoid + // Bots should avoid p->spectator = true; } */ @@ -10357,7 +10357,7 @@ void P_SpawnPlayer(INT32 playernum) if ((leveltime < starttime) || (pcount <= 1)) // Start of the map? { // Reset those bumpers! - p->bumpers = K_StartingBumperCount(); + p->bumpers = K_StartingBumperCount(); } if (p->bumpers) diff --git a/src/p_saveg.c b/src/p_saveg.c index e32b69735..4e6e31d88 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -235,7 +235,7 @@ static void P_NetArchivePlayers(void) if (flags & FOLLOWITEM) WRITEUINT32(save_p, players[i].followmobj->mobjnum); - + WRITEUINT32(save_p, (UINT32)players[i].followitem); WRITEUINT32(save_p, players[i].charflags); @@ -257,7 +257,10 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); WRITEUINT32(save_p, players[i].airtime); WRITEUINT8(save_p, players[i].trickpanel); - WRITEUINT32(save_p, players[i].trickdelay); + WRITEUINT8(save_p, players[i].trickdelay); + WRITEUINT32(save_p, players[i].trickmomx); + WRITEUINT32(save_p, players[i].trickmomy); + WRITEUINT32(save_p, players[i].trickmomz); WRITEUINT8(save_p, players[i].bumpers); WRITEINT16(save_p, players[i].karmadelay); @@ -426,7 +429,7 @@ static void P_NetUnArchivePlayers(void) if (flags & FOLLOWITEM) players[i].followmobj = (mobj_t *)(size_t)READUINT32(save_p); - + players[i].followitem = (mobjtype_t)READUINT32(save_p); //SetPlayerSkinByNum(i, players[i].skin); @@ -449,7 +452,10 @@ static void P_NetUnArchivePlayers(void) players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p); players[i].airtime = READUINT32(save_p); players[i].trickpanel = READUINT8(save_p); - players[i].trickdelay = READUINT32(save_p); + players[i].trickdelay = READUINT8(save_p); + players[i].trickmomx = READUINT32(save_p); + players[i].trickmomy = READUINT32(save_p); + players[i].trickmomz = READUINT32(save_p); players[i].bumpers = READUINT8(save_p); players[i].karmadelay = READINT16(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index ce7ffd841..62dffaf67 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4618,7 +4618,7 @@ DoneSection2: } player->trickpanel = 1; - player->trickdelay = TICRATE/2; + player->trickdelay = 1; K_DoPogoSpring(player->mo, upwards, 1); // Reduce speed From f2880241b4e9749a88151645103a249419d9ebbb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 6 Jan 2021 15:25:39 -0500 Subject: [PATCH 95/99] Fix scale issues reintroduced by this branch --- src/k_kart.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 35b9d9481..c99e8fbc9 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3576,8 +3576,9 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map PROJSPEED = FixedMul(82 * FRACUNIT, K_GetKartGameSpeedScalar(gamespeed)); } - // Scale to player scale - PROJSPEED = FixedMul(PROJSPEED, player->mo->scale); + // Scale to map scale + // Intentionally NOT player scale, that doesn't work. + PROJSPEED = FixedMul(PROJSPEED, mapobjectscale); if (altthrow) { @@ -3677,7 +3678,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map if (mo) { angle_t fa = player->mo->angle>>ANGLETOFINESHIFT; - fixed_t HEIGHT = ((20 + (dir*10)) * player->mo->scale) + (player->mo->momz*P_MobjFlip(player->mo)); + fixed_t HEIGHT = ((20 + (dir*10)) * FRACUNIT) + (player->mo->momz*P_MobjFlip(player->mo)); // Also intentionally not player scale P_SetObjectMomZ(mo, HEIGHT, false); mo->momx = player->mo->momx + FixedMul(FINECOSINE(fa), PROJSPEED*dir); @@ -3785,7 +3786,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map void K_PuntMine(mobj_t *origMine, mobj_t *punter) { angle_t fa = K_MomentumAngle(punter); - fixed_t z = punter->momz + (30 * punter->scale); + fixed_t z = (punter->momz * P_MobjFlip(punter)) + (30 * FRACUNIT); fixed_t spd; mobj_t *mine; @@ -3841,7 +3842,7 @@ void K_PuntMine(mobj_t *origMine, mobj_t *punter) mine->momx = punter->momx + FixedMul(FINECOSINE(fa >> ANGLETOFINESHIFT), spd); mine->momy = punter->momy + FixedMul(FINESINE(fa >> ANGLETOFINESHIFT), spd); - mine->momz = P_MobjFlip(mine) * z; + P_SetObjectMomZ(mine, z, false); //K_SetHitLagForObjects(punter, mine, 5); From 9d7e880d66f3617129aeb5e265a7f1ef45298f9a Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Wed, 6 Jan 2021 21:52:33 +0100 Subject: [PATCH 96/99] Buff side tricks slightly --- src/k_kart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 6a05c50d5..bc91e6ea9 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7962,7 +7962,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (cmd->turning > 0) { - P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*2)); + P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*5/2)); player->trickmomx = player->mo->momx; player->trickmomy = player->mo->momy; @@ -7975,7 +7975,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else if (cmd->turning < 0) { - P_InstaThrust(player->mo, player->mo->angle - lr, max(basespeed, speed*2)); + P_InstaThrust(player->mo, player->mo->angle - lr, max(basespeed, speed*5/2)); player->trickmomx = player->mo->momx; player->trickmomy = player->mo->momy; From 834bd78eb56df3e0ff61c035c1c56d7583137739 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Wed, 6 Jan 2021 22:10:23 +0100 Subject: [PATCH 97/99] Consider stuff unlocked if DEVELOP flag set --- src/m_cond.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/m_cond.c b/src/m_cond.c index 8ffe3c378..bfd463a7c 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -341,6 +341,12 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa UINT8 M_AnySecretUnlocked(void) { INT32 i; + +#ifdef DEVELOP + if (1) + return true; +#endif + for (i = 0; i < MAXUNLOCKABLES; ++i) { if (!unlockables[i].nocecho && unlockables[i].unlocked) @@ -376,6 +382,12 @@ UINT8 M_SecretUnlocked(INT32 type) UINT8 M_MapLocked(INT32 mapnum) { + +#ifdef DEVELOP + if (1) + return false; +#endif + if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0) return false; if (!unlockables[mapheaderinfo[mapnum-1]->unlockrequired].unlocked) From 56fba410ee4bd7eb6b5628c2d3dbd9eaef2fea4c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 6 Jan 2021 16:21:57 -0500 Subject: [PATCH 98/99] Waypoints use trace for blocking lines, instead of a sight check --- src/k_waypoint.c | 2 +- src/lua_baselib.c | 13 ++++ src/p_local.h | 2 + src/p_map.c | 2 +- src/p_sight.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 175 insertions(+), 2 deletions(-) diff --git a/src/k_waypoint.c b/src/k_waypoint.c index b9581e871..db8289aaa 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -314,7 +314,7 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj) } else if (checkdist < closestdist && bestfindist == INT32_MAX) { - if (!P_CheckSight(mobj, checkwaypoint->mobj)) + if (!P_TraceBlockingLines(mobj, checkwaypoint->mobj)) { // Save sight checks for the end, so we only do it if we have to continue; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index d689dc848..da2c21bbb 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1410,6 +1410,18 @@ static int lib_pCheckSight(lua_State *L) return 1; } +static int lib_pTraceBlockingLines(lua_State *L) +{ + mobj_t *t1 = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *t2 = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + //HUDSAFE? + INLEVEL + if (!t1 || !t2) + return LUA_ErrInvalid(L, "mobj_t"); + lua_pushboolean(L, P_TraceBlockingLines(t1, t2)); + return 1; +} + static int lib_pCheckHoopPosition(lua_State *L) { mobj_t *hoopthing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -3783,6 +3795,7 @@ static luaL_Reg lib[] = { {"P_SlideMove",lib_pSlideMove}, {"P_BounceMove",lib_pBounceMove}, {"P_CheckSight", lib_pCheckSight}, + {"P_TraceBlockingLines", lib_pTraceBlockingLines}, {"P_CheckHoopPosition",lib_pCheckHoopPosition}, {"P_RadiusAttack",lib_pRadiusAttack}, {"P_FloorzAtPos",lib_pFloorzAtPos}, diff --git a/src/p_local.h b/src/p_local.h index f4029aedc..47a65563c 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -400,6 +400,7 @@ void P_UnsetThingPosition(mobj_t *thing); void P_SetThingPosition(mobj_t *thing); void P_SetUnderlayPosition(mobj_t *thing); +boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing); boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y); boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam); boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff); @@ -409,6 +410,7 @@ void P_SlideMove(mobj_t *mo); void P_BouncePlayerMove(mobj_t *mo); void P_BounceMove(mobj_t *mo); boolean P_CheckSight(mobj_t *t1, mobj_t *t2); +boolean P_TraceBlockingLines(mobj_t *t1, mobj_t *t2); void P_CheckHoopPosition(mobj_t *hoopthing, fixed_t x, fixed_t y, fixed_t z, fixed_t radius); boolean P_CheckSector(sector_t *sector, boolean crunch); diff --git a/src/p_map.c b/src/p_map.c index 898ee0a49..98966c14d 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1624,7 +1624,7 @@ static boolean PIT_CheckCameraLine(line_t *ld) return true; } -static boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing) +boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing) { // missiles can cross uncrossable lines if ((thing->flags & MF_MISSILE)) diff --git a/src/p_sight.c b/src/p_sight.c index a18f22d40..38a50df36 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -498,3 +498,161 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) // the head node is the last node output return P_CrossBSPNode((INT32)numnodes - 1, &los); } + +// +// P_TraceBlockingLines +// +// Returns true if a straight line between t1 and t2 is unobstructed. +// Unlike P_CheckSight, simplifed down to only check for explicit blocking lines on the 2D plane. +// Intended for Kart waypoints. +// Might be better in it's own file? +// + +typedef struct { + fixed_t t2x, t2y; + divline_t strace; // from t1 to t2 + fixed_t bbox[4]; + mobj_t *compareThing; +} traceblocking_t; + +static boolean P_CrossBlockingSubsector(size_t num, register traceblocking_t *tb) +{ + seg_t *seg; + INT32 count; + +#ifdef RANGECHECK + if (num >= numsubsectors) + I_Error("P_CrossBlockingSubsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors)); +#endif + + // haleyjd 02/23/06: this assignment should be after the above check + seg = segs + subsectors[num].firstline; + + for (count = subsectors[num].numlines; --count >= 0; seg++) // check lines + { + line_t *line = seg->linedef; + divline_t divl; + const vertex_t *v1,*v2; + + if (seg->glseg) + continue; + + // already checked other side? + if (line->validcount == validcount) + continue; + + line->validcount = validcount; + + // OPTIMIZE: killough 4/20/98: Added quick bounding-box rejection test + if (line->bbox[BOXLEFT ] > tb->bbox[BOXRIGHT ] || + line->bbox[BOXRIGHT ] < tb->bbox[BOXLEFT ] || + line->bbox[BOXBOTTOM] > tb->bbox[BOXTOP ] || + line->bbox[BOXTOP] < tb->bbox[BOXBOTTOM]) + continue; + + v1 = line->v1; + v2 = line->v2; + + // line isn't crossed? + if (P_DivlineSide(v1->x, v1->y, &tb->strace) == + P_DivlineSide(v2->x, v2->y, &tb->strace)) + continue; + + // stop because it is not two sided anyway + if (!(line->flags & ML_TWOSIDED)) + return false; + + divl.dx = v2->x - (divl.x = v1->x); + divl.dy = v2->y - (divl.y = v1->y); + + // line isn't crossed? + if (P_DivlineSide(tb->strace.x, tb->strace.y, &divl) == + P_DivlineSide(tb->t2x, tb->t2y, &divl)) + continue; + + if (P_IsLineBlocking(line, tb->compareThing) == true) + { + // This line will block us + return false; + } + } + + // passed the subsector ok + return true; +} + +static boolean P_CrossBSPNodeBlocking(INT32 bspnum, register traceblocking_t *tb) +{ + while (!(bspnum & NF_SUBSECTOR)) + { + register node_t *bsp = nodes + bspnum; + INT32 side = P_DivlineSide(tb->strace.x,tb->strace.y,(divline_t *)bsp)&1; + if (side == P_DivlineSide(tb->t2x, tb->t2y, (divline_t *) bsp)) + bspnum = bsp->children[side]; // doesn't touch the other side + else // the partition plane is crossed here + { + if (!P_CrossBSPNodeBlocking(bsp->children[side], tb)) + return false; // cross the starting side + else + bspnum = bsp->children[side^1]; // cross the ending side + } + } + + return P_CrossBlockingSubsector((bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR), tb); +} + +boolean P_TraceBlockingLines(mobj_t *t1, mobj_t *t2) +{ + const sector_t *s1, *s2; + size_t pnum; + traceblocking_t tb; + + // First check for trivial rejection. + if (!t1 || !t2) + return false; + + I_Assert(!P_MobjWasRemoved(t1)); + I_Assert(!P_MobjWasRemoved(t2)); + + if (!t1->subsector || !t2->subsector + || !t1->subsector->sector || !t2->subsector->sector) + return false; + + s1 = t1->subsector->sector; + s2 = t2->subsector->sector; + pnum = (s1-sectors)*numsectors + (s2-sectors); + + if (rejectmatrix != NULL) + { + // Check in REJECT table. + if (rejectmatrix[pnum>>3] & (1 << (pnum&7))) // can't possibly be connected + return false; + } + + // killough 11/98: shortcut for melee situations + // same subsector? obviously visible + // haleyjd 02/23/06: can't do this if there are polyobjects in the subsec + if (!t1->subsector->polyList && + t1->subsector == t2->subsector) + return true; + + validcount++; + + tb.strace.dx = (tb.t2x = t2->x) - (tb.strace.x = t1->x); + tb.strace.dy = (tb.t2y = t2->y) - (tb.strace.y = t1->y); + + if (t1->x > t2->x) + tb.bbox[BOXRIGHT] = t1->x, tb.bbox[BOXLEFT] = t2->x; + else + tb.bbox[BOXRIGHT] = t2->x, tb.bbox[BOXLEFT] = t1->x; + + if (t1->y > t2->y) + tb.bbox[BOXTOP] = t1->y, tb.bbox[BOXBOTTOM] = t2->y; + else + tb.bbox[BOXTOP] = t2->y, tb.bbox[BOXBOTTOM] = t1->y; + + tb.compareThing = t1; + + // the head node is the last node output + return P_CrossBSPNodeBlocking((INT32)numnodes - 1, &tb); +} From 5e5758a8e67ba3fdc4f99b3d8fed05277cc26784 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 6 Jan 2021 16:48:36 -0500 Subject: [PATCH 99/99] Sliptiding now stacks your handling boosts Also removed the METABOLISM define because I'm pretty sure we all like it at this point --- src/k_kart.c | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index c3faafbc6..ad61591a2 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2063,20 +2063,17 @@ fixed_t K_GetSpindashChargeSpeed(player_t *player) return (player->kartspeed + player->kartweight) * (FRACUNIT/64); } -// Light weights have stronger boost stacking -- aka, better metabolism than heavies XD -#define METABOLISM -// sets k_boostpower, k_speedboost, k_accelboost, and k_handleboost to whatever we need it to be +// sets boostpower, speedboost, accelboost, and handleboost to whatever we need it to be static void K_GetKartBoostPower(player_t *player) { -#ifdef METABOLISM + // Light weights have stronger boost stacking -- aka, better metabolism than heavies XD const fixed_t maxmetabolismincrease = FRACUNIT/2; const fixed_t metabolism = FRACUNIT - ((9-player->kartweight) * maxmetabolismincrease / 8); -#endif // METABOLISM // v2 almost broke sliptiding when it fixed turning bugs! // This value is fine-tuned to feel like v1 again without reverting any of those changes. - const fixed_t sliptidehandling = 7*FRACUNIT/10; + const fixed_t sliptidehandling = FRACUNIT/2; fixed_t boostpower = FRACUNIT; fixed_t speedboost = 0, accelboost = 0, handleboost = 0; @@ -2095,43 +2092,35 @@ static void K_GetKartBoostPower(player_t *player) if (player->kartstuff[k_bananadrag] > TICRATE) boostpower = (4*boostpower)/5; -#ifdef METABOLISM - + // Note: Handling will ONLY stack when sliptiding! + // When you're not, it just uses the best instead of adding together, like the old behavior. #define ADDBOOST(s,a,h) { \ numboosts++; \ speedboost += FixedDiv(s, FRACUNIT + (metabolism * (numboosts-1))); \ accelboost += FixedDiv(a, FRACUNIT + (metabolism * (numboosts-1))); \ - handleboost = max(h, handleboost); \ + if (player->kartstuff[k_aizdriftstrat]) \ + handleboost += FixedDiv(h, FRACUNIT + (metabolism * (numboosts-1))); \ + else \ + handleboost = max(h, handleboost); \ } -#else - -#define ADDBOOST(s,a,h) { \ - numboosts++; \ - speedboost += s / numboosts; \ - accelboost += a / numboosts; \ - handleboost = max(h, handleboost); \ -} - -#endif // METABOLISM - if (player->kartstuff[k_sneakertimer]) // Sneaker { UINT8 i; for (i = 0; i < player->kartstuff[k_numsneakers]; i++) { - ADDBOOST(FRACUNIT/2, 8*FRACUNIT, sliptidehandling); // + 50% top speed, + 800% acceleration, +70% handling + ADDBOOST(FRACUNIT/2, 8*FRACUNIT, sliptidehandling); // + 50% top speed, + 800% acceleration, +50% handling } } if (player->kartstuff[k_invincibilitytimer]) // Invincibility { - ADDBOOST(3*FRACUNIT/8, 3*FRACUNIT, sliptidehandling/3); // + 37.5% top speed, + 300% acceleration, +23% handling + ADDBOOST(3*FRACUNIT/8, 3*FRACUNIT, sliptidehandling/2); // + 37.5% top speed, + 300% acceleration, +25% handling } if (player->kartstuff[k_growshrinktimer] > 0) // Grow { - ADDBOOST(0, 0, sliptidehandling/3); // + 0% top speed, + 0% acceleration, +23% handling + ADDBOOST(0, 0, sliptidehandling/2); // + 0% top speed, + 0% acceleration, +25% handling } if (player->kartstuff[k_flamedash]) // Flame Shield dash @@ -2140,7 +2129,7 @@ static void K_GetKartBoostPower(player_t *player) ADDBOOST( dash, // + infinite top speed 3*FRACUNIT, // + 300% acceleration - FixedMul(FixedDiv(dash, FRACUNIT/2), sliptidehandling/3) // + infinite handling + FixedMul(FixedDiv(dash, FRACUNIT/2), sliptidehandling/2) // + infinite handling ); }