From b6a8df557ea5290b11d65cc0bd11d11ce58fa53d Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 27 May 2015 00:45:34 -0400 Subject: [PATCH 01/17] New Match weapon/ammo dropping method. P_PlayerWeaponPanelOrAmmoBurst will go through all of the player's weapon rings and either drop the weapon panel itself (with no ammo attached, and no ammo taken away!) OR if the player has ammo but no weapon, it drops the ammo instead (and you lose it). --- src/lua_baselib.c | 11 +++++++ src/p_inter.c | 77 +++++++++++++++++++++++++++++++++++++++++++---- src/p_local.h | 1 + 3 files changed, 83 insertions(+), 6 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9b0a34f17..57bee95ed 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1100,6 +1100,16 @@ static int lib_pPlayerWeaponAmmoBurst(lua_State *L) return 0; } +static int lib_pPlayerWeaponPanelOrAmmoBurst(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_PlayerWeaponPanelOrAmmoBurst(player); + return 0; +} + static int lib_pPlayerEmeraldBurst(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -1965,6 +1975,7 @@ static luaL_Reg lib[] = { {"P_PlayerRingBurst",lib_pPlayerRingBurst}, {"P_PlayerWeaponPanelBurst",lib_pPlayerWeaponPanelBurst}, {"P_PlayerWeaponAmmoBurst",lib_pPlayerWeaponAmmoBurst}, + {"P_PlayerWeaponPanelOrAmmoBurst", lib_pPlayerWeaponPanelOrAmmoBurst}, {"P_PlayerEmeraldBurst",lib_pPlayerEmeraldBurst}, {"P_PlayerFlagBurst",lib_pPlayerFlagBurst}, {"P_PlayRinglossSound",lib_pPlayRinglossSound}, diff --git a/src/p_inter.c b/src/p_inter.c index d305cfc83..97a8624c1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -437,7 +437,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { INT32 pindex = special->info->mass - (INT32)pw_infinityring; - player->powers[special->info->mass] += (UINT16)special->info->reactiontime; + player->powers[special->info->mass] += (UINT16)special->reactiontime; player->ringweapons |= 1 << (pindex-1); if (player->powers[special->info->mass] > rw_maximums[pindex]) @@ -3093,11 +3093,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) P_PlayerEmeraldBurst(player, false); // Spill weapons first - if (player->ringweapons) - P_PlayerWeaponPanelBurst(player); - - // Spill the ammo - P_PlayerWeaponAmmoBurst(player); + P_PlayerWeaponPanelOrAmmoBurst(player); for (i = 0; i < num_rings; i++) { @@ -3354,6 +3350,75 @@ void P_PlayerWeaponAmmoBurst(player_t *player) } } +void P_PlayerWeaponPanelOrAmmoBurst(player_t *player) +{ + mobj_t *mo; + angle_t fa; + fixed_t ns; + INT32 i = 0; + fixed_t z; + + #define SETUP_DROP(thingtype) \ + z = player->mo->z; \ + if (player->mo->eflags & MFE_VERTICALFLIP) \ + z += player->mo->height - mobjinfo[thingtype].height; \ + fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK; \ + ns = FixedMul(3*FRACUNIT, player->mo->scale); \ + + #define DROP_WEAPON(rwflag, pickup, ammo, power) \ + if (player->ringweapons & rwflag) \ + { \ + player->ringweapons &= ~rwflag; \ + SETUP_DROP(pickup) \ + mo = P_SpawnMobj(player->mo->x, player->mo->y, z, pickup); \ + mo->reactiontime = 0; \ + mo->flags2 |= MF2_DONTRESPAWN; \ + mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ + P_SetTarget(&mo->target, player->mo); \ + mo->fuse = 12*TICRATE; \ + mo->destscale = player->mo->scale; \ + P_SetScale(mo, player->mo->scale); \ + mo->momx = FixedMul(FINECOSINE(fa),ns); \ + if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ + mo->momy = FixedMul(FINESINE(fa),ns); \ + P_SetObjectMomZ(mo, 4*FRACUNIT, false); \ + if (i & 1) \ + P_SetObjectMomZ(mo, 4*FRACUNIT, true); \ + ++i; \ + } \ + else if (player->powers[power] > 0) \ + { \ + SETUP_DROP(ammo) \ + mo = P_SpawnMobj(player->mo->x, player->mo->y, z, ammo); \ + mo->health = player->powers[power]; \ + mo->flags2 |= MF2_DONTRESPAWN; \ + mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ + P_SetTarget(&mo->target, player->mo); \ + mo->fuse = 12*TICRATE; \ + mo->destscale = player->mo->scale; \ + P_SetScale(mo, player->mo->scale); \ + mo->momx = FixedMul(FINECOSINE(fa),ns); \ + if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ + mo->momy = FixedMul(FINESINE(fa),ns); \ + P_SetObjectMomZ(mo, 3*FRACUNIT, false); \ + if (i & 1) \ + P_SetObjectMomZ(mo, 3*FRACUNIT, true); \ + player->powers[power] = 0; \ + ++i; \ + } + + DROP_WEAPON(RW_BOUNCE, MT_BOUNCEPICKUP, MT_BOUNCERING, pw_bouncering); + DROP_WEAPON(RW_RAIL, MT_RAILPICKUP, MT_RAILRING, pw_railring); + DROP_WEAPON(RW_AUTO, MT_AUTOPICKUP, MT_AUTOMATICRING, pw_automaticring); + DROP_WEAPON(RW_EXPLODE, MT_EXPLODEPICKUP, MT_EXPLOSIONRING, pw_explosionring); + DROP_WEAPON(RW_SCATTER, MT_SCATTERPICKUP, MT_SCATTERRING, pw_scatterring); + DROP_WEAPON(RW_GRENADE, MT_GRENADEPICKUP, MT_GRENADERING, pw_grenadering); + DROP_WEAPON(0, 0, MT_INFINITYRING, pw_infinityring); + + #undef DROP_WEAPON + #undef SETUP_DROP +} + // // P_PlayerEmeraldBurst // diff --git a/src/p_local.h b/src/p_local.h index 1e0a9e2eb..337cc3663 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -371,6 +371,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget void P_PlayerRingBurst(player_t *player, INT32 num_rings); /// \todo better fit in p_user.c void P_PlayerWeaponPanelBurst(player_t *player); void P_PlayerWeaponAmmoBurst(player_t *player); +void P_PlayerWeaponPanelOrAmmoBurst(player_t *player); void P_PlayerEmeraldBurst(player_t *player, boolean toss); void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck); From 67fcff7ee7260e75cb6be8e708fc9ce44fe0bee3 Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 27 May 2015 01:13:26 -0400 Subject: [PATCH 02/17] New Match ammo consumption rules. Weapon rings can now be fired with no rings at double the ammo cost. --- src/p_user.c | 61 +++++++++++++++++--------------------------------- src/st_stuff.c | 2 +- 2 files changed, 22 insertions(+), 41 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 32dc8733f..1f13e6c38 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3130,72 +3130,64 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) mobj_t *mo = NULL; player->pflags |= PF_ATTACKDOWN; + #define TAKE_AMMO(player, power) \ + player->powers[power]--; \ + if (player->health <= 1) \ + { \ + if (player->powers[power] > 0) \ + player->powers[power]--; \ + } \ + else \ + { \ + player->health--; \ + player->mo->health--; \ + } + if (cmd->buttons & BT_FIRENORMAL) // No powers, just a regular ring. goto firenormal; //code repetition sucks. // Bounce ring else if (player->currentweapon == WEP_BOUNCE && player->powers[pw_bouncering]) { - if (player->health <= 1) - return; + TAKE_AMMO(player, pw_bouncering); P_SetWeaponDelay(player, TICRATE/4); mo = P_SpawnPlayerMissile(player->mo, MT_THROWNBOUNCE, MF2_BOUNCERING); if (mo) mo->fuse = 3*TICRATE; // Bounce Ring time - - player->powers[pw_bouncering]--; - player->mo->health--; - player->health--; } // Rail ring else if (player->currentweapon == WEP_RAIL && player->powers[pw_railring]) { - if (player->health <= 1) - return; + TAKE_AMMO(player, pw_railring); P_SetWeaponDelay(player, (3*TICRATE)/2); mo = P_SpawnPlayerMissile(player->mo, MT_REDRING, MF2_RAILRING|MF2_DONTDRAW); // Rail has no unique thrown object, therefore its sound plays here. S_StartSound(player->mo, sfx_rail1); - - player->powers[pw_railring]--; - player->mo->health--; - player->health--; } // Automatic else if (player->currentweapon == WEP_AUTO && player->powers[pw_automaticring]) { - if (player->health <= 1) - return; + TAKE_AMMO(player, pw_automaticring); player->pflags &= ~PF_ATTACKDOWN; P_SetWeaponDelay(player, 2); mo = P_SpawnPlayerMissile(player->mo, MT_THROWNAUTOMATIC, MF2_AUTOMATIC); - - player->powers[pw_automaticring]--; - player->mo->health--; - player->health--; } // Explosion else if (player->currentweapon == WEP_EXPLODE && player->powers[pw_explosionring]) { - if (player->health <= 1) - return; + TAKE_AMMO(player, pw_explosionring); P_SetWeaponDelay(player, (3*TICRATE)/2); mo = P_SpawnPlayerMissile(player->mo, MT_THROWNEXPLOSION, MF2_EXPLOSION); - - player->powers[pw_explosionring]--; - player->mo->health--; - player->health--; } // Grenade else if (player->currentweapon == WEP_GRENADE && player->powers[pw_grenadering]) { - if (player->health <= 1) - return; + TAKE_AMMO(player, pw_grenadering); P_SetWeaponDelay(player, TICRATE/3); mo = P_SpawnPlayerMissile(player->mo, MT_THROWNGRENADE, MF2_EXPLOSION); @@ -3205,10 +3197,6 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) //P_InstaThrust(mo, player->mo->angle, FixedMul(mo->info->speed, player->mo->scale)); mo->fuse = mo->info->mass; } - - player->powers[pw_grenadering]--; - player->mo->health--; - player->health--; } // Scatter // Note: Ignores MF2_RAILRING @@ -3218,8 +3206,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) angle_t shotangle = player->mo->angle; angle_t oldaiming = player->aiming; - if (player->health <= 1) - return; + TAKE_AMMO(player, pw_scatterring); P_SetWeaponDelay(player, (2*TICRATE)/3); // Center @@ -3245,10 +3232,6 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) player->mo->z = oldz; player->aiming = oldaiming; - - player->powers[pw_scatterring]--; - player->mo->health--; - player->health--; return; } // No powers, just a regular ring. @@ -3286,6 +3269,8 @@ firenormal: } } + #undef TAKE_AMMO + if (mo) { if (mo->flags & MF_MISSILE && mo->flags2 & MF2_RAILRING) @@ -9223,10 +9208,6 @@ void P_PlayerAfterThink(player_t *player) if (player->currentweapon == WEP_RAIL && (!(player->ringweapons & RW_RAIL) || !player->powers[pw_railring])) player->currentweapon = 0; - // If you're out of rings, but have Infinity Rings left, switch to that. - if (player->currentweapon != 0 && player->health <= 1 && player->powers[pw_infinityring]) - player->currentweapon = 0; - if (P_IsLocalPlayer(player) && (player->pflags & PF_WPNDOWN) && player->currentweapon != oldweapon) S_StartSound(NULL, sfx_wepchg); diff --git a/src/st_stuff.c b/src/st_stuff.c index 6e19b92ff..940d0f6fa 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1349,7 +1349,7 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I txtflags |= V_YELLOWMAP; if (weapon == pw_infinityring - || (stplyr->ringweapons & rwflag && stplyr->health > 1)) + || (stplyr->ringweapons & rwflag)) txtflags |= V_20TRANS; else { From c6c4ab7c53bbe3a70bbdd3f033dac83f7a4e9c7f Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 27 May 2015 02:08:18 -0400 Subject: [PATCH 03/17] New emerald behavior in Match. No longer turns you super, instead emeralds steal points from enemy players and give you (and relevant teammates) an invincibility + super sneakers monitor. --- src/lua_baselib.c | 23 ++++++++ src/p_inter.c | 132 +++++++++++++++++++++++++++------------------- src/p_local.h | 1 + src/p_user.c | 80 ++++++++++++++++------------ 4 files changed, 147 insertions(+), 89 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 57bee95ed..411dc00cf 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -561,6 +561,17 @@ static int lib_pAddPlayerScore(lua_State *L) return 0; } +static int lib_pStealPlayerScore(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + UINT32 amount = (UINT32)luaL_checkinteger(L, 2); + NOHUD + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_StealPlayerScore(player, amount); + return 0; +} + static int lib_pPlayerInPain(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -1217,6 +1228,16 @@ static int lib_pDoNightsScore(lua_State *L) return 0; } +static int lib_pDoMatchSuper(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_DoMatchSuper(player); + return 0; +} + // P_SPEC //////////// @@ -1925,6 +1946,7 @@ static luaL_Reg lib[] = { {"P_GetPlayerSpinHeight",lib_pGetPlayerSpinHeight}, {"P_GetPlayerControlDirection",lib_pGetPlayerControlDirection}, {"P_AddPlayerScore",lib_pAddPlayerScore}, + {"P_StealPlayerScore",lib_pStealPlayerScore}, {"P_PlayerInPain",lib_pPlayerInPain}, {"P_DoPlayerPain",lib_pDoPlayerPain}, {"P_ResetPlayer",lib_pResetPlayer}, @@ -1984,6 +2006,7 @@ static luaL_Reg lib[] = { {"P_PlayLivesJingle",lib_pPlayLivesJingle}, {"P_CanPickupItem",lib_pCanPickupItem}, {"P_DoNightsScore",lib_pDoNightsScore}, + {"P_DoMatchSuper",lib_pDoMatchSuper}, // p_spec {"P_Thrust",lib_pThrust}, diff --git a/src/p_inter.c b/src/p_inter.c index 97a8624c1..e7f671ad1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -217,6 +217,72 @@ void P_DoNightsScore(player_t *player) dummymo->destscale = 2*FRACUNIT; } +// +// P_DoMatchSuper +// +// Checks if you have all 7 pw_emeralds, then turns you "super". =P +// +void P_DoMatchSuper(player_t *player) +{ + UINT16 match_emeralds = player->powers[pw_emeralds]; + boolean doteams = false; + int i; + + // If this gametype has teams, check every player on your team for emeralds. + if (G_GametypeHasTeams()) + { + doteams = true; + for (i = 0; i < MAXPLAYERS; i++) + if (players[i].ctfteam == player->ctfteam) + match_emeralds |= players[i].powers[pw_emeralds]; + } + + if (!ALL7EMERALDS(match_emeralds)) + return; + + // Got 'em all? Turn "super"! + player->powers[pw_emeralds] = 0; + player->powers[pw_invulnerability] = invulntics + 1; + player->powers[pw_sneakers] = player->powers[pw_invulnerability]; + if (P_IsLocalPlayer(player) && !player->powers[pw_super]) + { + S_StopMusic(); + if (mariomode) + { + S_ChangeMusic(mus_minvnc, false); + G_GhostAddColor(GHC_INVINCIBLE); + } + else + S_ChangeMusic(mus_invinc, false); + } + + // Also steal 50 points from every enemy, sealing your victory. + P_StealPlayerScore(player, 50); + + // In a team game? + // Check everyone else on your team for emeralds, and turn those helpful assisting players invincible too. + if (doteams) + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].ctfteam == player->ctfteam + && players[i].powers[pw_emeralds] != 0) + { + players[i].powers[pw_emeralds] = 0; + player->powers[pw_invulnerability] = invulntics + 1; + player->powers[pw_sneakers] = player->powers[pw_invulnerability]; + if (P_IsLocalPlayer(player) && !player->powers[pw_super]) + { + S_StopMusic(); + if (mariomode) + { + S_ChangeMusic(mus_minvnc, false); + G_GhostAddColor(GHC_INVINCIBLE); + } + else + S_ChangeMusic(mus_invinc, false); + } + } +} + /** Takes action based on a ::MF_SPECIAL thing touched by a player. * Actually, this just checks a few things (heights, toucher->player, no * objectplace, no dead or disappearing things) @@ -524,7 +590,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; if (special->threshold) + { player->powers[pw_emeralds] |= special->info->speed; + P_DoMatchSuper(player); + } else emeralds |= special->info->speed; @@ -545,6 +614,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; player->powers[pw_emeralds] |= special->threshold; + P_DoMatchSuper(player); break; // Secret emblem thingy @@ -1356,7 +1426,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } if (player->powers[pw_invulnerability] || player->powers[pw_flashing] - || (player->powers[pw_super] && !(ALL7EMERALDS(player->powers[pw_emeralds])))) + || player->powers[pw_super]) return; if (player->powers[pw_shield] || player->bot) //If One-Hit Shield { @@ -2434,16 +2504,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou P_PlayerRingBurst(player, player->mo->health - 1); } - if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - { - player->health -= 10; - if (player->health < 2) - player->health = 2; - target->health = player->health; - } - else - player->health = target->health = 1; - + player->health = target->health = 1; return true; } @@ -2654,16 +2715,6 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { - if (!(inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - { - P_DoPlayerPain(player, source, inflictor); - - P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); - - if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes - S_StartSound(player->mo, sfx_spkdth); - } - if (source && source->player && !player->powers[pw_super]) //don't score points against super players { // Award no points when players shoot each other when cv_friendlyfire is on. @@ -2913,7 +2964,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } } else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] // ignore bouncing & such in invulnerability - || (player->powers[pw_super] && !(ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player)))) + || player->powers[pw_super]) { if (force || (inflictor && (inflictor->flags & MF_MISSILE) && (inflictor->flags2 & MF2_SUPERFIRE) @@ -2960,24 +3011,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } } - if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - { - if (player->powers[pw_shield]) - { - P_RemoveShield(player); - return true; - } - else - { - player->health -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500))); - if (player->health < 2) - player->health = 2; - } - - if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) - P_PlayerFlagBurst(player, false); - } - else if (damagetype & DMG_DEATHMASK) + if (damagetype & DMG_DEATHMASK) player->health = 0; else { @@ -3001,13 +3035,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_DamageMobj(source, target, target, 1, 0); // do the damage - if (player && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player)) - { - target->health -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500))); - if (target->health < 2) - target->health = 2; - } - else if (damagetype & DMG_DEATHMASK) + if (damagetype & DMG_DEATHMASK) target->health = 0; else target->health -= damage; @@ -3022,10 +3050,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } if (player) - { - if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - P_ResetPlayer(target->player); - } + P_ResetPlayer(target->player); else switch (target->type) { @@ -3051,10 +3076,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (target->state == &states[target->info->spawnstate] && target->info->seestate != S_NULL) { if (player) - { - if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - P_SetPlayerMobjState(target, target->info->seestate); - } + P_SetPlayerMobjState(target, target->info->seestate); else P_SetMobjState(target, target->info->seestate); } diff --git a/src/p_local.h b/src/p_local.h index 337cc3663..b23f9fdf8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -385,6 +385,7 @@ void P_ResetStarposts(void); boolean P_CanPickupItem(player_t *player, boolean weapon); void P_DoNightsScore(player_t *player); +void P_DoMatchSuper(player_t *player); // // P_SPEC diff --git a/src/p_user.c b/src/p_user.c index 1f13e6c38..14c87a503 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -997,6 +997,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) P_PlayerFlagBurst(player, false); } + // Adds to the player's score void P_AddPlayerScore(player_t *player, UINT32 amount) { @@ -1083,6 +1084,42 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) } } +// Steals from every enemy's score. +void P_StealPlayerScore(player_t *player, UINT32 amount) +{ + boolean teams = G_GametypeHasTeams(); + UINT32 stolen = 0; + int i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (&players[i] == player + || (teams && players[i].ctfteam == player->ctfteam)) + continue; + if (players[i].score >= amount) + { + stolen += amount; + players[i].score -= amount; + } + else + { + stolen += players[i].score; + players[i].score = 0; + } + } + if (stolen > 0) + { + // In team match, all stolen points are removed from the enemy team's running score. + if (gametype == GT_TEAMMATCH) + { + if (player->ctfteam == 1) + bluescore -= amount; + else if (player->ctfteam == 2) + redscore -= amount; + } + P_AddPlayerScore(player, stolen); + } +} + // // P_PlayLivesJingle // @@ -3321,7 +3358,7 @@ static void P_DoSuperStuff(player_t *player) return; // NiGHTS Super doesn't mix with normal super // Does player have all emeralds? If so, flag the "Ready For Super!" - if ((ALL7EMERALDS(emeralds) || ALL7EMERALDS(player->powers[pw_emeralds])) && player->health > 50) + if (ALL7EMERALDS(emeralds) && player->health > 50) player->pflags |= PF_SUPERREADY; else player->pflags &= ~PF_SUPERREADY; @@ -3329,7 +3366,7 @@ static void P_DoSuperStuff(player_t *player) if (player->powers[pw_super]) { // If you're super and not Sonic, de-superize! - if (!((ALL7EMERALDS(emeralds)) && (player->charflags & SF_SUPER)) && !(ALL7EMERALDS(player->powers[pw_emeralds]))) + if (!(ALL7EMERALDS(emeralds) && player->charflags & SF_SUPER)) { player->powers[pw_super] = 0; P_SetPlayerMobjState(player->mo, S_PLAY_STND); @@ -3462,12 +3499,12 @@ static void P_DoSuperStuff(player_t *player) // boolean P_SuperReady(player_t *player) { - if ((player->pflags & PF_SUPERREADY) && !player->powers[pw_super] && !player->powers[pw_tailsfly] + if (player->pflags & PF_SUPERREADY && !player->powers[pw_super] && !player->powers[pw_tailsfly] && !(player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_invulnerability] && !(maptol & TOL_NIGHTS) // don't turn 'regular super' in nights levels && player->pflags & PF_JUMPED - && ((player->charflags & SF_SUPER) || ALL7EMERALDS(player->powers[pw_emeralds]))) + && player->charflags & SF_SUPER) return true; return false; @@ -3995,13 +4032,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags |= PF_GLIDING|PF_THOKKED; player->glidetime = 0; - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - { - // Glide at double speed while super. - glidespeed *= 2; - player->pflags &= ~PF_THOKKED; - } - P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); P_InstaThrust(player->mo, player->mo->angle, FixedMul(glidespeed, player->mo->scale)); player->pflags &= ~(PF_SPINNING|PF_STARTDASH); @@ -4115,8 +4145,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags &= ~PF_JUMPDOWN; // Repeat abilities, but not double jump! - if ((player->charability2 == CA2_MULTIABILITY && player->charability != CA_DOUBLEJUMP) - || (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) + if (player->charability2 == CA2_MULTIABILITY && player->charability != CA_DOUBLEJUMP) player->secondjump = 0; else if (player->charability == CA_FLOAT && player->secondjump == 1) player->secondjump = 2; @@ -4360,9 +4389,6 @@ static void P_2dMovement(player_t *player) if (cmd->forwardmove != 0) P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT,10*FRACUNIT), false); - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - player->mo->momz *= 2; - player->mo->momx = 0; } else if (cmd->sidemove != 0 && !(player->pflags & PF_GLIDING || player->exiting @@ -4556,11 +4582,7 @@ static void P_3dMovement(player_t *player) if (player->climbing) { if (cmd->forwardmove) - { P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 10*FRACUNIT), false); - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - player->mo->momz *= 2; - } } else if (!analogmove && cmd->forwardmove != 0 && !(player->pflags & PF_GLIDING || player->exiting @@ -4601,12 +4623,7 @@ static void P_3dMovement(player_t *player) } // Sideways movement if (player->climbing) - { - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 5*FRACUNIT), player->mo->scale)); - else - P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 10*FRACUNIT), player->mo->scale)); - } + P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 10*FRACUNIT), player->mo->scale)); // Analog movement control else if (analogmove) { @@ -6510,8 +6527,8 @@ static void P_MovePlayer(player_t *player) P_ResetPlayer(player); // down, stop gliding. if (onground) P_SetPlayerMobjState(player->mo, S_PLAY_WALK); - else if ((player->charability2 == CA2_MULTIABILITY) - || (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && player->charability == CA_GLIDEANDCLIMB)) + else if (player->charability2 == CA2_MULTIABILITY + && player->charability == CA_GLIDEANDCLIMB) { player->pflags |= PF_JUMPED; P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); @@ -6764,11 +6781,6 @@ static void P_MovePlayer(player_t *player) { if ((player->powers[pw_shield] & SH_NOSTACK) == SH_JUMP && !player->powers[pw_super]) P_DoJumpShield(player); - else if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && player->charability == CA_FLY) - { - P_DoJumpShield(player); - player->mo->momz *= 2; - } } // Bomb shield activation if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB) @@ -8924,7 +8936,7 @@ void P_PlayerThink(player_t *player) if (player->powers[pw_flashing] && player->powers[pw_flashing] < UINT16_MAX && ((player->pflags & PF_NIGHTSMODE) || player->powers[pw_flashing] < flashingtics)) player->powers[pw_flashing]--; - if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM && !(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) // tails fly counter + if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM) // tails fly counter player->powers[pw_tailsfly]--; if (player->powers[pw_underwater] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)) From 1c1acb9f0e9ac543b33604a7173b7c6d78291f19 Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 27 May 2015 04:01:58 -0400 Subject: [PATCH 04/17] Add emeraldspawndelay for Match "super" Emeralds will not spawn while players are still enjoying their victory dance now. --- src/g_game.c | 1 + src/p_inter.c | 5 +++-- src/p_mobj.c | 8 +++----- src/p_mobj.h | 1 + src/p_setup.c | 1 + 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 643ec8c93..7176d90dc 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -86,6 +86,7 @@ UINT8 modeattacking = ATTACKING_NONE; boolean disableSpeedAdjust = false; boolean imcontinuing = false; boolean runemeraldmanager = false; +UINT16 emeraldspawndelay = 60*TICRATE; // menu demo things UINT8 numDemos = 3; diff --git a/src/p_inter.c b/src/p_inter.c index e7f671ad1..d5c82fefc 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -241,9 +241,10 @@ void P_DoMatchSuper(player_t *player) return; // Got 'em all? Turn "super"! + emeraldspawndelay = invulntics + 1; player->powers[pw_emeralds] = 0; - player->powers[pw_invulnerability] = invulntics + 1; - player->powers[pw_sneakers] = player->powers[pw_invulnerability]; + player->powers[pw_invulnerability] = emeraldspawndelay; + player->powers[pw_sneakers] = emeraldspawndelay; if (P_IsLocalPlayer(player) && !player->powers[pw_super]) { S_StopMusic(); diff --git a/src/p_mobj.c b/src/p_mobj.c index 9565648c2..7742d63e1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -657,14 +657,12 @@ void P_EmeraldManager(void) else break; - if (leveltime < TICRATE) // Start of map - spawnpoints[j]->threshold = 60*TICRATE + P_Random() * (TICRATE/5); - else - spawnpoints[j]->threshold = P_Random() * (TICRATE/5); - + spawnpoints[j]->threshold = emeraldspawndelay + P_Random() * (TICRATE/5); break; } } + + emeraldspawndelay = 0; } // diff --git a/src/p_mobj.h b/src/p_mobj.h index 8e782b92e..5a4e01caf 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -444,5 +444,6 @@ void P_EmeraldManager(void); extern mapthing_t *huntemeralds[MAXHUNTEMERALDS]; extern INT32 numhuntemeralds; extern boolean runemeraldmanager; +extern UINT16 emeraldspawndelay; extern INT32 numstarposts; #endif diff --git a/src/p_setup.c b/src/p_setup.c index f2b0c49d8..196f6a471 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2015,6 +2015,7 @@ static void P_LevelInitStuff(void) // special stage tokens, emeralds, and ring total tokenbits = 0; runemeraldmanager = false; + emeraldspawndelay = 60*TICRATE; nummaprings = 0; // emerald hunt From 7118925959f16fab6be85c3138280f78640fe92c Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 27 May 2015 06:43:24 -0400 Subject: [PATCH 05/17] Fix broken P_RingDamage bug from c6c4ab7c Accidentally snipped too much out of P_DamageMobj's subfunctions... --- src/p_inter.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/p_inter.c b/src/p_inter.c index d5c82fefc..7fb81dede 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2716,6 +2716,13 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { + P_DoPlayerPain(player, source, inflictor); + + P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); + + if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes + S_StartSound(player->mo, sfx_spkdth); + if (source && source->player && !player->powers[pw_super]) //don't score points against super players { // Award no points when players shoot each other when cv_friendlyfire is on. From bed8dc4c7c8c87a4af19fb75ac27bb2b00259413 Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Thu, 28 May 2015 03:24:55 -0400 Subject: [PATCH 06/17] Tails ringslinger buff. Any character with CA_FLY will now throw rings 1.5x as fast. --- src/p_mobj.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 7742d63e1..3f6d039a0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9534,7 +9534,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai { mobj_t *th; angle_t an; - fixed_t x, y, z, slope = 0; + fixed_t x, y, z, slope = 0, speed; // angle at which you fire, is player angle an = angle; @@ -9566,9 +9566,13 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai P_SetTarget(&th->target, source); + speed = th->info->speed; + if (source->player && source->player->charability == CA_FLY) + speed = FixedMul(speed, 3*FRACUNIT/2); + th->angle = an; - th->momx = FixedMul(th->info->speed, FINECOSINE(an>>ANGLETOFINESHIFT)); - th->momy = FixedMul(th->info->speed, FINESINE(an>>ANGLETOFINESHIFT)); + th->momx = FixedMul(speed, FINECOSINE(an>>ANGLETOFINESHIFT)); + th->momy = FixedMul(speed, FINESINE(an>>ANGLETOFINESHIFT)); if (allowaim) { @@ -9576,7 +9580,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai th->momy = FixedMul(th->momy,FINECOSINE(source->player->aiming>>ANGLETOFINESHIFT)); } - th->momz = FixedMul(th->info->speed, slope); + th->momz = FixedMul(speed, slope); //scaling done here so it doesn't clutter up the code above th->momx = FixedMul(th->momx, th->scale); From 8cde0121d03f140c476e538be88b063c286f835c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 14 Aug 2015 15:55:24 +0100 Subject: [PATCH 07/17] Remove the switch-to-seestate behavior in P_DamageMobj. In Doom there was a random chance of enemies either being stunned (painstate) or instead just deciding to attack you (seetstate), but in SRB2 painstate is ALWAYS used beforehand. --- src/p_inter.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index d305cfc83..146be5077 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3048,16 +3048,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // if not intent on another player, // chase after this one P_SetTarget(&target->target, source); - if (target->state == &states[target->info->spawnstate] && target->info->seestate != S_NULL) - { - if (player) - { - if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - P_SetPlayerMobjState(target, target->info->seestate); - } - else - P_SetMobjState(target, target->info->seestate); - } } return true; From 6bc1a5fdefbeeb710cab5ebd8ddf7cd161f0cd24 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 15 Aug 2015 21:07:16 +0100 Subject: [PATCH 08/17] Okay, major overhaul time! *player->health (formerly the "HUD" health) is now to be known as player->rings, and now acts as the player's actual ring count *player->mo->health (formerly rings + 1) is now always 1 when alive, regardless of ring count; if player with rings is damaged, this is untouched Damage in normal SP/Coop gameplay has been tested and still works fine; still a lot of mess to clear up though Tag damaging probably is broken now, I'll fix this later --- src/d_clisrv.c | 7 ++- src/d_clisrv.h | 3 +- src/d_netcmd.c | 2 +- src/d_player.h | 6 +-- src/g_game.c | 2 +- src/hu_stuff.c | 36 +++++++------- src/lua_baselib.c | 2 +- src/lua_playerlib.c | 8 ++-- src/m_cheat.c | 6 +-- src/m_menu.c | 4 +- src/p_enemy.c | 18 +++---- src/p_inter.c | 79 +++++++++++++++---------------- src/p_mobj.c | 17 +++---- src/p_saveg.c | 4 +- src/p_setup.c | 2 +- src/p_spec.c | 22 ++++----- src/p_tick.c | 2 +- src/p_user.c | 113 ++++++++++++++++---------------------------- src/st_stuff.c | 18 +++---- src/y_inter.c | 14 +++--- 20 files changed, 164 insertions(+), 201 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index c0179ca1b..d08badd4a 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -495,7 +495,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->powers[j] = (UINT16)SHORT(players[i].powers[j]); // Score is resynched in the rspfirm resync packet - rsp->health = 0; // resynched with mo health + rsp->rings = LONG(players[i].rings); rsp->lives = players[i].lives; rsp->continues = players[i].continues; rsp->scoreadd = players[i].scoreadd; @@ -577,7 +577,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->hasmo = true; rsp->health = LONG(players[i].mo->health); - rsp->angle = (angle_t)LONG(players[i].mo->angle); rsp->x = LONG(players[i].mo->x); rsp->y = LONG(players[i].mo->y); @@ -620,7 +619,7 @@ static void resynch_read_player(resynch_pak *rsp) players[i].powers[j] = (UINT16)SHORT(rsp->powers[j]); // Score is resynched in the rspfirm resync packet - players[i].health = rsp->health; + players[i].rings = LONG(rsp->rings); players[i].lives = rsp->lives; players[i].continues = rsp->continues; players[i].scoreadd = rsp->scoreadd; @@ -2244,7 +2243,7 @@ static void CL_RemovePlayer(INT32 playernum) } count--; - rings = players[playernum].health - 1; + rings = players[playernum].rings; increment = rings/count; for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 6bc06f13a..bf07f035c 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -155,7 +155,7 @@ typedef struct UINT16 powers[NUMPOWERS]; // Score is resynched in the confirm resync packet - INT32 health; + INT32 rings; SINT8 lives; SINT8 continues; UINT8 scoreadd; @@ -231,6 +231,7 @@ typedef struct //player->mo stuff UINT8 hasmo; //boolean + INT32 health; angle_t angle; fixed_t x; fixed_t y; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 557715064..537588e4b 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2558,7 +2558,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) if (players[playernum].spectator) { players[playernum].score = 0; - players[playernum].health = 1; + players[playernum].rings = 0; if (players[playernum].mo) players[playernum].mo->health = 1; } diff --git a/src/d_player.h b/src/d_player.h index e2a1081b0..8c3df4883 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -278,10 +278,8 @@ typedef struct player_s // It is updated with cmd->aiming. angle_t aiming; - // This is only used between levels, - // mo->health is used during levels. - /// \todo Remove this. We don't need a second health definition for players. - INT32 health; + // player's ring count + INT32 rings; SINT8 pity; // i pity the fool. INT32 currentweapon; // current weapon selected. diff --git a/src/g_game.c b/src/g_game.c index 643ec8c93..41b875ce7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2177,7 +2177,7 @@ void G_PlayerReborn(INT32 player) p->pflags |= PF_JUMPDOWN; p->playerstate = PST_LIVE; - p->health = 1; // 0 rings + p->rings = 0; // 0 rings p->panim = PA_IDLE; // standing animation if ((netgame || multiplayer) && !p->spectator) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 80e30beb5..dd7418f60 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1198,7 +1198,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].health > 0) ? 0 : V_60TRANS) + | ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS) | V_ALLOWLOWERCASE, tab[i].name); // Draw emeralds @@ -1208,7 +1208,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I HU_DrawEmeralds(x-12,y+2,tab[i].emeralds); } - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentPatch (x, y-4, V_80TRANS, livesback); else V_DrawSmallScaledPatch (x, y-4, 0, livesback); @@ -1220,7 +1220,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I V_DrawSmallScaledPatch(x, y-4, 0, superprefix[players[tab[i].num].skin]); else { - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentPatch(x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin]); else V_DrawSmallScaledPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin]); @@ -1236,7 +1236,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentMappedPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin], colormap); else V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); @@ -1244,10 +1244,10 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I } if (G_GametypeUsesLives()) //show lives - V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%dx", players[tab[i].num].lives)); + V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%dx", players[tab[i].num].lives)); else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) { - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentPatch(x-32, y-4, V_60TRANS, tagico); else V_DrawSmallScaledPatch(x-32, y-4, 0, tagico); @@ -1260,13 +1260,13 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I if (players[tab[i].num].exiting) V_DrawRightAlignedString(x+240, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); + V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); } else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); + V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); } else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); + V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); y += 16; } @@ -1311,7 +1311,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) strlcpy(name, tab[i].name, 9); V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) + | ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT) | V_ALLOWLOWERCASE, name); if (gametype == GT_CTF) @@ -1337,12 +1337,12 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); else V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); } - V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); } } @@ -1367,7 +1367,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline strlcpy(name, tab[i].name, 9); V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) + | ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT) | V_ALLOWLOWERCASE, name); if (G_GametypeUsesLives()) //show lives @@ -1390,7 +1390,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline V_DrawSmallScaledPatch (x, y-4, 0, superprefix[players[tab[i].num].skin]); else { - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin]); else V_DrawSmallScaledPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin]); @@ -1406,7 +1406,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); else V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); @@ -1421,13 +1421,13 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline if (players[tab[i].num].exiting) V_DrawRightAlignedThinString(x+156, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); else - V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); } else - V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); + V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); } else - V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); y += 16; if (y > 160) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 2a5ff8d65..50324d8f2 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1068,7 +1068,7 @@ static int lib_pPlayerRingBurst(lua_State *L) if (!player) return LUA_ErrInvalid(L, "player_t"); if (num_rings == -1) - num_rings = player->health - 1; + num_rings = player->rings; P_PlayerRingBurst(player, num_rings); return 0; } diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 64513ab97..64396670b 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -118,8 +118,8 @@ static int player_get(lua_State *L) lua_pushfixed(L, plr->bob); else if (fastcmp(field,"aiming")) lua_pushangle(L, plr->aiming); - else if (fastcmp(field,"health")) - lua_pushinteger(L, plr->health); + else if (fastcmp(field,"rings")) + lua_pushinteger(L, plr->rings); else if (fastcmp(field,"pity")) lua_pushinteger(L, plr->pity); else if (fastcmp(field,"currentweapon")) @@ -368,8 +368,8 @@ static int player_set(lua_State *L) else if (plr == &players[secondarydisplayplayer]) localaiming2 = plr->aiming; } - else if (fastcmp(field,"health")) - plr->health = (INT32)luaL_checkinteger(L, 3); + else if (fastcmp(field,"rings")) + plr->rings = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"pity")) plr->pity = (SINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"currentweapon")) diff --git a/src/m_cheat.c b/src/m_cheat.c index 4da9b3ba7..dde3376f8 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -625,7 +625,7 @@ void Command_CauseCfail_f(void) players[consoleplayer].mo->y = 123311; //cfail cansuled kthxbye players[consoleplayer].mo->z = 123311; players[consoleplayer].score = 1337; - players[consoleplayer].health = 1337; + players[consoleplayer].rings = 1337; players[consoleplayer].mo->destscale = 25; P_SetThingPosition(players[consoleplayer].mo); @@ -739,7 +739,7 @@ void Command_Setrings_f(void) if (COM_Argc() > 1) { // P_GivePlayerRings does value clamping - players[consoleplayer].health = players[consoleplayer].mo->health = 1; + players[consoleplayer].rings = 0; P_GivePlayerRings(&players[consoleplayer], atoi(COM_Argv(1))); if (!G_IsSpecialStage(gamemap) || !useNightsSS) players[consoleplayer].totalring -= atoi(COM_Argv(1)); //undo totalring addition done in P_GivePlayerRings @@ -1241,7 +1241,7 @@ void Command_ObjectPlace_f(void) // Like the classics, recover from death by entering objectplace if (players[0].mo->health <= 0) { - players[0].mo->health = players[0].health = 1; + players[0].mo->health = 1; players[0].deadtimer = 0; op_oldflags1 = mobjinfo[MT_PLAYER].flags; ++players[0].lives; diff --git a/src/m_menu.c b/src/m_menu.c index 88893b3c6..f19c4da3d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3789,7 +3789,7 @@ static void M_HandleImageDef(INT32 choice) static void M_PandorasBox(INT32 choice) { (void)choice; - CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].health - 1, 0)); + CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].rings, 0)); CV_StealthSetValue(&cv_dummylives, players[consoleplayer].lives); CV_StealthSetValue(&cv_dummycontinues, players[consoleplayer].continues); M_SetupNextMenu(&SR_PandoraDef); @@ -3797,7 +3797,7 @@ static void M_PandorasBox(INT32 choice) static boolean M_ExitPandorasBox(void) { - if (cv_dummyrings.value != max(players[consoleplayer].health - 1, 0)) + if (cv_dummyrings.value != max(players[consoleplayer].rings, 0)) COM_ImmedExecute(va("setrings %d", cv_dummyrings.value)); if (cv_dummylives.value != players[consoleplayer].lives) COM_ImmedExecute(va("setlives %d", cv_dummylives.value)); diff --git a/src/p_enemy.c b/src/p_enemy.c index 3cc9aaca2..303e74880 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -655,15 +655,15 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed if ((netgame || multiplayer) && player->spectator) continue; - if (player->health <= 0) - continue; // dead - if (player->pflags & PF_INVIS) continue; // ignore notarget if (!player->mo || P_MobjWasRemoved(player->mo)) continue; + if (player->mo->health <= 0) + continue; // dead + if (dist > 0 && P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist) continue; // Too far away @@ -727,7 +727,7 @@ static boolean P_LookForShield(mobj_t *actor) player = &players[actor->lastlook]; - if (player->health <= 0 || !player->mo) + if (!player->mo || player->mo->health <= 0) continue; // dead //When in CTF, don't pull rings that you cannot pick up. @@ -2721,7 +2721,7 @@ void A_BossDeath(mobj_t *mo) // make sure there is a player alive for victory for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (players[i].health > 0 + if (playeringame[i] && ((players[i].mo && players[i].mo->health > 0) || ((netgame || multiplayer) && (players[i].lives > 0 || players[i].continues > 0)))) break; @@ -8268,7 +8268,7 @@ void A_RingDrain(mobj_t *actor) } player = actor->target->player; - P_GivePlayerRings(player, -min(locvar1, player->mo->health-1)); + P_GivePlayerRings(player, -min(locvar1, player->rings)); } // Function: A_SplitShot @@ -8578,7 +8578,7 @@ void A_CheckTargetRings(mobj_t *actor) if (!(actor->target) || !(actor->target->player)) return; - if (actor->target->player->health >= locvar1) + if (actor->target->player->rings >= locvar1) P_SetMobjState(actor, locvar2); } @@ -8600,7 +8600,7 @@ void A_CheckRings(mobj_t *actor) #endif for (i = 0; i < MAXPLAYERS; i++) - cntr += players[i].health-1; + cntr += players[i].rings; if (cntr >= locvar1) P_SetMobjState(actor, locvar2); @@ -9172,7 +9172,7 @@ void A_ForceWin(mobj_t *actor) for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && (players[i].health > 0 + if (playeringame[i] && ((players[i].mo && players[i].mo->health > 0) || ((netgame || multiplayer) && (players[i].lives > 0 || players[i].continues > 0)))) break; } diff --git a/src/p_inter.c b/src/p_inter.c index de90f419e..3bf0e68a5 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -796,16 +796,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (G_IsSpecialStage(gamemap) && !player->exiting) { // In special stages, share rings. Everyone gives up theirs to the player who touched the capsule for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (&players[i] != player) && players[i].mo->health > 1) + if (playeringame[i] && (&players[i] != player) && players[i].rings > 0) { - toucher->health += players[i].mo->health-1; - player->health = toucher->health; - players[i].mo->health = 1; - players[i].health = players[i].mo->health; + player->rings += players[i].rings; + players[i].rings = 0; } } - if (!(player->health > 1) || player->exiting) + if (player->rings <= 0 || player->exiting) return; // Mark the player as 'pull into the capsule' @@ -1366,11 +1364,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) else { P_PlayRinglossSound(toucher); - if (toucher->health > 10) - toucher->health -= 10; + if (player->rings >= 10) + player->rings -= 10; else - toucher->health = 1; - player->health = toucher->health; + player->rings = 0; } P_DoPlayerPain(player, special, NULL); @@ -1475,6 +1472,9 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour if (!player) return; // Impossible! + if (!player->mo) + return; // Also impossible! + if (!netgame) return; // Presumably it's obvious what's happening in splitscreen. @@ -1483,7 +1483,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour return; #endif - deadtarget = (player->health <= 0); + deadtarget = (player->mo->health <= 0); // Target's name snprintf(targetname, sizeof(targetname), "%s%s%s", @@ -2428,26 +2428,25 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou return true; } - if (target->health <= 1) // Death + if (player->rings > 0) // Ring loss + { + P_PlayRinglossSound(target); + P_PlayerRingBurst(player, player->rings); + } + else // Death { P_PlayDeathSound(target); P_PlayVictorySound(source); // Killer laughs at you! LAUGHS! BWAHAHAHHAHAA!! } - else if (target->health > 1) // Ring loss - { - P_PlayRinglossSound(target); - P_PlayerRingBurst(player, player->mo->health - 1); - } if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) { - player->health -= 10; - if (player->health < 2) - player->health = 2; - target->health = player->health; + player->rings -= 10; + if (player->rings < 1) + player->rings = 1; } else - player->health = target->health = 1; + player->rings = 0; return true; } @@ -2497,7 +2496,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) // Burst weapons and emeralds in Match/CTF only if (source && (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF)) { - P_PlayerRingBurst(player, player->health - 1); + P_PlayerRingBurst(player, player->rings); P_PlayerEmeraldBurst(player, false); } @@ -2942,9 +2941,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_ShieldDamage(player, inflictor, source, damage); damage = 0; } - else if (player->mo->health > 1) // No shield but have rings. + else if (player->rings > 0) // No shield but have rings. { - damage = player->mo->health - 1; + damage = player->rings; P_RingDamage(player, inflictor, source, damage, damagetype); } else // No shield, no rings, no invincibility. @@ -2974,26 +2973,28 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } else { - player->health -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500))); - if (player->health < 2) - player->health = 2; + player->rings -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500))); + if (player->rings < 1) + player->rings = 1; } if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) P_PlayerFlagBurst(player, false); + damage = 0; } else if (damagetype & DMG_DEATHMASK) - player->health = 0; - else + player->rings = 0; + else if (damage == 0 || player->rings) //quickfix to just get things back to normal ...for now (sans Tag, I'll deal with that later) { - player->health -= damage; // mirror mobj health here - target->player->powers[pw_flashing] = flashingtics; if (damage > 0) // don't spill emeralds/ammo/panels for shield damage P_PlayerRingBurst(player, damage); + player->rings -= damage; + target->player->powers[pw_flashing] = flashingtics; + damage = 0; } - if (player->health < 0) - player->health = 0; + if (player->rings < 0) + player->rings = 0; P_HitDeathMessages(player, inflictor, source, damagetype); @@ -3006,13 +3007,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_DamageMobj(source, target, target, 1, 0); // do the damage - if (player && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player)) - { - target->health -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500))); - if (target->health < 2) - target->health = 2; - } - else if (damagetype & DMG_DEATHMASK) + if (damagetype & DMG_DEATHMASK) target->health = 0; else target->health -= damage; @@ -3078,7 +3073,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) return; // If no health, don't spawn ring! - if (player->mo->health <= 1) + if (player->rings <= 0) num_rings = 0; if (num_rings > 32 && !(player->pflags & PF_NIGHTSFALL)) diff --git a/src/p_mobj.c b/src/p_mobj.c index 8ea71d6c7..d0a6b2432 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3357,15 +3357,15 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest) player = &players[actor->lastlook]; - if (player->health <= 0) - continue; // dead - if (player->pflags & PF_INVIS || player->bot || player->spectator) continue; // ignore notarget if (!player->mo || P_MobjWasRemoved(player->mo)) continue; + if (player->mo->health <= 0) + continue; //dead + if (!P_CheckSight(actor, player->mo)) continue; // out of sight @@ -3395,15 +3395,15 @@ boolean P_SupermanLook4Players(mobj_t *actor) { if (playeringame[c]) { - if (players[c].health <= 0) - continue; // dead - if (players[c].pflags & PF_INVIS) continue; // ignore notarget if (!players[c].mo || players[c].bot) continue; + if (players[c].mo->health <= 0) + continue; // dead + playersinthegame[stop] = &players[c]; stop++; } @@ -6175,7 +6175,7 @@ void P_MobjThinker(mobj_t *mobj) P_SetTarget(&mobj->target, NULL); for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo - && players[i].mare == mobj->threshold && players[i].health > 1) + && players[i].mare == mobj->threshold && players[i].rings > 0) { fixed_t dist = P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y); if (dist < shortest) @@ -7819,7 +7819,8 @@ void P_SpawnPlayer(INT32 playernum) // the dead body mobj retains the skin through the 'spritedef' override). mobj->skin = &skins[p->skin]; - mobj->health = p->health; + mobj->health = 1; + p->rings = 0; p->playerstate = PST_LIVE; p->bonustime = false; diff --git a/src/p_saveg.c b/src/p_saveg.c index 2afcfd0ef..5a2da118b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -125,7 +125,7 @@ static inline void P_NetArchivePlayers(void) WRITEANGLE(save_p, players[i].aiming); WRITEANGLE(save_p, players[i].awayviewaiming); WRITEINT32(save_p, players[i].awayviewtics); - WRITEINT32(save_p, players[i].health); + WRITEINT32(save_p, players[i].rings); WRITESINT8(save_p, players[i].pity); WRITEINT32(save_p, players[i].currentweapon); @@ -300,7 +300,7 @@ static inline void P_NetUnArchivePlayers(void) players[i].aiming = READANGLE(save_p); players[i].awayviewaiming = READANGLE(save_p); players[i].awayviewtics = READINT32(save_p); - players[i].health = READINT32(save_p); + players[i].rings = READINT32(save_p); players[i].pity = READSINT8(save_p); players[i].currentweapon = READINT32(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index f2b0c49d8..10f4f4bc3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2057,7 +2057,7 @@ static void P_LevelInitStuff(void) players[i].gotcontinue = false; players[i].xtralife = players[i].deadtimer = players[i].numboxes = players[i].totalring = players[i].laps = 0; - players[i].health = 1; + players[i].rings = 0; players[i].aiming = 0; players[i].pflags &= ~PF_TIMEOVER; diff --git a/src/p_spec.c b/src/p_spec.c index cb3340ee4..6712f40ec 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1592,10 +1592,10 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (!playeringame[i] || players[i].spectator) continue; - if (!players[i].mo || players[i].mo->health < 1) + if (!players[i].mo || players[i].rings <= 0) continue; - rings += players[i].mo->health-1; + rings += players[i].rings; } } else @@ -1603,7 +1603,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (!(actor && actor->player)) return false; // no player to count rings from here, sorry - rings = actor->health-1; + rings = actor->player->rings; } if (triggerline->flags & ML_NOCLIMB) @@ -3499,10 +3499,9 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers break; case 9: // Ring Drainer (Floor Touch) case 10: // Ring Drainer (No Floor Touch) - if (leveltime % (TICRATE/2) == 0 && player->mo->health > 1) + if (leveltime % (TICRATE/2) == 0 && player->rings > 0) { - player->mo->health--; - player->health--; + player->rings--; S_StartSound(player->mo, sfx_itemup); } break; @@ -3510,7 +3509,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super] || player->exiting || player->bot) break; - if (!(player->powers[pw_shield] || player->mo->health > 1)) // Don't do anything if no shield or rings anyway + if (!(player->powers[pw_shield] || player->rings > 0)) // Don't do anything if no shield or rings anyway break; if (player->powers[pw_shield]) @@ -3518,14 +3517,13 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers P_RemoveShield(player); S_StartSound(player->mo, sfx_shldls); // Ba-Dum! Shield loss. } - else if (player->mo->health > 1) + else if (player->rings > 0) { P_PlayRinglossSound(player->mo); - if (player->mo->health > 10) - player->mo->health -= 10; + if (player->rings >= 10) + player->rings -= 10; else - player->mo->health = 1; - player->health = player->mo->health; + player->rings = 0; } P_DoPlayerPain(player, NULL, NULL); // this does basically everything that was here before diff --git a/src/p_tick.c b/src/p_tick.c index 15d3abc80..3c7820c2d 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -469,7 +469,7 @@ static inline void P_DoSpecialStageStuff(void) for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) { - ssrings += (players[i].mo->health-1); + ssrings += players[i].rings; // If in water, deplete timer 6x as fast. if ((players[i].mo->eflags & MFE_TOUCHWATER) diff --git a/src/p_user.c b/src/p_user.c index c7d612efc..2f384de34 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -704,7 +704,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) { for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]/* && players[i].pflags & PF_NIGHTSMODE*/) - total_rings += players[i].health-1; + total_rings += players[i].rings; } for (i = 0; i < MAXPLAYERS; i++) @@ -722,8 +722,8 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) } else { - players[i].finishedrings = (INT16)(players[i].health - 1); - P_AddPlayerScore(&players[i], (players[i].health - 1) * 50); + players[i].finishedrings = (INT16)(players[i].rings); + P_AddPlayerScore(&players[i], (players[i].rings) * 50); } // Add score to leaderboards now @@ -734,7 +734,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) players[i].lastmarescore = players[i].marescore; players[i].marescore = 0; - players[i].mo->health = players[i].health = 1; + players[i].rings = 0; P_DoPlayerExit(&players[i]); } } @@ -742,12 +742,12 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) { /// \todo Handle multi-mare special stages. // Ring bonus - P_AddPlayerScore(player, (player->health - 1) * 50); + P_AddPlayerScore(player, (player->rings) * 50); player->lastmare = (UINT8)oldmare; player->texttimer = 4*TICRATE; player->textvar = 4; // Score and grades - player->finishedrings = (INT16)(player->health - 1); + player->finishedrings = (INT16)(player->rings); // Add score to temp leaderboards if (!(netgame||multiplayer) && P_IsLocalPlayer(player)) @@ -758,7 +758,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->marescore = 0; player->marebegunat = leveltime; - player->mo->health = player->health = 1; + player->rings = 0; } else { @@ -901,30 +901,23 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) if (!player->mo) return; - player->mo->health += num_rings; - player->health += num_rings; + player->rings += num_rings; if (!G_IsSpecialStage(gamemap) || !useNightsSS) player->totalring += num_rings; // Can only get up to 9999 rings, sorry! - if (player->mo->health > 10000) - { - player->mo->health = 10000; - player->health = 10000; - } - else if (player->mo->health < 1) - { - player->mo->health = 1; - player->health = 1; - } + if (player->rings > 9999) + player->rings = 9999; + else if (player->rings < 0) + player->rings = 0; // Now extra life bonuses are handled here instead of in P_MovePlayer, since why not? if (!ultimatemode && !modeattacking && !G_IsSpecialStage(gamemap) && G_GametypeUsesLives()) { INT32 gainlives = 0; - while (player->xtralife < maxXtraLife && player->health > 100 * (player->xtralife+1)) + while (player->xtralife < maxXtraLife && player->rings >= 100 * (player->xtralife+1)) { ++gainlives; ++player->xtralife; @@ -975,10 +968,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) player->mo->momx = player->mo->momy = player->mo->momz = 0; if (giverings) - { - player->mo->health = 51; - player->health = player->mo->health; - } + player->rings = 50; // Just in case. if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)) @@ -3135,7 +3125,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) // Bounce ring else if (player->currentweapon == WEP_BOUNCE && player->powers[pw_bouncering]) { - if (player->health <= 1) + if (player->rings <= 0) return; P_SetWeaponDelay(player, TICRATE/4); @@ -3145,13 +3135,12 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) mo->fuse = 3*TICRATE; // Bounce Ring time player->powers[pw_bouncering]--; - player->mo->health--; - player->health--; + player->rings--; } // Rail ring else if (player->currentweapon == WEP_RAIL && player->powers[pw_railring]) { - if (player->health <= 1) + if (player->rings <= 0) return; P_SetWeaponDelay(player, (3*TICRATE)/2); @@ -3161,13 +3150,12 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) S_StartSound(player->mo, sfx_rail1); player->powers[pw_railring]--; - player->mo->health--; - player->health--; + player->rings--; } // Automatic else if (player->currentweapon == WEP_AUTO && player->powers[pw_automaticring]) { - if (player->health <= 1) + if (player->rings <= 0) return; player->pflags &= ~PF_ATTACKDOWN; P_SetWeaponDelay(player, 2); @@ -3175,26 +3163,24 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) mo = P_SpawnPlayerMissile(player->mo, MT_THROWNAUTOMATIC, MF2_AUTOMATIC); player->powers[pw_automaticring]--; - player->mo->health--; - player->health--; + player->rings--; } // Explosion else if (player->currentweapon == WEP_EXPLODE && player->powers[pw_explosionring]) { - if (player->health <= 1) + if (player->rings <= 0) return; P_SetWeaponDelay(player, (3*TICRATE)/2); mo = P_SpawnPlayerMissile(player->mo, MT_THROWNEXPLOSION, MF2_EXPLOSION); player->powers[pw_explosionring]--; - player->mo->health--; - player->health--; + player->rings--; } // Grenade else if (player->currentweapon == WEP_GRENADE && player->powers[pw_grenadering]) { - if (player->health <= 1) + if (player->rings <= 0) return; P_SetWeaponDelay(player, TICRATE/3); @@ -3207,8 +3193,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) } player->powers[pw_grenadering]--; - player->mo->health--; - player->health--; + player->rings--; } // Scatter // Note: Ignores MF2_RAILRING @@ -3218,7 +3203,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) angle_t shotangle = player->mo->angle; angle_t oldaiming = player->aiming; - if (player->health <= 1) + if (player->rings <= 0) return; P_SetWeaponDelay(player, (2*TICRATE)/3); @@ -3247,8 +3232,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) player->aiming = oldaiming; player->powers[pw_scatterring]--; - player->mo->health--; - player->health--; + player->rings--; return; } // No powers, just a regular ring. @@ -3272,7 +3256,7 @@ firenormal: // Red Ring else { - if (player->health <= 1) + if (player->rings <= 0) return; P_SetWeaponDelay(player, TICRATE/4); @@ -3281,8 +3265,7 @@ firenormal: if (mo) P_ColorTeamMissile(mo, player); - player->mo->health--; - player->health--; + player->rings--; } } @@ -3336,7 +3319,7 @@ static void P_DoSuperStuff(player_t *player) return; // NiGHTS Super doesn't mix with normal super // Does player have all emeralds? If so, flag the "Ready For Super!" - if ((ALL7EMERALDS(emeralds) || ALL7EMERALDS(player->powers[pw_emeralds])) && player->health > 50) + if ((ALL7EMERALDS(emeralds) || ALL7EMERALDS(player->powers[pw_emeralds])) && player->rings >= 50) player->pflags |= PF_SUPERREADY; else player->pflags &= ~PF_SUPERREADY; @@ -3374,10 +3357,7 @@ static void P_DoSuperStuff(player_t *player) // Deplete one ring every second while super if ((leveltime % TICRATE == 0) && !(player->exiting)) - { - player->health--; - player->mo->health--; - } + player->rings--; switch (player->skin) { @@ -3412,7 +3392,7 @@ static void P_DoSuperStuff(player_t *player) G_GhostAddColor(GHC_SUPER); // Ran out of rings while super! - if (player->health <= 1 || player->exiting) + if (player->rings <= 0 || player->exiting) { player->powers[pw_emeralds] = 0; // lost the power stones P_SpawnGhostMobj(player->mo); @@ -3465,12 +3445,6 @@ static void P_DoSuperStuff(player_t *player) P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); break; } - - if (!player->exiting) - { - player->health = 1; - player->mo->health = 1; - } } // Inform the netgame that the champion has fallen in the heat of battle. @@ -5392,12 +5366,10 @@ static void P_DoNiGHTSCapsule(player_t *player) if (G_IsSpecialStage(gamemap)) { // In special stages, share rings. Everyone gives up theirs to the capsule player always, because we can't have any individualism here! for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (&players[i] != player) && players[i].mo->health > 1) + if (playeringame[i] && (&players[i] != player) && players[i].rings > 0) { - player->mo->health += players[i].mo->health-1; - player->health = player->mo->health; - players[i].mo->health = 1; - players[i].health = players[i].mo->health; + player->rings += players[i].rings; + players[i].rings = 0; } } @@ -5406,10 +5378,9 @@ static void P_DoNiGHTSCapsule(player_t *player) && player->mo->y == player->capsule->y && player->mo->z == player->capsule->z+(player->capsule->height/3)) { - if (player->mo->health > 1) + if (player->rings > 0) { - player->mo->health--; - player->health--; + player->rings--; player->capsule->health--; player->capsule->extravalue1++; @@ -6129,7 +6100,7 @@ static void P_PlayerDropWeapon(player_t *player) if (mo) { - player->mo->health--; + player->rings--; P_InstaThrust(mo, player->mo->angle-ANGLE_180, 8*FRACUNIT); P_SetObjectMomZ(mo, 4*FRACUNIT, false); mo->flags2 |= MF2_DONTRESPAWN; @@ -6416,7 +6387,7 @@ static void P_MovePlayer(player_t *player) if (playeringame[i]) players[i].exiting = (14*TICRATE)/5 + 1; } - else if (player->health > 1) + else if (player->rings > 0) P_DamageMobj(player->mo, NULL, NULL, 1, 0); player->pflags &= ~PF_NIGHTSFALL; } @@ -8613,7 +8584,7 @@ void P_PlayerThink(player_t *player) #endif // todo: Figure out what is actually causing these problems in the first place... - if ((player->health <= 0 || player->mo->health <= 0) && player->playerstate == PST_LIVE) //you should be DEAD! + if (player->mo->health <= 0 && player->playerstate == PST_LIVE) //you should be DEAD! { CONS_Debug(DBG_GAMELOGIC, "P_PlayerThink: Player %s in PST_LIVE with 0 health. (\"Zombie bug\")\n", sizeu1(playeri)); player->playerstate = PST_DEAD; @@ -8713,7 +8684,7 @@ void P_PlayerThink(player_t *player) // it to the exit, you're a goner! else if (countdown == 1 && !player->exiting && player->lives > 0) { - if (netgame && player->health > 0) + if (netgame && player->mo->health > 0) CONS_Printf(M_GetText("%s ran out of time.\n"), player_names[player-players]); player->pflags |= PF_TIMEOVER; @@ -8802,7 +8773,7 @@ void P_PlayerThink(player_t *player) { player->score = 0; player->mo->health = 1; - player->health = 1; + player->rings = 0; } if ((netgame || multiplayer) && player->lives <= 0) @@ -9270,7 +9241,7 @@ void P_PlayerAfterThink(player_t *player) player->currentweapon = 0; // If you're out of rings, but have Infinity Rings left, switch to that. - if (player->currentweapon != 0 && player->health <= 1 && player->powers[pw_infinityring]) + if (player->currentweapon != 0 && player->rings <= 0 && player->powers[pw_infinityring]) player->currentweapon = 0; if (P_IsLocalPlayer(player) && (player->pflags & PF_WPNDOWN) && player->currentweapon != oldweapon) diff --git a/src/st_stuff.c b/src/st_stuff.c index 6e19b92ff..65a52d60e 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -660,9 +660,9 @@ static void ST_drawTime(void) static inline void ST_drawRings(void) { - INT32 ringnum = max(stplyr->health-1, 0); + INT32 ringnum = max(stplyr->rings, 0); - ST_DrawPatchFromHudWS(HUD_RINGS, ((stplyr->health <= 1 && leveltime/5 & 1) ? rrings : sborings)); + ST_DrawPatchFromHudWS(HUD_RINGS, ((stplyr->rings <= 0 && leveltime/5 & 1) ? rrings : sborings)); if (objectplacing) ringnum = op_currentdoomednum; @@ -671,8 +671,8 @@ static inline void ST_drawRings(void) INT32 i; ringnum = 0; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].mo && players[i].mo->health > 1) - ringnum += players[i].mo->health - 1; + if (playeringame[i] && players[i].mo && players[i].rings > 0) + ringnum += players[i].rings; } ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum); @@ -1133,11 +1133,11 @@ static void ST_drawNiGHTSHUD(void) INT32 i; total_ringcount = 0; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] /*&& players[i].pflags & PF_NIGHTSMODE*/ && players[i].health) - total_ringcount += players[i].health - 1; + if (playeringame[i] /*&& players[i].pflags & PF_NIGHTSMODE*/ && players[i].rings) + total_ringcount += players[i].rings; } else - total_ringcount = stplyr->health-1; + total_ringcount = stplyr->rings; if (stplyr->capsule) { @@ -1349,7 +1349,7 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I txtflags |= V_YELLOWMAP; if (weapon == pw_infinityring - || (stplyr->ringweapons & rwflag && stplyr->health > 1)) + || (stplyr->ringweapons & rwflag && stplyr->rings > 0)) txtflags |= V_20TRANS; else { @@ -1383,7 +1383,7 @@ static void ST_drawMatchHUD(void) if (stplyr->powers[pw_infinityring]) ST_drawWeaponRing(pw_infinityring, 0, 0, offset, infinityring); - else if (stplyr->health > 1) + else if (stplyr->rings > 0) V_DrawScaledPatch(8 + offset, STRINGY(162), V_SNAPTOLEFT, normring); else V_DrawTranslucentPatch(8 + offset, STRINGY(162), V_SNAPTOLEFT|V_80TRANS, normring); diff --git a/src/y_inter.c b/src/y_inter.c index 2f2edf7ca..37a8bc4cc 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -792,13 +792,13 @@ static void Y_UpdateRecordReplays(void) if ((mainrecords[gamemap-1]->time == 0) || (players[consoleplayer].realtime < mainrecords[gamemap-1]->time)) mainrecords[gamemap-1]->time = players[consoleplayer].realtime; - if ((UINT16)(players[consoleplayer].health - 1) > mainrecords[gamemap-1]->rings) - mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].health - 1); + if ((UINT16)(players[consoleplayer].rings) > mainrecords[gamemap-1]->rings) + mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings); // Save demo! bestdemo[255] = '\0'; lastdemo[255] = '\0'; - G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].health-1)); + G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].rings)); G_CheckDemoStatus(); I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755); @@ -1373,7 +1373,7 @@ static void Y_CalculateCompetitionWinners(void) bestat[j] = true; times[i] = players[i].realtime; - rings[i] = (UINT32)max(players[i].health-1, 0); + rings[i] = (UINT32)max(players[i].rings, 0); maxrings[i] = (UINT32)players[i].totalring; monitors[i] = (UINT32)players[i].numboxes; scores[i] = (UINT32)min(players[i].score, 99999990); @@ -1388,7 +1388,7 @@ static void Y_CalculateCompetitionWinners(void) else bestat[0] = false; - if (max(players[i].health-1, 0) >= max(players[j].health-1, 0)) + if (max(players[i].rings, 0) >= max(players[j].rings, 0)) points[i]++; else bestat[1] = false; @@ -1511,7 +1511,7 @@ static void Y_SetRingBonus(player_t *player, y_bonus_t *bstruct) { strncpy(bstruct->patch, "YB_RING", sizeof(bstruct->patch)); bstruct->display = true; - bstruct->points = max(0, (player->health-1) * 100); + bstruct->points = max(0, (player->rings) * 100); } // @@ -1559,7 +1559,7 @@ static void Y_SetPerfectBonus(player_t *player, y_bonus_t *bstruct) for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) continue; - sharedringtotal += players[i].health - 1; + sharedringtotal += players[i].rings; } if (!sharedringtotal || sharedringtotal < nummaprings) data.coop.gotperfbonus = 0; From 7dcf0d3d09564fdab4163b33a58b864fb4bab04e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 1 Oct 2015 20:02:44 +0100 Subject: [PATCH 09/17] Fix an error from match-balancing being merged in. Apparently match-balancing also doesn't have a prototype for P_StealPlayerScore for whatever reason. --- src/p_inter.c | 1 - src/p_local.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index 60ba32c90..9f29401a0 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3025,7 +3025,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } if (damagetype & DMG_DEATHMASK) - damage = 0; player->rings = 0; else if (damage == 0 || player->rings) //quickfix to just get things back to normal ...for now (sans Tag, I'll deal with that later) { diff --git a/src/p_local.h b/src/p_local.h index 359b7b842..30582ba1a 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -123,6 +123,7 @@ fixed_t P_GetPlayerHeight(player_t *player); fixed_t P_GetPlayerSpinHeight(player_t *player); INT32 P_GetPlayerControlDirection(player_t *player); void P_AddPlayerScore(player_t *player, UINT32 amount); +void P_StealPlayerScore(player_t *player, UINT32 amount); void P_ResetCamera(player_t *player, camera_t *thiscam); boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam); void P_SlideCameraMove(camera_t *thiscam); From 175561cc7f34cd8f02162605b00731dc5e55074f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 5 Oct 2015 17:13:34 +0100 Subject: [PATCH 10/17] Check if God mode is one before even going to NiGHTS or player vs player damaging code or whatever. --- src/p_inter.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 9f29401a0..83d20689e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2383,8 +2383,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source) player_t *player = target->player; tic_t oldnightstime = player->nightstime; - if (!player->powers[pw_flashing] - && !(player->pflags & PF_GODMODE)) + if (!player->powers[pw_flashing]) { angle_t fa; @@ -2891,6 +2890,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (player->exiting) return false; + if (player->pflags & PF_GODMODE) + return false; + if (!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS)) return false; @@ -2953,9 +2955,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; } - if (!force && player->pflags & PF_GODMODE) - return false; - // Instant-Death if (damagetype & DMG_DEATHMASK) P_KillPlayer(player, source, damage); From 31b2919847abbc79b33723e0f2495e3ce4aac5ad Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 5 Oct 2015 20:18:45 +0100 Subject: [PATCH 11/17] Added a "damagetype" argument to P_ShieldDamage. We don't use MT_NULL to hack in damage for sector specials anymore, after all. Must have forgotten to do this back when I originally implemented damage types, oh well. --- src/p_inter.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 83d20689e..af8b90040 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2686,7 +2686,7 @@ void P_RemoveShield(player_t *player) player->powers[pw_shield] = player->powers[pw_shield] & SH_STACK; } -static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage) +static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { // Must do pain first to set flashing -- P_RemoveShield can cause damage P_DoPlayerPain(player, source, inflictor); @@ -2695,7 +2695,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); - if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // spikes + if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes S_StartSound(player->mo, sfx_spkdth); else S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss. @@ -2971,7 +2971,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; // Metal Sonic walk through flame !! else { // Oh no! Metal Sonic is hit !! - P_ShieldDamage(player, inflictor, source, damage); + P_ShieldDamage(player, inflictor, source, damage, damagetype); return true; } } @@ -2997,7 +2997,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da #endif else if (!player->powers[pw_super] && (player->powers[pw_shield] || player->bot)) //If One-Hit Shield { - P_ShieldDamage(player, inflictor, source, damage); + P_ShieldDamage(player, inflictor, source, damage, damagetype); damage = 0; } else if (player->rings > 0) // No shield but have rings. @@ -3019,7 +3019,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da else { damage = 0; - P_ShieldDamage(player, inflictor, source, damage); + P_ShieldDamage(player, inflictor, source, damage, damagetype); } } From a84c2c6081e1dd0329556da8b04c6b716a7e492f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 6 Oct 2015 21:14:11 +0100 Subject: [PATCH 12/17] Some cleanup and reordering --- src/p_inter.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index af8b90040..b7f581abb 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2920,7 +2920,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; // Don't hit yourself with your own paraloop, baka if (source && source->player && !cv_friendlyfire.value && (gametype == GT_COOP - || (G_GametypeHasTeams() && target->player->ctfteam == source->player->ctfteam))) + || (G_GametypeHasTeams() && player->ctfteam == source->player->ctfteam))) return false; // Don't run eachother over in special stages and team games and such } #ifdef HAVE_BLUA @@ -2995,7 +2995,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da else if (LUAh_MobjDamage(target, inflictor, source, damage)) return true; #endif - else if (!player->powers[pw_super] && (player->powers[pw_shield] || player->bot)) //If One-Hit Shield + else if (player->powers[pw_shield] || player->bot) //If One-Hit Shield { P_ShieldDamage(player, inflictor, source, damage, damagetype); damage = 0; @@ -3005,22 +3005,19 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da damage = player->rings; P_RingDamage(player, inflictor, source, damage, damagetype); } + // To reduce griefing potential, don't allow players to be killed + // by friendly fire. Spilling their rings and other items is enough. + else if (!force && G_GametypeHasTeams() + && source && source->player && (source->player->ctfteam == player->ctfteam) + && cv_friendlyfire.value) + { + damage = 0; + P_ShieldDamage(player, inflictor, source, damage, damagetype); + } else // No shield, no rings, no invincibility. { - // To reduce griefing potential, don't allow players to be killed - // by friendly fire. Spilling their rings and other items is enough. - if (force || !(G_GametypeHasTeams() - && source && source->player && (source->player->ctfteam == player->ctfteam) - && cv_friendlyfire.value)) - { - damage = 1; - P_KillPlayer(player, source, damage); - } - else - { - damage = 0; - P_ShieldDamage(player, inflictor, source, damage, damagetype); - } + damage = 1; + P_KillPlayer(player, source, damage); } if (damagetype & DMG_DEATHMASK) From d7b402e3c4c63139791ff8b05a760c340001a571 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 6 Oct 2015 22:05:32 +0100 Subject: [PATCH 13/17] More cleanup, most notably dumping ring spilling code in P_RingDamage ...one wonders why P_RingDamage didn't already do that in the first place --- src/p_inter.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index b7f581abb..d5eff8d2a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2747,6 +2747,10 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN // Ring loss sound plays despite hitting spikes P_PlayRinglossSound(player->mo); // Ringledingle! + P_PlayerRingBurst(player, damage); + player->rings -= damage; + if (player->rings < 0) + player->rings = 0; } /** Damages an object, which may or may not be a player. @@ -2957,7 +2961,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Instant-Death if (damagetype & DMG_DEATHMASK) + { P_KillPlayer(player, source, damage); + player->rings = 0; + } else if (metalrecording) { if (!inflictor) @@ -3004,6 +3011,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { damage = player->rings; P_RingDamage(player, inflictor, source, damage, damagetype); + damage = 0; } // To reduce griefing potential, don't allow players to be killed // by friendly fire. Spilling their rings and other items is enough. @@ -3020,20 +3028,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_KillPlayer(player, source, damage); } - if (damagetype & DMG_DEATHMASK) - player->rings = 0; - else if (damage == 0 || player->rings) //quickfix to just get things back to normal ...for now (sans Tag, I'll deal with that later) - { - if (damage > 0) // don't spill emeralds/ammo/panels for shield damage - P_PlayerRingBurst(player, damage); - player->rings -= damage; - target->player->powers[pw_flashing] = flashingtics; - damage = 0; - } - - if (player->rings < 0) - player->rings = 0; - P_HitDeathMessages(player, inflictor, source, damagetype); P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); From a749d79aa5c0ba68abe99b91bacca2b2e1aa19a6 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 13 Mar 2016 20:53:10 +0000 Subject: [PATCH 14/17] Fix up S_ChangeMusic usage from merge so things can compile again --- src/p_inter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 2a6c0bd21..bc1857c20 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -250,11 +250,11 @@ void P_DoMatchSuper(player_t *player) S_StopMusic(); if (mariomode) { - S_ChangeMusic(mus_minvnc, false); + S_ChangeMusicInternal("minvnc", false); G_GhostAddColor(GHC_INVINCIBLE); } else - S_ChangeMusic(mus_invinc, false); + S_ChangeMusicInternal("invinc", false); } // Also steal 50 points from every enemy, sealing your victory. @@ -275,11 +275,11 @@ void P_DoMatchSuper(player_t *player) S_StopMusic(); if (mariomode) { - S_ChangeMusic(mus_minvnc, false); + S_ChangeMusicInternal("minvnc", false); G_GhostAddColor(GHC_INVINCIBLE); } else - S_ChangeMusic(mus_invinc, false); + S_ChangeMusicInternal("invinc", false); } } } From d31fd95d7574d8cc50caa597e8ac45bbf8e75b95 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 7 Apr 2016 22:02:52 +0100 Subject: [PATCH 15/17] Armageddon & Sparkles confusion is no more, DMG_NUKE exists to sort that out now --- src/p_inter.c | 2 +- src/p_local.h | 3 ++- src/p_user.c | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index bc1857c20..14667d21f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1586,7 +1586,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour else switch (inflictor->type) { case MT_PLAYER: - if ((inflictor->player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB) + if (damagetype == DMG_NUKE) // SH_BOMB, armageddon shield str = M_GetText("%s%s's armageddon blast %s %s.\n"); else if (inflictor->player->powers[pw_invulnerability]) str = M_GetText("%s%s's invincibility aura %s %s.\n"); diff --git a/src/p_local.h b/src/p_local.h index 583f115ef..717f66d69 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -376,7 +376,8 @@ typedef struct BasicFF_s #define DMG_FIRE 2 #define DMG_ELECTRIC 3 #define DMG_SPIKE 4 -//#define DMG_SPECIALSTAGE 5 +#define DMG_NUKE 5 // bomb shield +//#define DMG_SPECIALSTAGE 6 //// Death types - cannot be combined with damage types #define DMG_INSTAKILL 0x80 #define DMG_DROWNED 0x80+1 diff --git a/src/p_user.c b/src/p_user.c index 4f9bca55e..4cf75ef33 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7440,12 +7440,12 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) mo->flags |= MF_SPECIAL|MF_SHOOTABLE; if (mo->type == MT_EGGGUARD && mo->tracer) //nuke Egg Guard's shield! - P_KillMobj(mo->tracer, inflictor, source, 0); + P_KillMobj(mo->tracer, inflictor, source, DMG_NUKE); if (mo->flags & MF_BOSS || mo->type == MT_PLAYER) //don't OHKO bosses nor players! - P_DamageMobj(mo, inflictor, source, 1, 0); + P_DamageMobj(mo, inflictor, source, 1, DMG_NUKE); else - P_DamageMobj(mo, inflictor, source, 1000, 0); + P_DamageMobj(mo, inflictor, source, 1000, DMG_NUKE); } } From 35d89a4fbfb1002199cefe22ce177e31be703c98 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 20 Jul 2016 21:21:14 +0100 Subject: [PATCH 16/17] add DMG_* constants to dehacked.c lists --- src/dehacked.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 75235e054..023a872cf 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7165,6 +7165,22 @@ struct { {"PAL_MIXUP",PAL_MIXUP}, {"PAL_RECYCLE",PAL_RECYCLE}, {"PAL_NUKE",PAL_NUKE}, + // for P_DamageMobj + //// Damage types + {"DMG_WATER",DMG_WATER}, + {"DMG_FIRE",DMG_FIRE}, + {"DMG_ELECTRIC",DMG_ELECTRIC}, + {"DMG_SPIKE",DMG_SPIKE}, + {"DMG_NUKE",DMG_NUKE}, + //// Death types + {"DMG_INSTAKILL",DMG_INSTAKILL}, + {"DMG_DROWNED",DMG_DROWNED}, + {"DMG_SPACEDROWN",DMG_SPACEDROWN}, + {"DMG_DEATHPIT",DMG_DEATHPIT}, + {"DMG_CRUSHED",DMG_CRUSHED}, + {"DMG_SPECTATOR",DMG_SPECTATOR}, + //// Masks + {"DMG_DEATHMASK",DMG_DEATHMASK}, // Gametypes, for use with global var "gametype" {"GT_COOP",GT_COOP}, From ea65e9e54f40c43914f5a4bc0a29da2c5ae55cd8 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 20 Jul 2016 22:02:02 +0100 Subject: [PATCH 17/17] Add "damagetype" argument to functions for Lua hooks ShouldDamage, MobjDamage, MobjDeath and HurtMsg --- src/lua_hook.h | 8 ++++---- src/lua_hooklib.c | 52 +++++++++++++++++++++++++++-------------------- src/p_inter.c | 18 ++++++++-------- 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 804d99e12..d2ce0d826 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -62,9 +62,9 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher); // Hook for P_Touch #define LUAh_MobjFuse(mo) LUAh_MobjHook(mo, hook_MobjFuse) // Hook for mobj->fuse == 0 by mobj type #define LUAh_MobjThinker(mo) LUAh_MobjHook(mo, hook_MobjThinker) // Hook for P_MobjThinker or P_SceneryThinker by mobj type #define LUAh_BossThinker(mo) LUAh_MobjHook(mo, hook_BossThinker) // Hook for P_GenericBossThinker by mobj type -UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage); // Hook for P_DamageMobj by mobj type (Should mobj take damage?) -boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage); // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) -boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source); // Hook for P_KillMobj by mobj type +UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); // Hook for P_DamageMobj by mobj type (Should mobj take damage?) +boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) +boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for P_KillMobj by mobj type #define LUAh_BossDeath(mo) LUAh_MobjHook(mo, hook_BossDeath) // Hook for A_BossDeath by mobj type #define LUAh_MobjRemoved(mo) LUAh_MobjHook(mo, hook_MobjRemoved) // Hook for P_RemoveMobj by mobj type #define LUAh_JumpSpecial(player) LUAh_PlayerHook(player, hook_JumpSpecial) // Hook for P_DoJumpStuff (Any-jumping) @@ -75,7 +75,7 @@ boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages -boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages +boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for hurt messages #define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 1b9652571..e95b75eda 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -412,7 +412,7 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) } // Hook for P_DamageMobj by mobj type (Should mobj take damage?) -UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage) +UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { hook_p hookp; UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. @@ -431,14 +431,16 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + if (lua_pcall(gL, 5, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -460,7 +462,7 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 } // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) -boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage) +boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { hook_p hookp; boolean hooked = false; @@ -479,14 +481,16 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + if (lua_pcall(gL, 5, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -503,7 +507,7 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 } // Hook for P_KillMobj by mobj type -boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source) +boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) { hook_p hookp; boolean hooked = false; @@ -521,13 +525,15 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source) LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - if (lua_pcall(gL, 3, 1, 0)) { + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + if (lua_pcall(gL, 4, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -729,7 +735,7 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) } // Hook for hurt messages -boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source) +boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) { hook_p hookp; boolean hooked = false; @@ -747,13 +753,15 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source) LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - if (lua_pcall(gL, 3, 1, 0)) { + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + if (lua_pcall(gL, 4, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); diff --git a/src/p_inter.c b/src/p_inter.c index 4a6a4445f..dee2aa824 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1565,7 +1565,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour return; // Presumably it's obvious what's happening in splitscreen. #ifdef HAVE_BLUA - if (LUAh_HurtMsg(player, inflictor, source)) + if (LUAh_HurtMsg(player, inflictor, source, damagetype)) return; #endif @@ -2037,7 +2037,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->health = 0; // This makes it easy to check if something's dead elsewhere. #ifdef HAVE_BLUA - if (LUAh_MobjDeath(target, inflictor, source) || P_MobjWasRemoved(target)) + if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) return; #endif @@ -2917,7 +2917,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Everything above here can't be forced. if (!metalrecording) { - UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage); + UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage, damagetype); if (P_MobjWasRemoved(target)) return (shouldForce == 1); // mobj was removed if (shouldForce == 1) @@ -2960,7 +2960,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; #ifdef HAVE_BLUA - if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target)) + if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target)) return true; #endif @@ -2988,7 +2988,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; #ifdef HAVE_BLUA - if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target)) + if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target)) return true; #endif @@ -2998,7 +2998,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da #ifdef HAVE_BLUA else if (target->flags & MF_ENEMY) { - if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target)) + if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target)) return true; } #endif @@ -3046,7 +3046,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; // Don't run eachother over in special stages and team games and such } #ifdef HAVE_BLUA - if (LUAh_MobjDamage(target, inflictor, source, damage)) + if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) return true; #endif P_NiGHTSDamage(target, source); // -5s :( @@ -3108,7 +3108,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da && player->powers[pw_super])) { #ifdef HAVE_BLUA - if (!LUAh_MobjDamage(target, inflictor, source, damage)) + if (!LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) #endif P_SuperDamage(player, inflictor, source, damage); return true; @@ -3117,7 +3117,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; } #ifdef HAVE_BLUA - else if (LUAh_MobjDamage(target, inflictor, source, damage)) + else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) return true; #endif else if (player->powers[pw_shield] || player->bot) //If One-Hit Shield