diff options
author | Simon Howard | 2008-09-05 00:02:14 +0000 |
---|---|---|
committer | Simon Howard | 2008-09-05 00:02:14 +0000 |
commit | c7ddc423f67236a99956960cf9fe89abf077839b (patch) | |
tree | 61322034e9d75f1c1a409d1e14ca21ee5c6025c2 /src/hexen/p_inter.c | |
parent | 0774dce204c2c01622c59819e2a29590a1b50e46 (diff) | |
download | chocolate-doom-c7ddc423f67236a99956960cf9fe89abf077839b.tar.gz chocolate-doom-c7ddc423f67236a99956960cf9fe89abf077839b.tar.bz2 chocolate-doom-c7ddc423f67236a99956960cf9fe89abf077839b.zip |
Reformat (beautify) Raven sources and add GPL headers.
Subversion-branch: /branches/raven-branch
Subversion-revision: 1197
Diffstat (limited to 'src/hexen/p_inter.c')
-rw-r--r-- | src/hexen/p_inter.c | 3667 |
1 files changed, 1835 insertions, 1832 deletions
diff --git a/src/hexen/p_inter.c b/src/hexen/p_inter.c index b9e904fa..ab6b9501 100644 --- a/src/hexen/p_inter.c +++ b/src/hexen/p_inter.c @@ -1,14 +1,26 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 1993-1996 Id Software, Inc. +// Copyright(C) 1993-2008 Raven Software +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- -//************************************************************************** -//** -//** p_inter.c : Heretic 2 : Raven Software, Corp. -//** -//** $RCSfile: p_inter.c,v $ -//** $Revision: 1.145 $ -//** $Date: 96/01/16 10:35:33 $ -//** $Author: bgokey $ -//** -//************************************************************************** #include "h2def.h" #include "p_local.h" @@ -16,38 +28,38 @@ #define BONUSADD 6 -int ArmorIncrement[NUMCLASSES][NUMARMOR] = -{ - { 25*FRACUNIT, 20*FRACUNIT, 15*FRACUNIT, 5*FRACUNIT }, - { 10*FRACUNIT, 25*FRACUNIT, 5*FRACUNIT, 20*FRACUNIT }, - { 5*FRACUNIT, 15*FRACUNIT, 10*FRACUNIT, 25*FRACUNIT }, - { 0, 0, 0, 0 } +int ArmorIncrement[NUMCLASSES][NUMARMOR] = { + {25 * FRACUNIT, 20 * FRACUNIT, 15 * FRACUNIT, 5 * FRACUNIT}, + {10 * FRACUNIT, 25 * FRACUNIT, 5 * FRACUNIT, 20 * FRACUNIT}, + {5 * FRACUNIT, 15 * FRACUNIT, 10 * FRACUNIT, 25 * FRACUNIT}, + {0, 0, 0, 0} }; -int AutoArmorSave[NUMCLASSES] = { 15*FRACUNIT, 10*FRACUNIT, 5*FRACUNIT, 0 }; - -char *TextKeyMessages[] = -{ - TXT_KEY_STEEL, - TXT_KEY_CAVE, - TXT_KEY_AXE, - TXT_KEY_FIRE, - TXT_KEY_EMERALD, - TXT_KEY_DUNGEON, - TXT_KEY_SILVER, - TXT_KEY_RUSTED, - TXT_KEY_HORN, - TXT_KEY_SWAMP, - TXT_KEY_CASTLE +int AutoArmorSave[NUMCLASSES] = + { 15 * FRACUNIT, 10 * FRACUNIT, 5 * FRACUNIT, 0 }; + +char *TextKeyMessages[] = { + TXT_KEY_STEEL, + TXT_KEY_CAVE, + TXT_KEY_AXE, + TXT_KEY_FIRE, + TXT_KEY_EMERALD, + TXT_KEY_DUNGEON, + TXT_KEY_SILVER, + TXT_KEY_RUSTED, + TXT_KEY_HORN, + TXT_KEY_SWAMP, + TXT_KEY_CASTLE }; -static void SetDormantArtifact(mobj_t *arti); -static void TryPickupArtifact(player_t *player, artitype_t artifactType, - mobj_t *artifact); -static void TryPickupWeapon(player_t *player, pclass_t weaponClass, - weapontype_t weaponType, mobj_t *weapon, char *message); -static void TryPickupWeaponPiece(player_t *player, pclass_t matchClass, - int pieceValue, mobj_t *pieceMobj); +static void SetDormantArtifact(mobj_t * arti); +static void TryPickupArtifact(player_t * player, artitype_t artifactType, + mobj_t * artifact); +static void TryPickupWeapon(player_t * player, pclass_t weaponClass, + weapontype_t weaponType, mobj_t * weapon, + char *message); +static void TryPickupWeaponPiece(player_t * player, pclass_t matchClass, + int pieceValue, mobj_t * pieceMobj); #ifdef __NeXT__ extern void strupr(char *s); @@ -59,34 +71,34 @@ extern void strupr(char *s); // //-------------------------------------------------------------------------- -void P_SetMessage(player_t *player, char *message, boolean ultmsg) +void P_SetMessage(player_t * player, char *message, boolean ultmsg) { - extern boolean messageson; - - if((player->ultimateMessage || !messageson) && !ultmsg) - { - return; - } - if(strlen(message) > 79) - { - memcpy(player->message, message, 80); - player->message[80] = 0; - } - else - { - strcpy(player->message, message); - } - strupr(player->message); - player->messageTics = MESSAGETICS; - player->yellowMessage = false; - if(ultmsg) - { - player->ultimateMessage = true; - } - if(player == &players[consoleplayer]) - { - BorderTopRefresh = true; - } + extern boolean messageson; + + if ((player->ultimateMessage || !messageson) && !ultmsg) + { + return; + } + if (strlen(message) > 79) + { + memcpy(player->message, message, 80); + player->message[80] = 0; + } + else + { + strcpy(player->message, message); + } + strupr(player->message); + player->messageTics = MESSAGETICS; + player->yellowMessage = false; + if (ultmsg) + { + player->ultimateMessage = true; + } + if (player == &players[consoleplayer]) + { + BorderTopRefresh = true; + } } //========================================================================== @@ -95,33 +107,33 @@ void P_SetMessage(player_t *player, char *message, boolean ultmsg) // //========================================================================== -void P_SetYellowMessage(player_t *player, char *message, boolean ultmsg) +void P_SetYellowMessage(player_t * player, char *message, boolean ultmsg) { - extern boolean messageson; - - if((player->ultimateMessage || !messageson) && !ultmsg) - { - return; - } - if(strlen(message) > 79) - { - memcpy(player->message, message, 80); - player->message[80] = 0; - } - else - { - strcpy(player->message, message); - } - player->messageTics = 5*MESSAGETICS; // Bold messages last longer - player->yellowMessage = true; - if(ultmsg) - { - player->ultimateMessage = true; - } - if(player == &players[consoleplayer]) - { - BorderTopRefresh = true; - } + extern boolean messageson; + + if ((player->ultimateMessage || !messageson) && !ultmsg) + { + return; + } + if (strlen(message) > 79) + { + memcpy(player->message, message, 80); + player->message[80] = 0; + } + else + { + strcpy(player->message, message); + } + player->messageTics = 5 * MESSAGETICS; // Bold messages last longer + player->yellowMessage = true; + if (ultmsg) + { + player->ultimateMessage = true; + } + if (player == &players[consoleplayer]) + { + BorderTopRefresh = true; + } } //========================================================================== @@ -130,13 +142,13 @@ void P_SetYellowMessage(player_t *player, char *message, boolean ultmsg) // //========================================================================== -void P_ClearMessage(player_t *player) +void P_ClearMessage(player_t * player) { - player->messageTics = 0; - if(player == &players[consoleplayer]) - { - BorderTopRefresh = true; - } + player->messageTics = 0; + if (player == &players[consoleplayer]) + { + BorderTopRefresh = true; + } } //---------------------------------------------------------------------------- @@ -145,11 +157,11 @@ void P_ClearMessage(player_t *player) // //---------------------------------------------------------------------------- -void P_HideSpecialThing(mobj_t *thing) +void P_HideSpecialThing(mobj_t * thing) { - thing->flags &= ~MF_SPECIAL; - thing->flags2 |= MF2_DONTDRAW; - P_SetMobjState(thing, S_HIDESPECIAL1); + thing->flags &= ~MF_SPECIAL; + thing->flags2 |= MF2_DONTDRAW; + P_SetMobjState(thing, S_HIDESPECIAL1); } //-------------------------------------------------------------------------- @@ -161,40 +173,40 @@ void P_HideSpecialThing(mobj_t *thing) // //-------------------------------------------------------------------------- -boolean P_GiveMana(player_t *player, manatype_t mana, int count) +boolean P_GiveMana(player_t * player, manatype_t mana, int count) { - int prevMana; - //weapontype_t changeWeapon; - - if(mana == MANA_NONE || mana == MANA_BOTH) - { - return(false); - } - if(mana < 0 || mana > NUMMANA) - { - I_Error("P_GiveMana: bad type %i", mana); - } - if(player->mana[mana] == MAX_MANA) - { - return(false); - } - if(gameskill == sk_baby || gameskill == sk_nightmare) - { // extra mana in baby mode and nightmare mode - count += count>>1; - } - prevMana = player->mana[mana]; - - player->mana[mana] += count; - if(player->mana[mana] > MAX_MANA) - { - player->mana[mana] = MAX_MANA; - } - if(player->class == PCLASS_FIGHTER && player->readyweapon == WP_SECOND - && mana == MANA_1 && prevMana <= 0) - { - P_SetPsprite(player, ps_weapon, S_FAXEREADY_G); - } - return(true); + int prevMana; + //weapontype_t changeWeapon; + + if (mana == MANA_NONE || mana == MANA_BOTH) + { + return (false); + } + if (mana < 0 || mana > NUMMANA) + { + I_Error("P_GiveMana: bad type %i", mana); + } + if (player->mana[mana] == MAX_MANA) + { + return (false); + } + if (gameskill == sk_baby || gameskill == sk_nightmare) + { // extra mana in baby mode and nightmare mode + count += count >> 1; + } + prevMana = player->mana[mana]; + + player->mana[mana] += count; + if (player->mana[mana] > MAX_MANA) + { + player->mana[mana] = MAX_MANA; + } + if (player->class == PCLASS_FIGHTER && player->readyweapon == WP_SECOND + && mana == MANA_1 && prevMana <= 0) + { + P_SetPsprite(player, ps_weapon, S_FAXEREADY_G); + } + return (true); } //========================================================================== @@ -203,108 +215,109 @@ boolean P_GiveMana(player_t *player, manatype_t mana, int count) // //========================================================================== -static void TryPickupWeapon(player_t *player, pclass_t weaponClass, - weapontype_t weaponType, mobj_t *weapon, char *message) +static void TryPickupWeapon(player_t * player, pclass_t weaponClass, + weapontype_t weaponType, mobj_t * weapon, + char *message) { - boolean remove; - boolean gaveMana; - boolean gaveWeapon; - - remove = true; - if(player->class != weaponClass) - { // Wrong class, but try to pick up for mana - if(netgame && !deathmatch) - { // Can't pick up weapons for other classes in coop netplay - return; - } - if(weaponType == WP_SECOND) - { - if(!P_GiveMana(player, MANA_1, 25)) - { - return; - } - } - else - { - if(!P_GiveMana(player, MANA_2, 25)) - { - return; - } - } - } - else if(netgame && !deathmatch) - { // Cooperative net-game - if(player->weaponowned[weaponType]) - { - return; - } - player->weaponowned[weaponType] = true; - if(weaponType == WP_SECOND) - { - P_GiveMana(player, MANA_1, 25); - } - else - { - P_GiveMana(player, MANA_2, 25); - } - player->pendingweapon = weaponType; - remove = false; - } - else - { // Deathmatch or single player game - if(weaponType == WP_SECOND) - { - gaveMana = P_GiveMana(player, MANA_1, 25); - } - else - { - gaveMana = P_GiveMana(player, MANA_2, 25); - } - if(player->weaponowned[weaponType]) - { - gaveWeapon = false; - } - else - { - gaveWeapon = true; - player->weaponowned[weaponType] = true; - if(weaponType > player->readyweapon) - { // Only switch to more powerful weapons - player->pendingweapon = weaponType; - } - } - if(!(gaveWeapon || gaveMana)) - { // Player didn't need the weapon or any mana - return; - } - } - - P_SetMessage(player, message, false); - if(weapon->special) - { - P_ExecuteLineSpecial(weapon->special, weapon->args, - NULL, 0, player->mo); - weapon->special = 0; - } - - if(remove) - { - if(deathmatch && !(weapon->flags2&MF2_DROPPED)) - { - P_HideSpecialThing(weapon); - } - else - { - P_RemoveMobj(weapon); - } - } - - player->bonuscount += BONUSADD; - if(player == &players[consoleplayer]) - { - S_StartSound(NULL, SFX_PICKUP_WEAPON); - SB_PaletteFlash(false); - } + boolean remove; + boolean gaveMana; + boolean gaveWeapon; + + remove = true; + if (player->class != weaponClass) + { // Wrong class, but try to pick up for mana + if (netgame && !deathmatch) + { // Can't pick up weapons for other classes in coop netplay + return; + } + if (weaponType == WP_SECOND) + { + if (!P_GiveMana(player, MANA_1, 25)) + { + return; + } + } + else + { + if (!P_GiveMana(player, MANA_2, 25)) + { + return; + } + } + } + else if (netgame && !deathmatch) + { // Cooperative net-game + if (player->weaponowned[weaponType]) + { + return; + } + player->weaponowned[weaponType] = true; + if (weaponType == WP_SECOND) + { + P_GiveMana(player, MANA_1, 25); + } + else + { + P_GiveMana(player, MANA_2, 25); + } + player->pendingweapon = weaponType; + remove = false; + } + else + { // Deathmatch or single player game + if (weaponType == WP_SECOND) + { + gaveMana = P_GiveMana(player, MANA_1, 25); + } + else + { + gaveMana = P_GiveMana(player, MANA_2, 25); + } + if (player->weaponowned[weaponType]) + { + gaveWeapon = false; + } + else + { + gaveWeapon = true; + player->weaponowned[weaponType] = true; + if (weaponType > player->readyweapon) + { // Only switch to more powerful weapons + player->pendingweapon = weaponType; + } + } + if (!(gaveWeapon || gaveMana)) + { // Player didn't need the weapon or any mana + return; + } + } + + P_SetMessage(player, message, false); + if (weapon->special) + { + P_ExecuteLineSpecial(weapon->special, weapon->args, + NULL, 0, player->mo); + weapon->special = 0; + } + + if (remove) + { + if (deathmatch && !(weapon->flags2 & MF2_DROPPED)) + { + P_HideSpecialThing(weapon); + } + else + { + P_RemoveMobj(weapon); + } + } + + player->bonuscount += BONUSADD; + if (player == &players[consoleplayer]) + { + S_StartSound(NULL, SFX_PICKUP_WEAPON); + SB_PaletteFlash(false); + } } //-------------------------------------------------------------------------- @@ -419,126 +432,123 @@ boolean P_GiveWeaponPiece(player_t *player, pclass_t class, int piece) // //========================================================================== -static void TryPickupWeaponPiece(player_t *player, pclass_t matchClass, - int pieceValue, mobj_t *pieceMobj) +static void TryPickupWeaponPiece(player_t * player, pclass_t matchClass, + int pieceValue, mobj_t * pieceMobj) { - boolean remove; - boolean checkAssembled; - boolean gaveWeapon; - int gaveMana; - static char *fourthWeaponText[] = - { - TXT_WEAPON_F4, - TXT_WEAPON_C4, - TXT_WEAPON_M4 - }; - static char *weaponPieceText[] = - { - TXT_QUIETUS_PIECE, - TXT_WRAITHVERGE_PIECE, - TXT_BLOODSCOURGE_PIECE - }; - static int pieceValueTrans[] = - { - 0, // 0: never - WPIECE1|WPIECE2|WPIECE3, // WPIECE1 (1) - WPIECE2|WPIECE3, // WPIECE2 (2) - 0, // 3: never - WPIECE3 // WPIECE3 (4) - }; - - remove = true; - checkAssembled = true; - gaveWeapon = false; - if(player->class != matchClass) - { // Wrong class, but try to pick up for mana - if(netgame && !deathmatch) - { // Can't pick up wrong-class weapons in coop netplay - return; - } - checkAssembled = false; - gaveMana = P_GiveMana(player, MANA_1, 20)+ - P_GiveMana(player, MANA_2, 20); - if(!gaveMana) - { // Didn't need the mana, so don't pick it up - return; - } - } - else if(netgame && !deathmatch) - { // Cooperative net-game - if(player->pieces&pieceValue) - { // Already has the piece - return; - } - pieceValue = pieceValueTrans[pieceValue]; - P_GiveMana(player, MANA_1, 20); - P_GiveMana(player, MANA_2, 20); - remove = false; - } - else - { // Deathmatch or single player game - gaveMana = P_GiveMana(player, MANA_1, 20)+ - P_GiveMana(player, MANA_2, 20); - if(player->pieces&pieceValue) - { // Already has the piece, check if mana needed - if(!gaveMana) - { // Didn't need the mana, so don't pick it up - return; - } - checkAssembled = false; - } - } - - // Pick up the weapon piece - if(pieceMobj->special) - { - P_ExecuteLineSpecial(pieceMobj->special, pieceMobj->args, - NULL, 0, player->mo); - pieceMobj->special = 0; - } - if(remove) - { - if(deathmatch && !(pieceMobj->flags2&MF2_DROPPED)) - { - P_HideSpecialThing(pieceMobj); - } - else - { - P_RemoveMobj(pieceMobj); - } - } - player->bonuscount += BONUSADD; - if(player == &players[consoleplayer]) - { - SB_PaletteFlash(false); - } - - // Check if fourth weapon assembled - if(checkAssembled) - { - player->pieces |= pieceValue; - if(player->pieces == (WPIECE1|WPIECE2|WPIECE3)) - { - gaveWeapon = true; - player->weaponowned[WP_FOURTH] = true; - player->pendingweapon = WP_FOURTH; - } - } - - if(gaveWeapon) - { - P_SetMessage(player, fourthWeaponText[matchClass], false); - // Play the build-sound full volume for all players - S_StartSound(NULL, SFX_WEAPON_BUILD); - } - else - { - P_SetMessage(player, weaponPieceText[matchClass], false); - if(player == &players[consoleplayer]) - { - S_StartSound(NULL, SFX_PICKUP_WEAPON); - } - } + boolean remove; + boolean checkAssembled; + boolean gaveWeapon; + int gaveMana; + static char *fourthWeaponText[] = { + TXT_WEAPON_F4, + TXT_WEAPON_C4, + TXT_WEAPON_M4 + }; + static char *weaponPieceText[] = { + TXT_QUIETUS_PIECE, + TXT_WRAITHVERGE_PIECE, + TXT_BLOODSCOURGE_PIECE + }; + static int pieceValueTrans[] = { + 0, // 0: never + WPIECE1 | WPIECE2 | WPIECE3, // WPIECE1 (1) + WPIECE2 | WPIECE3, // WPIECE2 (2) + 0, // 3: never + WPIECE3 // WPIECE3 (4) + }; + + remove = true; + checkAssembled = true; + gaveWeapon = false; + if (player->class != matchClass) + { // Wrong class, but try to pick up for mana + if (netgame && !deathmatch) + { // Can't pick up wrong-class weapons in coop netplay + return; + } + checkAssembled = false; + gaveMana = P_GiveMana(player, MANA_1, 20) + + P_GiveMana(player, MANA_2, 20); + if (!gaveMana) + { // Didn't need the mana, so don't pick it up + return; + } + } + else if (netgame && !deathmatch) + { // Cooperative net-game + if (player->pieces & pieceValue) + { // Already has the piece + return; + } + pieceValue = pieceValueTrans[pieceValue]; + P_GiveMana(player, MANA_1, 20); + P_GiveMana(player, MANA_2, 20); + remove = false; + } + else + { // Deathmatch or single player game + gaveMana = P_GiveMana(player, MANA_1, 20) + + P_GiveMana(player, MANA_2, 20); + if (player->pieces & pieceValue) + { // Already has the piece, check if mana needed + if (!gaveMana) + { // Didn't need the mana, so don't pick it up + return; + } + checkAssembled = false; + } + } + + // Pick up the weapon piece + if (pieceMobj->special) + { + P_ExecuteLineSpecial(pieceMobj->special, pieceMobj->args, + NULL, 0, player->mo); + pieceMobj->special = 0; + } + if (remove) + { + if (deathmatch && !(pieceMobj->flags2 & MF2_DROPPED)) + { + P_HideSpecialThing(pieceMobj); + } + else + { + P_RemoveMobj(pieceMobj); + } + } + player->bonuscount += BONUSADD; + if (player == &players[consoleplayer]) + { + SB_PaletteFlash(false); + } + + // Check if fourth weapon assembled + if (checkAssembled) + { + player->pieces |= pieceValue; + if (player->pieces == (WPIECE1 | WPIECE2 | WPIECE3)) + { + gaveWeapon = true; + player->weaponowned[WP_FOURTH] = true; + player->pendingweapon = WP_FOURTH; + } + } + + if (gaveWeapon) + { + P_SetMessage(player, fourthWeaponText[matchClass], false); + // Play the build-sound full volume for all players + S_StartSound(NULL, SFX_WEAPON_BUILD); + } + else + { + P_SetMessage(player, weaponPieceText[matchClass], false); + if (player == &players[consoleplayer]) + { + S_StartSound(NULL, SFX_PICKUP_WEAPON); + } + } } //--------------------------------------------------------------------------- @@ -549,26 +559,26 @@ static void TryPickupWeaponPiece(player_t *player, pclass_t matchClass, // //--------------------------------------------------------------------------- -boolean P_GiveBody(player_t *player, int num) +boolean P_GiveBody(player_t * player, int num) { - int max; - - max = MAXHEALTH; - if(player->morphTics) - { - max = MAXMORPHHEALTH; - } - if(player->health >= max) - { - return(false); - } - player->health += num; - if(player->health > max) - { - player->health = max; - } - player->mo->health = player->health; - return(true); + int max; + + max = MAXHEALTH; + if (player->morphTics) + { + max = MAXMORPHHEALTH; + } + if (player->health >= max) + { + return (false); + } + player->health += num; + if (player->health > max) + { + player->health = max; + } + player->mo->health = player->health; + return (true); } //--------------------------------------------------------------------------- @@ -579,43 +589,43 @@ boolean P_GiveBody(player_t *player, int num) // //--------------------------------------------------------------------------- -boolean P_GiveArmor(player_t *player, armortype_t armortype, int amount) +boolean P_GiveArmor(player_t * player, armortype_t armortype, int amount) { - int hits; - int totalArmor; - - extern int ArmorMax[NUMCLASSES]; - - if(amount == -1) - { - hits = ArmorIncrement[player->class][armortype]; - if(player->armorpoints[armortype] >= hits) - { - return false; - } - else - { - player->armorpoints[armortype] = hits; - } - } - else - { - hits = amount*5*FRACUNIT; - totalArmor = player->armorpoints[ARMOR_ARMOR] - +player->armorpoints[ARMOR_SHIELD] - +player->armorpoints[ARMOR_HELMET] - +player->armorpoints[ARMOR_AMULET] - +AutoArmorSave[player->class]; - if(totalArmor < ArmorMax[player->class]*5*FRACUNIT) - { - player->armorpoints[armortype] += hits; - } - else - { - return false; - } - } - return true; + int hits; + int totalArmor; + + extern int ArmorMax[NUMCLASSES]; + + if (amount == -1) + { + hits = ArmorIncrement[player->class][armortype]; + if (player->armorpoints[armortype] >= hits) + { + return false; + } + else + { + player->armorpoints[armortype] = hits; + } + } + else + { + hits = amount * 5 * FRACUNIT; + totalArmor = player->armorpoints[ARMOR_ARMOR] + + player->armorpoints[ARMOR_SHIELD] + + player->armorpoints[ARMOR_HELMET] + + player->armorpoints[ARMOR_AMULET] + + AutoArmorSave[player->class]; + if (totalArmor < ArmorMax[player->class] * 5 * FRACUNIT) + { + player->armorpoints[armortype] += hits; + } + else + { + return false; + } + } + return true; } //--------------------------------------------------------------------------- @@ -624,15 +634,15 @@ boolean P_GiveArmor(player_t *player, armortype_t armortype, int amount) // //--------------------------------------------------------------------------- -int P_GiveKey(player_t *player, keytype_t key) +int P_GiveKey(player_t * player, keytype_t key) { - if(player->keys&(1<<key)) - { - return false; - } - player->bonuscount += BONUSADD; - player->keys |= 1<<key; - return true; + if (player->keys & (1 << key)) + { + return false; + } + player->bonuscount += BONUSADD; + player->keys |= 1 << key; + return true; } //--------------------------------------------------------------------------- @@ -643,61 +653,61 @@ int P_GiveKey(player_t *player, keytype_t key) // //--------------------------------------------------------------------------- -boolean P_GivePower(player_t *player, powertype_t power) +boolean P_GivePower(player_t * player, powertype_t power) { - if(power == pw_invulnerability) - { - if(player->powers[power] > BLINKTHRESHOLD) - { // Already have it - return(false); - } - player->powers[power] = INVULNTICS; - player->mo->flags2 |= MF2_INVULNERABLE; - if(player->class == PCLASS_MAGE) - { - player->mo->flags2 |= MF2_REFLECTIVE; - } - return(true); - } - if(power == pw_flight) - { - if(player->powers[power] > BLINKTHRESHOLD) - { // Already have it - return(false); - } - player->powers[power] = FLIGHTTICS; - player->mo->flags2 |= MF2_FLY; - player->mo->flags |= MF_NOGRAVITY; - if(player->mo->z <= player->mo->floorz) - { - player->flyheight = 10; // thrust the player in the air a bit - } - return(true); - } - if(power == pw_infrared) - { - if(player->powers[power] > BLINKTHRESHOLD) - { // Already have it - return(false); - } - player->powers[power] = INFRATICS; - return(true); - } - if(power == pw_speed) - { - if(player->powers[power] > BLINKTHRESHOLD) - { // Already have it - return(false); - } - player->powers[power] = SPEEDTICS; - return(true); - } - if(power == pw_minotaur) - { - // Doesn't matter if already have power, renew ticker - player->powers[power] = MAULATORTICS; - return(true); - } + if (power == pw_invulnerability) + { + if (player->powers[power] > BLINKTHRESHOLD) + { // Already have it + return (false); + } + player->powers[power] = INVULNTICS; + player->mo->flags2 |= MF2_INVULNERABLE; + if (player->class == PCLASS_MAGE) + { + player->mo->flags2 |= MF2_REFLECTIVE; + } + return (true); + } + if (power == pw_flight) + { + if (player->powers[power] > BLINKTHRESHOLD) + { // Already have it + return (false); + } + player->powers[power] = FLIGHTTICS; + player->mo->flags2 |= MF2_FLY; + player->mo->flags |= MF_NOGRAVITY; + if (player->mo->z <= player->mo->floorz) + { + player->flyheight = 10; // thrust the player in the air a bit + } + return (true); + } + if (power == pw_infrared) + { + if (player->powers[power] > BLINKTHRESHOLD) + { // Already have it + return (false); + } + player->powers[power] = INFRATICS; + return (true); + } + if (power == pw_speed) + { + if (player->powers[power] > BLINKTHRESHOLD) + { // Already have it + return (false); + } + player->powers[power] = SPEEDTICS; + return (true); + } + if (power == pw_minotaur) + { + // Doesn't matter if already have power, renew ticker + player->powers[power] = MAULATORTICS; + return (true); + } /* if(power == pw_ironfeet) { @@ -711,12 +721,12 @@ boolean P_GivePower(player_t *player, powertype_t power) return(true); } */ - if(player->powers[power]) - { - return(false); // already got it - } - player->powers[power] = 1; - return(true); + if (player->powers[power]) + { + return (false); // already got it + } + player->powers[power] = 1; + return (true); } //========================================================================== @@ -725,71 +735,70 @@ boolean P_GivePower(player_t *player, powertype_t power) // //========================================================================== -static void TryPickupArtifact(player_t *player, artitype_t artifactType, - mobj_t *artifact) +static void TryPickupArtifact(player_t * player, artitype_t artifactType, + mobj_t * artifact) { - static char *artifactMessages[NUMARTIFACTS] = - { - NULL, - TXT_ARTIINVULNERABILITY, - TXT_ARTIHEALTH, - TXT_ARTISUPERHEALTH, - TXT_ARTIHEALINGRADIUS, - TXT_ARTISUMMON, - TXT_ARTITORCH, - TXT_ARTIEGG, - TXT_ARTIFLY, - TXT_ARTIBLASTRADIUS, - TXT_ARTIPOISONBAG, - TXT_ARTITELEPORTOTHER, - TXT_ARTISPEED, - TXT_ARTIBOOSTMANA, - TXT_ARTIBOOSTARMOR, - TXT_ARTITELEPORT, - TXT_ARTIPUZZSKULL, - TXT_ARTIPUZZGEMBIG, - TXT_ARTIPUZZGEMRED, - TXT_ARTIPUZZGEMGREEN1, - TXT_ARTIPUZZGEMGREEN2, - TXT_ARTIPUZZGEMBLUE1, - TXT_ARTIPUZZGEMBLUE2, - TXT_ARTIPUZZBOOK1, - TXT_ARTIPUZZBOOK2, - TXT_ARTIPUZZSKULL2, - TXT_ARTIPUZZFWEAPON, - TXT_ARTIPUZZCWEAPON, - TXT_ARTIPUZZMWEAPON, - TXT_ARTIPUZZGEAR, // All gear pickups use the same text - TXT_ARTIPUZZGEAR, - TXT_ARTIPUZZGEAR, - TXT_ARTIPUZZGEAR - }; - - if(P_GiveArtifact(player, artifactType, artifact)) - { - if(artifact->special) - { - P_ExecuteLineSpecial(artifact->special, artifact->args, - NULL, 0, NULL); - artifact->special = 0; - } - player->bonuscount += BONUSADD; - if(artifactType < arti_firstpuzzitem) - { - SetDormantArtifact(artifact); - S_StartSound(artifact, SFX_PICKUP_ARTIFACT); - P_SetMessage(player, artifactMessages[artifactType], false); - } - else - { // Puzzle item - S_StartSound(NULL, SFX_PICKUP_ITEM); - P_SetMessage(player, artifactMessages[artifactType], true); - if(!netgame || deathmatch) - { // Remove puzzle items if not cooperative netplay - P_RemoveMobj(artifact); - } - } - } + static char *artifactMessages[NUMARTIFACTS] = { + NULL, + TXT_ARTIINVULNERABILITY, + TXT_ARTIHEALTH, + TXT_ARTISUPERHEALTH, + TXT_ARTIHEALINGRADIUS, + TXT_ARTISUMMON, + TXT_ARTITORCH, + TXT_ARTIEGG, + TXT_ARTIFLY, + TXT_ARTIBLASTRADIUS, + TXT_ARTIPOISONBAG, + TXT_ARTITELEPORTOTHER, + TXT_ARTISPEED, + TXT_ARTIBOOSTMANA, + TXT_ARTIBOOSTARMOR, + TXT_ARTITELEPORT, + TXT_ARTIPUZZSKULL, + TXT_ARTIPUZZGEMBIG, + TXT_ARTIPUZZGEMRED, + TXT_ARTIPUZZGEMGREEN1, + TXT_ARTIPUZZGEMGREEN2, + TXT_ARTIPUZZGEMBLUE1, + TXT_ARTIPUZZGEMBLUE2, + TXT_ARTIPUZZBOOK1, + TXT_ARTIPUZZBOOK2, + TXT_ARTIPUZZSKULL2, + TXT_ARTIPUZZFWEAPON, + TXT_ARTIPUZZCWEAPON, + TXT_ARTIPUZZMWEAPON, + TXT_ARTIPUZZGEAR, // All gear pickups use the same text + TXT_ARTIPUZZGEAR, + TXT_ARTIPUZZGEAR, + TXT_ARTIPUZZGEAR + }; + + if (P_GiveArtifact(player, artifactType, artifact)) + { + if (artifact->special) + { + P_ExecuteLineSpecial(artifact->special, artifact->args, + NULL, 0, NULL); + artifact->special = 0; + } + player->bonuscount += BONUSADD; + if (artifactType < arti_firstpuzzitem) + { + SetDormantArtifact(artifact); + S_StartSound(artifact, SFX_PICKUP_ARTIFACT); + P_SetMessage(player, artifactMessages[artifactType], false); + } + else + { // Puzzle item + S_StartSound(NULL, SFX_PICKUP_ITEM); + P_SetMessage(player, artifactMessages[artifactType], true); + if (!netgame || deathmatch) + { // Remove puzzle items if not cooperative netplay + P_RemoveMobj(artifact); + } + } + } } //--------------------------------------------------------------------------- @@ -800,70 +809,71 @@ static void TryPickupArtifact(player_t *player, artitype_t artifactType, // //--------------------------------------------------------------------------- -boolean P_GiveArtifact(player_t *player, artitype_t arti, mobj_t *mo) +boolean P_GiveArtifact(player_t * player, artitype_t arti, mobj_t * mo) { - int i; - int j; - boolean slidePointer; - - slidePointer = false; - i = 0; - while(player->inventory[i].type != arti && i < player->inventorySlotNum) - { - i++; - } - if(i == player->inventorySlotNum) - { - if(arti < arti_firstpuzzitem) - { - i = 0; - while(player->inventory[i].type < arti_firstpuzzitem - && i < player->inventorySlotNum) - { - i++; - } - if(i != player->inventorySlotNum) - { - for(j = player->inventorySlotNum; j > i; j--) - { - player->inventory[j].count = player->inventory[j-1].count; - player->inventory[j].type = player->inventory[j-1].type; - slidePointer = true; - } - } - } - player->inventory[i].count = 1; - player->inventory[i].type = arti; - player->inventorySlotNum++; - } - else - { - if(arti >= arti_firstpuzzitem && netgame && !deathmatch) - { // Can't carry more than 1 puzzle item in coop netplay - return false; - } - if(player->inventory[i].count >= 25) - { // Player already has 25 of this item - return false; - } - player->inventory[i].count++; - } - if(!player->artifactCount) - { - player->readyArtifact = arti; - } - else if(player == &players[consoleplayer] && slidePointer - && i <= inv_ptr) - { - inv_ptr++; - curpos++; - if(curpos > 6) - { - curpos = 6; - } - } - player->artifactCount++; - return(true); + int i; + int j; + boolean slidePointer; + + slidePointer = false; + i = 0; + while (player->inventory[i].type != arti && i < player->inventorySlotNum) + { + i++; + } + if (i == player->inventorySlotNum) + { + if (arti < arti_firstpuzzitem) + { + i = 0; + while (player->inventory[i].type < arti_firstpuzzitem + && i < player->inventorySlotNum) + { + i++; + } + if (i != player->inventorySlotNum) + { + for (j = player->inventorySlotNum; j > i; j--) + { + player->inventory[j].count = + player->inventory[j - 1].count; + player->inventory[j].type = player->inventory[j - 1].type; + slidePointer = true; + } + } + } + player->inventory[i].count = 1; + player->inventory[i].type = arti; + player->inventorySlotNum++; + } + else + { + if (arti >= arti_firstpuzzitem && netgame && !deathmatch) + { // Can't carry more than 1 puzzle item in coop netplay + return false; + } + if (player->inventory[i].count >= 25) + { // Player already has 25 of this item + return false; + } + player->inventory[i].count++; + } + if (!player->artifactCount) + { + player->readyArtifact = arti; + } + else if (player == &players[consoleplayer] && slidePointer + && i <= inv_ptr) + { + inv_ptr++; + curpos++; + if (curpos > 6) + { + curpos = 6; + } + } + player->artifactCount++; + return (true); } //========================================================================== @@ -875,29 +885,28 @@ boolean P_GiveArtifact(player_t *player, artitype_t arti, mobj_t *mo) // //========================================================================== -static void SetDormantArtifact(mobj_t *arti) +static void SetDormantArtifact(mobj_t * arti) { - arti->flags &= ~MF_SPECIAL; - if(deathmatch && !(arti->flags2 & MF2_DROPPED)) - { - if(arti->type == MT_ARTIINVULNERABILITY) - { - P_SetMobjState(arti, S_DORMANTARTI3_1); - } - else if(arti->type == MT_SUMMONMAULATOR - || arti->type == MT_ARTIFLY) - { - P_SetMobjState(arti, S_DORMANTARTI2_1); - } - else - { - P_SetMobjState(arti, S_DORMANTARTI1_1); - } - } - else - { // Don't respawn - P_SetMobjState(arti, S_DEADARTI1); - } + arti->flags &= ~MF_SPECIAL; + if (deathmatch && !(arti->flags2 & MF2_DROPPED)) + { + if (arti->type == MT_ARTIINVULNERABILITY) + { + P_SetMobjState(arti, S_DORMANTARTI3_1); + } + else if (arti->type == MT_SUMMONMAULATOR || arti->type == MT_ARTIFLY) + { + P_SetMobjState(arti, S_DORMANTARTI2_1); + } + else + { + P_SetMobjState(arti, S_DORMANTARTI1_1); + } + } + else + { // Don't respawn + P_SetMobjState(arti, S_DEADARTI1); + } } //--------------------------------------------------------------------------- @@ -906,11 +915,11 @@ static void SetDormantArtifact(mobj_t *arti) // //--------------------------------------------------------------------------- -void A_RestoreArtifact(mobj_t *arti) +void A_RestoreArtifact(mobj_t * arti) { - arti->flags |= MF_SPECIAL; - P_SetMobjState(arti, arti->info->spawnstate); - S_StartSound(arti, SFX_RESPAWN); + arti->flags |= MF_SPECIAL; + P_SetMobjState(arti, arti->info->spawnstate); + S_StartSound(arti, SFX_RESPAWN); } //--------------------------------------------------------------------------- @@ -921,10 +930,10 @@ void A_RestoreArtifact(mobj_t *arti) // //--------------------------------------------------------------------------- -void A_RestoreSpecialThing1(mobj_t *thing) +void A_RestoreSpecialThing1(mobj_t * thing) { - thing->flags2 &= ~MF2_DONTDRAW; - S_StartSound(thing, SFX_RESPAWN); + thing->flags2 &= ~MF2_DONTDRAW; + S_StartSound(thing, SFX_RESPAWN); } //--------------------------------------------------------------------------- @@ -933,10 +942,10 @@ void A_RestoreSpecialThing1(mobj_t *thing) // //--------------------------------------------------------------------------- -void A_RestoreSpecialThing2(mobj_t *thing) +void A_RestoreSpecialThing2(mobj_t * thing) { - thing->flags |= MF_SPECIAL; - P_SetMobjState(thing, thing->info->spawnstate); + thing->flags |= MF_SPECIAL; + P_SetMobjState(thing, thing->info->spawnstate); } //--------------------------------------------------------------------------- @@ -945,350 +954,348 @@ void A_RestoreSpecialThing2(mobj_t *thing) // //--------------------------------------------------------------------------- -void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher) +void P_TouchSpecialThing(mobj_t * special, mobj_t * toucher) { - player_t *player; - fixed_t delta; - int sound; - boolean respawn; - - delta = special->z-toucher->z; - if(delta > toucher->height || delta < -32*FRACUNIT) - { // Out of reach - return; - } - if(toucher->health <= 0) - { // Toucher is dead - return; - } - sound = SFX_PICKUP_ITEM; - player = toucher->player; - respawn = true; - switch(special->sprite) - { - // Items - case SPR_PTN1: // Item_HealingPotion - if(!P_GiveBody(player, 10)) - { - return; - } - P_SetMessage(player, TXT_ITEMHEALTH, false); - break; - case SPR_ARM1: - if(!P_GiveArmor(player, ARMOR_ARMOR, -1)) - { - return; - } - P_SetMessage(player, TXT_ARMOR1, false); - break; - case SPR_ARM2: - if(!P_GiveArmor(player, ARMOR_SHIELD, -1)) - { - return; - } - P_SetMessage(player, TXT_ARMOR2, false); - break; - case SPR_ARM3: - if(!P_GiveArmor(player, ARMOR_HELMET, -1)) - { - return; - } - P_SetMessage(player, TXT_ARMOR3, false); - break; - case SPR_ARM4: - if(!P_GiveArmor(player, ARMOR_AMULET, -1)) - { - return; - } - P_SetMessage(player, TXT_ARMOR4, false); - break; - - // Keys - case SPR_KEY1: - case SPR_KEY2: - case SPR_KEY3: - case SPR_KEY4: - case SPR_KEY5: - case SPR_KEY6: - case SPR_KEY7: - case SPR_KEY8: - case SPR_KEY9: - case SPR_KEYA: - case SPR_KEYB: - if(!P_GiveKey(player, special->sprite-SPR_KEY1)) - { - return; - } - P_SetMessage(player, TextKeyMessages[special->sprite-SPR_KEY1], - true); - sound = SFX_PICKUP_KEY; - - // Check and process the special now in case the key doesn't - // get removed for coop netplay - if(special->special) - { - P_ExecuteLineSpecial(special->special, special->args, - NULL, 0, toucher); - special->special = 0; - } - - if(!netgame) - { // Only remove keys in single player game - break; - } - player->bonuscount += BONUSADD; - if(player == &players[consoleplayer]) - { - S_StartSound(NULL, sound); - SB_PaletteFlash(false); - } - return; - - // Artifacts - case SPR_PTN2: - TryPickupArtifact(player, arti_health, special); - return; - case SPR_SOAR: - TryPickupArtifact(player, arti_fly, special); - return; - case SPR_INVU: - TryPickupArtifact(player, arti_invulnerability, special); - return; - case SPR_SUMN: - TryPickupArtifact(player, arti_summon, special); - return; - case SPR_PORK: - TryPickupArtifact(player, arti_egg, special); - return; - case SPR_SPHL: - TryPickupArtifact(player, arti_superhealth, special); - return; - case SPR_HRAD: - TryPickupArtifact(player, arti_healingradius, special); - return; - case SPR_TRCH: - TryPickupArtifact(player, arti_torch, special); - return; - case SPR_ATLP: - TryPickupArtifact(player, arti_teleport, special); - return; - case SPR_TELO: - TryPickupArtifact(player, arti_teleportother, special); - return; - case SPR_PSBG: - TryPickupArtifact(player, arti_poisonbag, special); - return; - case SPR_SPED: - TryPickupArtifact(player, arti_speed, special); - return; - case SPR_BMAN: - TryPickupArtifact(player, arti_boostmana, special); - return; - case SPR_BRAC: - TryPickupArtifact(player, arti_boostarmor, special); - return; - case SPR_BLST: - TryPickupArtifact(player, arti_blastradius, special); - return; - - // Puzzle artifacts - case SPR_ASKU: - TryPickupArtifact(player, arti_puzzskull, special); - return; - case SPR_ABGM: - TryPickupArtifact(player, arti_puzzgembig, special); - return; - case SPR_AGMR: - TryPickupArtifact(player, arti_puzzgemred, special); - return; - case SPR_AGMG: - TryPickupArtifact(player, arti_puzzgemgreen1, special); - return; - case SPR_AGG2: - TryPickupArtifact(player, arti_puzzgemgreen2, special); - return; - case SPR_AGMB: - TryPickupArtifact(player, arti_puzzgemblue1, special); - return; - case SPR_AGB2: - TryPickupArtifact(player, arti_puzzgemblue2, special); - return; - case SPR_ABK1: - TryPickupArtifact(player, arti_puzzbook1, special); - return; - case SPR_ABK2: - TryPickupArtifact(player, arti_puzzbook2, special); - return; - case SPR_ASK2: - TryPickupArtifact(player, arti_puzzskull2, special); - return; - case SPR_AFWP: - TryPickupArtifact(player, arti_puzzfweapon, special); - return; - case SPR_ACWP: - TryPickupArtifact(player, arti_puzzcweapon, special); - return; - case SPR_AMWP: - TryPickupArtifact(player, arti_puzzmweapon, special); - return; - case SPR_AGER: - TryPickupArtifact(player, arti_puzzgear1, special); - return; - case SPR_AGR2: - TryPickupArtifact(player, arti_puzzgear2, special); - return; - case SPR_AGR3: - TryPickupArtifact(player, arti_puzzgear3, special); - return; - case SPR_AGR4: - TryPickupArtifact(player, arti_puzzgear4, special); - return; - - // Mana - case SPR_MAN1: - if(!P_GiveMana(player, MANA_1, 15)) - { - return; - } - P_SetMessage(player, TXT_MANA_1, false); - break; - case SPR_MAN2: - if(!P_GiveMana(player, MANA_2, 15)) - { - return; - } - P_SetMessage(player, TXT_MANA_2, false); - break; - case SPR_MAN3: // Double Mana Dodecahedron - if(!P_GiveMana(player, MANA_1, 20)) - { - if(!P_GiveMana(player, MANA_2, 20)) - { - return; - } - } - else - { - P_GiveMana(player, MANA_2, 20); - } - P_SetMessage(player, TXT_MANA_BOTH, false); - break; - - // 2nd and 3rd Mage Weapons - case SPR_WMCS: // Frost Shards - TryPickupWeapon(player, PCLASS_MAGE, WP_SECOND, - special, TXT_WEAPON_M2); - return; - case SPR_WMLG: // Arc of Death - TryPickupWeapon(player, PCLASS_MAGE, WP_THIRD, - special, TXT_WEAPON_M3); - return; - - // 2nd and 3rd Fighter Weapons - case SPR_WFAX: // Timon's Axe - TryPickupWeapon(player, PCLASS_FIGHTER, WP_SECOND, - special, TXT_WEAPON_F2); - return; - case SPR_WFHM: // Hammer of Retribution - TryPickupWeapon(player, PCLASS_FIGHTER, WP_THIRD, - special, TXT_WEAPON_F3); - return; - - // 2nd and 3rd Cleric Weapons - case SPR_WCSS: // Serpent Staff - TryPickupWeapon(player, PCLASS_CLERIC, WP_SECOND, - special, TXT_WEAPON_C2); - return; - case SPR_WCFM: // Firestorm - TryPickupWeapon(player, PCLASS_CLERIC, WP_THIRD, - special, TXT_WEAPON_C3); - return; - - // Fourth Weapon Pieces - case SPR_WFR1: - TryPickupWeaponPiece(player, PCLASS_FIGHTER, WPIECE1, - special); - return; - case SPR_WFR2: - TryPickupWeaponPiece(player, PCLASS_FIGHTER, WPIECE2, - special); - return; - case SPR_WFR3: - TryPickupWeaponPiece(player, PCLASS_FIGHTER, WPIECE3, - special); - return; - case SPR_WCH1: - TryPickupWeaponPiece(player, PCLASS_CLERIC, WPIECE1, - special); - return; - case SPR_WCH2: - TryPickupWeaponPiece(player, PCLASS_CLERIC, WPIECE2, - special); - return; - case SPR_WCH3: - TryPickupWeaponPiece(player, PCLASS_CLERIC, WPIECE3, - special); - return; - case SPR_WMS1: - TryPickupWeaponPiece(player, PCLASS_MAGE, WPIECE1, - special); - return; - case SPR_WMS2: - TryPickupWeaponPiece(player, PCLASS_MAGE, WPIECE2, - special); - return; - case SPR_WMS3: - TryPickupWeaponPiece(player, PCLASS_MAGE, WPIECE3, - special); - return; - - default: - I_Error("P_SpecialThing: Unknown gettable thing"); - } - if(special->special) - { - P_ExecuteLineSpecial(special->special, special->args, NULL, - 0, toucher); - special->special = 0; - } - if(deathmatch && respawn && !(special->flags2&MF2_DROPPED)) - { - P_HideSpecialThing(special); - } - else - { - P_RemoveMobj(special); - } - player->bonuscount += BONUSADD; - if(player == &players[consoleplayer]) - { - S_StartSound(NULL, sound); - SB_PaletteFlash(false); - } + player_t *player; + fixed_t delta; + int sound; + boolean respawn; + + delta = special->z - toucher->z; + if (delta > toucher->height || delta < -32 * FRACUNIT) + { // Out of reach + return; + } + if (toucher->health <= 0) + { // Toucher is dead + return; + } + sound = SFX_PICKUP_ITEM; + player = toucher->player; + respawn = true; + switch (special->sprite) + { + // Items + case SPR_PTN1: // Item_HealingPotion + if (!P_GiveBody(player, 10)) + { + return; + } + P_SetMessage(player, TXT_ITEMHEALTH, false); + break; + case SPR_ARM1: + if (!P_GiveArmor(player, ARMOR_ARMOR, -1)) + { + return; + } + P_SetMessage(player, TXT_ARMOR1, false); + break; + case SPR_ARM2: + if (!P_GiveArmor(player, ARMOR_SHIELD, -1)) + { + return; + } + P_SetMessage(player, TXT_ARMOR2, false); + break; + case SPR_ARM3: + if (!P_GiveArmor(player, ARMOR_HELMET, -1)) + { + return; + } + P_SetMessage(player, TXT_ARMOR3, false); + break; + case SPR_ARM4: + if (!P_GiveArmor(player, ARMOR_AMULET, -1)) + { + return; + } + P_SetMessage(player, TXT_ARMOR4, false); + break; + + // Keys + case SPR_KEY1: + case SPR_KEY2: + case SPR_KEY3: + case SPR_KEY4: + case SPR_KEY5: + case SPR_KEY6: + case SPR_KEY7: + case SPR_KEY8: + case SPR_KEY9: + case SPR_KEYA: + case SPR_KEYB: + if (!P_GiveKey(player, special->sprite - SPR_KEY1)) + { + return; + } + P_SetMessage(player, TextKeyMessages[special->sprite - SPR_KEY1], + true); + sound = SFX_PICKUP_KEY; + + // Check and process the special now in case the key doesn't + // get removed for coop netplay + if (special->special) + { + P_ExecuteLineSpecial(special->special, special->args, + NULL, 0, toucher); + special->special = 0; + } + + if (!netgame) + { // Only remove keys in single player game + break; + } + player->bonuscount += BONUSADD; + if (player == &players[consoleplayer]) + { + S_StartSound(NULL, sound); + SB_PaletteFlash(false); + } + return; + + // Artifacts + case SPR_PTN2: + TryPickupArtifact(player, arti_health, special); + return; + case SPR_SOAR: + TryPickupArtifact(player, arti_fly, special); + return; + case SPR_INVU: + TryPickupArtifact(player, arti_invulnerability, special); + return; + case SPR_SUMN: + TryPickupArtifact(player, arti_summon, special); + return; + case SPR_PORK: + TryPickupArtifact(player, arti_egg, special); + return; + case SPR_SPHL: + TryPickupArtifact(player, arti_superhealth, special); + return; + case SPR_HRAD: + TryPickupArtifact(player, arti_healingradius, special); + return; + case SPR_TRCH: + TryPickupArtifact(player, arti_torch, special); + return; + case SPR_ATLP: + TryPickupArtifact(player, arti_teleport, special); + return; + case SPR_TELO: + TryPickupArtifact(player, arti_teleportother, special); + return; + case SPR_PSBG: + TryPickupArtifact(player, arti_poisonbag, special); + return; + case SPR_SPED: + TryPickupArtifact(player, arti_speed, special); + return; + case SPR_BMAN: + TryPickupArtifact(player, arti_boostmana, special); + return; + case SPR_BRAC: + TryPickupArtifact(player, arti_boostarmor, special); + return; + case SPR_BLST: + TryPickupArtifact(player, arti_blastradius, special); + return; + + // Puzzle artifacts + case SPR_ASKU: + TryPickupArtifact(player, arti_puzzskull, special); + return; + case SPR_ABGM: + TryPickupArtifact(player, arti_puzzgembig, special); + return; + case SPR_AGMR: + TryPickupArtifact(player, arti_puzzgemred, special); + return; + case SPR_AGMG: + TryPickupArtifact(player, arti_puzzgemgreen1, special); + return; + case SPR_AGG2: + TryPickupArtifact(player, arti_puzzgemgreen2, special); + return; + case SPR_AGMB: + TryPickupArtifact(player, arti_puzzgemblue1, special); + return; + case SPR_AGB2: + TryPickupArtifact(player, arti_puzzgemblue2, special); + return; + case SPR_ABK1: + TryPickupArtifact(player, arti_puzzbook1, special); + return; + case SPR_ABK2: + TryPickupArtifact(player, arti_puzzbook2, special); + return; + case SPR_ASK2: + TryPickupArtifact(player, arti_puzzskull2, special); + return; + case SPR_AFWP: + TryPickupArtifact(player, arti_puzzfweapon, special); + return; + case SPR_ACWP: + TryPickupArtifact(player, arti_puzzcweapon, special); + return; + case SPR_AMWP: + TryPickupArtifact(player, arti_puzzmweapon, special); + return; + case SPR_AGER: + TryPickupArtifact(player, arti_puzzgear1, special); + return; + case SPR_AGR2: + TryPickupArtifact(player, arti_puzzgear2, special); + return; + case SPR_AGR3: + TryPickupArtifact(player, arti_puzzgear3, special); + return; + case SPR_AGR4: + TryPickupArtifact(player, arti_puzzgear4, special); + return; + + // Mana + case SPR_MAN1: + if (!P_GiveMana(player, MANA_1, 15)) + { + return; + } + P_SetMessage(player, TXT_MANA_1, false); + break; + case SPR_MAN2: + if (!P_GiveMana(player, MANA_2, 15)) + { + return; + } + P_SetMessage(player, TXT_MANA_2, false); + break; + case SPR_MAN3: // Double Mana Dodecahedron + if (!P_GiveMana(player, MANA_1, 20)) + { + if (!P_GiveMana(player, MANA_2, 20)) + { + return; + } + } + else + { + P_GiveMana(player, MANA_2, 20); + } + P_SetMessage(player, TXT_MANA_BOTH, false); + break; + + // 2nd and 3rd Mage Weapons + case SPR_WMCS: // Frost Shards + TryPickupWeapon(player, PCLASS_MAGE, WP_SECOND, + special, TXT_WEAPON_M2); + return; + case SPR_WMLG: // Arc of Death + TryPickupWeapon(player, PCLASS_MAGE, WP_THIRD, + special, TXT_WEAPON_M3); + return; + + // 2nd and 3rd Fighter Weapons + case SPR_WFAX: // Timon's Axe + TryPickupWeapon(player, PCLASS_FIGHTER, WP_SECOND, + special, TXT_WEAPON_F2); + return; + case SPR_WFHM: // Hammer of Retribution + TryPickupWeapon(player, PCLASS_FIGHTER, WP_THIRD, + special, TXT_WEAPON_F3); + return; + + // 2nd and 3rd Cleric Weapons + case SPR_WCSS: // Serpent Staff + TryPickupWeapon(player, PCLASS_CLERIC, WP_SECOND, + special, TXT_WEAPON_C2); + return; + case SPR_WCFM: // Firestorm + TryPickupWeapon(player, PCLASS_CLERIC, WP_THIRD, + special, TXT_WEAPON_C3); + return; + + // Fourth Weapon Pieces + case SPR_WFR1: + TryPickupWeaponPiece(player, PCLASS_FIGHTER, WPIECE1, special); + return; + case SPR_WFR2: + TryPickupWeaponPiece(player, PCLASS_FIGHTER, WPIECE2, special); + return; + case SPR_WFR3: + TryPickupWeaponPiece(player, PCLASS_FIGHTER, WPIECE3, special); + return; + case SPR_WCH1: + TryPickupWeaponPiece(player, PCLASS_CLERIC, WPIECE1, special); + return; + case SPR_WCH2: + TryPickupWeaponPiece(player, PCLASS_CLERIC, WPIECE2, special); + return; + case SPR_WCH3: + TryPickupWeaponPiece(player, PCLASS_CLERIC, WPIECE3, special); + return; + case SPR_WMS1: + TryPickupWeaponPiece(player, PCLASS_MAGE, WPIECE1, special); + return; + case SPR_WMS2: + TryPickupWeaponPiece(player, PCLASS_MAGE, WPIECE2, special); + return; + case SPR_WMS3: + TryPickupWeaponPiece(player, PCLASS_MAGE, WPIECE3, special); + return; + + default: + I_Error("P_SpecialThing: Unknown gettable thing"); + } + if (special->special) + { + P_ExecuteLineSpecial(special->special, special->args, NULL, + 0, toucher); + special->special = 0; + } + if (deathmatch && respawn && !(special->flags2 & MF2_DROPPED)) + { + P_HideSpecialThing(special); + } + else + { + P_RemoveMobj(special); + } + player->bonuscount += BONUSADD; + if (player == &players[consoleplayer]) + { + S_StartSound(NULL, sound); + SB_PaletteFlash(false); + } } // Search thinker list for minotaur -mobj_t *ActiveMinotaur(player_t *master) +mobj_t *ActiveMinotaur(player_t * master) { - mobj_t *mo; - player_t *plr; - thinker_t *think; - unsigned int *starttime; - - for(think = thinkercap.next; think != &thinkercap; think = think->next) - { - if(think->function != P_MobjThinker) continue; - mo = (mobj_t *)think; - if(mo->type != MT_MINOTAUR) continue; - if(mo->health <= 0) continue; - if(!(mo->flags&MF_COUNTKILL)) continue; // for morphed minotaurs - if(mo->flags&MF_CORPSE) continue; - starttime = (unsigned int *)mo->args; - if ((leveltime - *starttime) >= MAULATORTICS) continue; - plr = ((mobj_t *)mo->special1)->player; - if(plr == master) return(mo); - } - return(NULL); + mobj_t *mo; + player_t *plr; + thinker_t *think; + unsigned int *starttime; + + for (think = thinkercap.next; think != &thinkercap; think = think->next) + { + if (think->function != P_MobjThinker) + continue; + mo = (mobj_t *) think; + if (mo->type != MT_MINOTAUR) + continue; + if (mo->health <= 0) + continue; + if (!(mo->flags & MF_COUNTKILL)) + continue; // for morphed minotaurs + if (mo->flags & MF_CORPSE) + continue; + starttime = (unsigned int *) mo->args; + if ((leveltime - *starttime) >= MAULATORTICS) + continue; + plr = ((mobj_t *) mo->special1)->player; + if (plr == master) + return (mo); + } + return (NULL); } @@ -1298,229 +1305,227 @@ mobj_t *ActiveMinotaur(player_t *master) // //--------------------------------------------------------------------------- -void P_KillMobj(mobj_t *source, mobj_t *target) +void P_KillMobj(mobj_t * source, mobj_t * target) { - int dummy; - mobj_t *master; - - target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SKULLFLY|MF_NOGRAVITY); - target->flags |= MF_CORPSE|MF_DROPOFF; - target->flags2 &= ~MF2_PASSMOBJ; - target->height >>= 2; - if((target->flags&MF_COUNTKILL || target->type == MT_ZBELL) - && target->special) - { // Initiate monster death actions - if(target->type == MT_SORCBOSS) - { - dummy = 0; - P_StartACS(target->special, 0, (byte *)&dummy, target, - NULL, 0); - } - else - { - P_ExecuteLineSpecial(target->special, target->args, - NULL, 0, target); - } - } - if(source && source->player) - { // Check for frag changes - if(target->player) - { - if(target == source) - { // Self-frag - target->player->frags[target->player-players]--; - if(cmdfrag && netgame - && source->player == &players[consoleplayer]) - { // Send out a frag count packet - NET_SendFrags(source->player); - } - } - else - { - source->player->frags[target->player-players]++; - if(cmdfrag && netgame - && source->player == &players[consoleplayer]) - { // Send out a frag count packet - NET_SendFrags(source->player); - } - } - } - } - if(target->player) - { // Player death - if(!source) - { // Self-frag - target->player->frags[target->player-players]--; - if(cmdfrag && netgame - && target->player == &players[consoleplayer]) - { // Send out a frag count packet - NET_SendFrags(target->player); - } - } - target->flags &= ~MF_SOLID; - target->flags2 &= ~MF2_FLY; - target->player->powers[pw_flight] = 0; - target->player->playerstate = PST_DEAD; - P_DropWeapon(target->player); - if(target->flags2&MF2_FIREDAMAGE) - { // Player flame death - switch(target->player->class) - { - case PCLASS_FIGHTER: - S_StartSound(target, SFX_PLAYER_FIGHTER_BURN_DEATH); - P_SetMobjState(target, S_PLAY_F_FDTH1); - return; - case PCLASS_CLERIC: - S_StartSound(target, SFX_PLAYER_CLERIC_BURN_DEATH); - P_SetMobjState(target, S_PLAY_C_FDTH1); - return; - case PCLASS_MAGE: - S_StartSound(target, SFX_PLAYER_MAGE_BURN_DEATH); - P_SetMobjState(target, S_PLAY_M_FDTH1); - return; - default: - break; - } - } - if(target->flags2&MF2_ICEDAMAGE) - { // Player ice death - target->flags &= ~(7<<MF_TRANSSHIFT); //no translation - target->flags |= MF_ICECORPSE; - switch(target->player->class) - { - case PCLASS_FIGHTER: - P_SetMobjState(target, S_FPLAY_ICE); - return; - case PCLASS_CLERIC: - P_SetMobjState(target, S_CPLAY_ICE); - return; - case PCLASS_MAGE: - P_SetMobjState(target, S_MPLAY_ICE); - return; - case PCLASS_PIG: - P_SetMobjState(target, S_PIG_ICE); - return; - default: - break; - } - } - } - if(target->flags2&MF2_FIREDAMAGE) - { - if(target->type == MT_FIGHTER_BOSS - || target->type == MT_CLERIC_BOSS - || target->type == MT_MAGE_BOSS) - { - switch(target->type) - { - case MT_FIGHTER_BOSS: - S_StartSound(target, SFX_PLAYER_FIGHTER_BURN_DEATH); - P_SetMobjState(target, S_PLAY_F_FDTH1); - return; - case MT_CLERIC_BOSS: - S_StartSound(target, SFX_PLAYER_CLERIC_BURN_DEATH); - P_SetMobjState(target, S_PLAY_C_FDTH1); - return; - case MT_MAGE_BOSS: - S_StartSound(target, SFX_PLAYER_MAGE_BURN_DEATH); - P_SetMobjState(target, S_PLAY_M_FDTH1); - return; - default: - break; - } - } - else if(target->type == MT_TREEDESTRUCTIBLE) - { - P_SetMobjState(target, S_ZTREEDES_X1); - target->height = 24*FRACUNIT; - S_StartSound(target, SFX_TREE_EXPLODE); - return; - } - } - if(target->flags2&MF2_ICEDAMAGE) - { - target->flags |= MF_ICECORPSE; - switch(target->type) - { - case MT_BISHOP: - P_SetMobjState(target, S_BISHOP_ICE); - return; - case MT_CENTAUR: - case MT_CENTAURLEADER: - P_SetMobjState(target, S_CENTAUR_ICE); - return; - case MT_DEMON: - case MT_DEMON2: - P_SetMobjState(target, S_DEMON_ICE); - return; - case MT_SERPENT: - case MT_SERPENTLEADER: - P_SetMobjState(target, S_SERPENT_ICE); - return; - case MT_WRAITH: - case MT_WRAITHB: - P_SetMobjState(target, S_WRAITH_ICE); - return; - case MT_ETTIN: - P_SetMobjState(target, S_ETTIN_ICE1); - return; - case MT_FIREDEMON: - P_SetMobjState(target, S_FIRED_ICE1); - return; - case MT_FIGHTER_BOSS: - P_SetMobjState(target, S_FIGHTER_ICE); - return; - case MT_CLERIC_BOSS: - P_SetMobjState(target, S_CLERIC_ICE); - return; - case MT_MAGE_BOSS: - P_SetMobjState(target, S_MAGE_ICE); - return; - case MT_PIG: - P_SetMobjState(target, S_PIG_ICE); - return; - default: - target->flags &= ~MF_ICECORPSE; - break; - } - } - - if(target->type == MT_MINOTAUR) - { - master = (mobj_t *)target->special1; - if(master->health > 0) - { - if (!ActiveMinotaur(master->player)) - { - master->player->powers[pw_minotaur] = 0; - } - } - } - else if(target->type == MT_TREEDESTRUCTIBLE) - { - target->height = 24*FRACUNIT; - } - if(target->health < -(target->info->spawnhealth>>1) - && target->info->xdeathstate) - { // Extreme death - P_SetMobjState(target, target->info->xdeathstate); - } - else - { // Normal death - if ((target->type==MT_FIREDEMON) && - (target->z <= target->floorz + 2*FRACUNIT) && - (target->info->xdeathstate)) - { - // This is to fix the imps' staying in fall state - P_SetMobjState(target, target->info->xdeathstate); - } - else - { - P_SetMobjState(target, target->info->deathstate); - } - } - target->tics -= P_Random()&3; -// I_StartSound(&actor->r, actor->info->deathsound); + int dummy; + mobj_t *master; + + target->flags &= ~(MF_SHOOTABLE | MF_FLOAT | MF_SKULLFLY | MF_NOGRAVITY); + target->flags |= MF_CORPSE | MF_DROPOFF; + target->flags2 &= ~MF2_PASSMOBJ; + target->height >>= 2; + if ((target->flags & MF_COUNTKILL || target->type == MT_ZBELL) + && target->special) + { // Initiate monster death actions + if (target->type == MT_SORCBOSS) + { + dummy = 0; + P_StartACS(target->special, 0, (byte *) & dummy, target, NULL, 0); + } + else + { + P_ExecuteLineSpecial(target->special, target->args, + NULL, 0, target); + } + } + if (source && source->player) + { // Check for frag changes + if (target->player) + { + if (target == source) + { // Self-frag + target->player->frags[target->player - players]--; + if (cmdfrag && netgame + && source->player == &players[consoleplayer]) + { // Send out a frag count packet + NET_SendFrags(source->player); + } + } + else + { + source->player->frags[target->player - players]++; + if (cmdfrag && netgame + && source->player == &players[consoleplayer]) + { // Send out a frag count packet + NET_SendFrags(source->player); + } + } + } + } + if (target->player) + { // Player death + if (!source) + { // Self-frag + target->player->frags[target->player - players]--; + if (cmdfrag && netgame + && target->player == &players[consoleplayer]) + { // Send out a frag count packet + NET_SendFrags(target->player); + } + } + target->flags &= ~MF_SOLID; + target->flags2 &= ~MF2_FLY; + target->player->powers[pw_flight] = 0; + target->player->playerstate = PST_DEAD; + P_DropWeapon(target->player); + if (target->flags2 & MF2_FIREDAMAGE) + { // Player flame death + switch (target->player->class) + { + case PCLASS_FIGHTER: + S_StartSound(target, SFX_PLAYER_FIGHTER_BURN_DEATH); + P_SetMobjState(target, S_PLAY_F_FDTH1); + return; + case PCLASS_CLERIC: + S_StartSound(target, SFX_PLAYER_CLERIC_BURN_DEATH); + P_SetMobjState(target, S_PLAY_C_FDTH1); + return; + case PCLASS_MAGE: + S_StartSound(target, SFX_PLAYER_MAGE_BURN_DEATH); + P_SetMobjState(target, S_PLAY_M_FDTH1); + return; + default: + break; + } + } + if (target->flags2 & MF2_ICEDAMAGE) + { // Player ice death + target->flags &= ~(7 << MF_TRANSSHIFT); //no translation + target->flags |= MF_ICECORPSE; + switch (target->player->class) + { + case PCLASS_FIGHTER: + P_SetMobjState(target, S_FPLAY_ICE); + return; + case PCLASS_CLERIC: + P_SetMobjState(target, S_CPLAY_ICE); + return; + case PCLASS_MAGE: + P_SetMobjState(target, S_MPLAY_ICE); + return; + case PCLASS_PIG: + P_SetMobjState(target, S_PIG_ICE); + return; + default: + break; + } + } + } + if (target->flags2 & MF2_FIREDAMAGE) + { + if (target->type == MT_FIGHTER_BOSS + || target->type == MT_CLERIC_BOSS || target->type == MT_MAGE_BOSS) + { + switch (target->type) + { + case MT_FIGHTER_BOSS: + S_StartSound(target, SFX_PLAYER_FIGHTER_BURN_DEATH); + P_SetMobjState(target, S_PLAY_F_FDTH1); + return; + case MT_CLERIC_BOSS: + S_StartSound(target, SFX_PLAYER_CLERIC_BURN_DEATH); + P_SetMobjState(target, S_PLAY_C_FDTH1); + return; + case MT_MAGE_BOSS: + S_StartSound(target, SFX_PLAYER_MAGE_BURN_DEATH); + P_SetMobjState(target, S_PLAY_M_FDTH1); + return; + default: + break; + } + } + else if (target->type == MT_TREEDESTRUCTIBLE) + { + P_SetMobjState(target, S_ZTREEDES_X1); + target->height = 24 * FRACUNIT; + S_StartSound(target, SFX_TREE_EXPLODE); + return; + } + } + if (target->flags2 & MF2_ICEDAMAGE) + { + target->flags |= MF_ICECORPSE; + switch (target->type) + { + case MT_BISHOP: + P_SetMobjState(target, S_BISHOP_ICE); + return; + case MT_CENTAUR: + case MT_CENTAURLEADER: + P_SetMobjState(target, S_CENTAUR_ICE); + return; + case MT_DEMON: + case MT_DEMON2: + P_SetMobjState(target, S_DEMON_ICE); + return; + case MT_SERPENT: + case MT_SERPENTLEADER: + P_SetMobjState(target, S_SERPENT_ICE); + return; + case MT_WRAITH: + case MT_WRAITHB: + P_SetMobjState(target, S_WRAITH_ICE); + return; + case MT_ETTIN: + P_SetMobjState(target, S_ETTIN_ICE1); + return; + case MT_FIREDEMON: + P_SetMobjState(target, S_FIRED_ICE1); + return; + case MT_FIGHTER_BOSS: + P_SetMobjState(target, S_FIGHTER_ICE); + return; + case MT_CLERIC_BOSS: + P_SetMobjState(target, S_CLERIC_ICE); + return; + case MT_MAGE_BOSS: + P_SetMobjState(target, S_MAGE_ICE); + return; + case MT_PIG: + P_SetMobjState(target, S_PIG_ICE); + return; + default: + target->flags &= ~MF_ICECORPSE; + break; + } + } + + if (target->type == MT_MINOTAUR) + { + master = (mobj_t *) target->special1; + if (master->health > 0) + { + if (!ActiveMinotaur(master->player)) + { + master->player->powers[pw_minotaur] = 0; + } + } + } + else if (target->type == MT_TREEDESTRUCTIBLE) + { + target->height = 24 * FRACUNIT; + } + if (target->health < -(target->info->spawnhealth >> 1) + && target->info->xdeathstate) + { // Extreme death + P_SetMobjState(target, target->info->xdeathstate); + } + else + { // Normal death + if ((target->type == MT_FIREDEMON) && + (target->z <= target->floorz + 2 * FRACUNIT) && + (target->info->xdeathstate)) + { + // This is to fix the imps' staying in fall state + P_SetMobjState(target, target->info->xdeathstate); + } + else + { + P_SetMobjState(target, target->info->deathstate); + } + } + target->tics -= P_Random() & 3; +// I_StartSound(&actor->r, actor->info->deathsound); } //--------------------------------------------------------------------------- @@ -1529,22 +1534,22 @@ void P_KillMobj(mobj_t *source, mobj_t *target) // //--------------------------------------------------------------------------- -void P_MinotaurSlam(mobj_t *source, mobj_t *target) +void P_MinotaurSlam(mobj_t * source, mobj_t * target) { - angle_t angle; - fixed_t thrust; - - angle = R_PointToAngle2(source->x, source->y, target->x, target->y); - angle >>= ANGLETOFINESHIFT; - thrust = 16*FRACUNIT+(P_Random()<<10); - target->momx += FixedMul(thrust, finecosine[angle]); - target->momy += FixedMul(thrust, finesine[angle]); - P_DamageMobj(target, NULL, source, HITDICE(4)); - if(target->player) - { - target->reactiontime = 14+(P_Random()&7); - } - source->args[0] = 0; // Stop charging + angle_t angle; + fixed_t thrust; + + angle = R_PointToAngle2(source->x, source->y, target->x, target->y); + angle >>= ANGLETOFINESHIFT; + thrust = 16 * FRACUNIT + (P_Random() << 10); + target->momx += FixedMul(thrust, finecosine[angle]); + target->momy += FixedMul(thrust, finesine[angle]); + P_DamageMobj(target, NULL, source, HITDICE(4)); + if (target->player) + { + target->reactiontime = 14 + (P_Random() & 7); + } + source->args[0] = 0; // Stop charging } @@ -1556,49 +1561,49 @@ void P_MinotaurSlam(mobj_t *source, mobj_t *target) // //--------------------------------------------------------------------------- -boolean P_MorphPlayer(player_t *player) +boolean P_MorphPlayer(player_t * player) { - mobj_t *pmo; - mobj_t *fog; - mobj_t *beastMo; - fixed_t x; - fixed_t y; - fixed_t z; - angle_t angle; - int oldFlags2; - - if(player->powers[pw_invulnerability]) - { // Immune when invulnerable - return(false); - } - if(player->morphTics) - { // Player is already a beast - return false; - } - pmo = player->mo; - x = pmo->x; - y = pmo->y; - z = pmo->z; - angle = pmo->angle; - oldFlags2 = pmo->flags2; - P_SetMobjState(pmo, S_FREETARGMOBJ); - fog = P_SpawnMobj(x, y, z+TELEFOGHEIGHT, MT_TFOG); - S_StartSound(fog, SFX_TELEPORT); - beastMo = P_SpawnMobj(x, y, z, MT_PIGPLAYER); - beastMo->special1 = player->readyweapon; - beastMo->angle = angle; - beastMo->player = player; - player->health = beastMo->health = MAXMORPHHEALTH; - player->mo = beastMo; - memset(&player->armorpoints[0], 0, NUMARMOR*sizeof(int)); - player->class = PCLASS_PIG; - if(oldFlags2&MF2_FLY) - { - beastMo->flags2 |= MF2_FLY; - } - player->morphTics = MORPHTICS; - P_ActivateMorphWeapon(player); - return(true); + mobj_t *pmo; + mobj_t *fog; + mobj_t *beastMo; + fixed_t x; + fixed_t y; + fixed_t z; + angle_t angle; + int oldFlags2; + + if (player->powers[pw_invulnerability]) + { // Immune when invulnerable + return (false); + } + if (player->morphTics) + { // Player is already a beast + return false; + } + pmo = player->mo; + x = pmo->x; + y = pmo->y; + z = pmo->z; + angle = pmo->angle; + oldFlags2 = pmo->flags2; + P_SetMobjState(pmo, S_FREETARGMOBJ); + fog = P_SpawnMobj(x, y, z + TELEFOGHEIGHT, MT_TFOG); + S_StartSound(fog, SFX_TELEPORT); + beastMo = P_SpawnMobj(x, y, z, MT_PIGPLAYER); + beastMo->special1 = player->readyweapon; + beastMo->angle = angle; + beastMo->player = player; + player->health = beastMo->health = MAXMORPHHEALTH; + player->mo = beastMo; + memset(&player->armorpoints[0], 0, NUMARMOR * sizeof(int)); + player->class = PCLASS_PIG; + if (oldFlags2 & MF2_FLY) + { + beastMo->flags2 |= MF2_FLY; + } + player->morphTics = MORPHTICS; + P_ActivateMorphWeapon(player); + return (true); } //--------------------------------------------------------------------------- @@ -1607,63 +1612,66 @@ boolean P_MorphPlayer(player_t *player) // //--------------------------------------------------------------------------- -boolean P_MorphMonster(mobj_t *actor) +boolean P_MorphMonster(mobj_t * actor) { - mobj_t *master, *monster, *fog; - mobjtype_t moType; - fixed_t x; - fixed_t y; - fixed_t z; - mobj_t oldMonster; - - if(actor->player) return(false); - if(!(actor->flags&MF_COUNTKILL)) return false; - if(actor->flags2&MF2_BOSS) return false; - moType = actor->type; - switch(moType) - { - case MT_PIG: - return(false); - case MT_FIGHTER_BOSS: - case MT_CLERIC_BOSS: - case MT_MAGE_BOSS: - return(false); - default: - break; - } - - oldMonster = *actor; - x = oldMonster.x; - y = oldMonster.y; - z = oldMonster.z; - P_RemoveMobjFromTIDList(actor); - P_SetMobjState(actor, S_FREETARGMOBJ); - fog = P_SpawnMobj(x, y, z+TELEFOGHEIGHT, MT_TFOG); - S_StartSound(fog, SFX_TELEPORT); - monster = P_SpawnMobj(x, y, z, MT_PIG); - monster->special2 = moType; - monster->special1 = MORPHTICS+P_Random(); - monster->flags |= (oldMonster.flags&MF_SHADOW); - monster->target = oldMonster.target; - monster->angle = oldMonster.angle; - monster->tid = oldMonster.tid; - monster->special = oldMonster.special; - P_InsertMobjIntoTIDList(monster, oldMonster.tid); - memcpy(monster->args, oldMonster.args, 5); - - // check for turning off minotaur power for active icon - if (moType==MT_MINOTAUR) - { - master = (mobj_t *)oldMonster.special1; - if(master->health > 0) - { - if (!ActiveMinotaur(master->player)) - { - master->player->powers[pw_minotaur] = 0; - } - } - } - return(true); + mobj_t *master, *monster, *fog; + mobjtype_t moType; + fixed_t x; + fixed_t y; + fixed_t z; + mobj_t oldMonster; + + if (actor->player) + return (false); + if (!(actor->flags & MF_COUNTKILL)) + return false; + if (actor->flags2 & MF2_BOSS) + return false; + moType = actor->type; + switch (moType) + { + case MT_PIG: + return (false); + case MT_FIGHTER_BOSS: + case MT_CLERIC_BOSS: + case MT_MAGE_BOSS: + return (false); + default: + break; + } + + oldMonster = *actor; + x = oldMonster.x; + y = oldMonster.y; + z = oldMonster.z; + P_RemoveMobjFromTIDList(actor); + P_SetMobjState(actor, S_FREETARGMOBJ); + fog = P_SpawnMobj(x, y, z + TELEFOGHEIGHT, MT_TFOG); + S_StartSound(fog, SFX_TELEPORT); + monster = P_SpawnMobj(x, y, z, MT_PIG); + monster->special2 = moType; + monster->special1 = MORPHTICS + P_Random(); + monster->flags |= (oldMonster.flags & MF_SHADOW); + monster->target = oldMonster.target; + monster->angle = oldMonster.angle; + monster->tid = oldMonster.tid; + monster->special = oldMonster.special; + P_InsertMobjIntoTIDList(monster, oldMonster.tid); + memcpy(monster->args, oldMonster.args, 5); + + // check for turning off minotaur power for active icon + if (moType == MT_MINOTAUR) + { + master = (mobj_t *) oldMonster.special1; + if (master->health > 0) + { + if (!ActiveMinotaur(master->player)) + { + master->player->powers[pw_minotaur] = 0; + } + } + } + return (true); } //--------------------------------------------------------------------------- @@ -1672,65 +1680,65 @@ boolean P_MorphMonster(mobj_t *actor) // //--------------------------------------------------------------------------- -void P_AutoUseHealth(player_t *player, int saveHealth) +void P_AutoUseHealth(player_t * player, int saveHealth) { - int i; - int count; - int normalCount; - int normalSlot=0; - int superCount; - int superSlot=0; - - normalCount = superCount = 0; - for(i = 0; i < player->inventorySlotNum; i++) - { - if(player->inventory[i].type == arti_health) - { - normalSlot = i; - normalCount = player->inventory[i].count; - } - else if(player->inventory[i].type == arti_superhealth) - { - superSlot = i; - superCount = player->inventory[i].count; - } - } - if((gameskill == sk_baby) && (normalCount*25 >= saveHealth)) - { // Use quartz flasks - count = (saveHealth+24)/25; - for(i = 0; i < count; i++) - { - player->health += 25; - P_PlayerRemoveArtifact(player, normalSlot); - } - } - else if(superCount*100 >= saveHealth) - { // Use mystic urns - count = (saveHealth+99)/100; - for(i = 0; i < count; i++) - { - player->health += 100; - P_PlayerRemoveArtifact(player, superSlot); - } - } - else if((gameskill == sk_baby) - && (superCount*100+normalCount*25 >= saveHealth)) - { // Use mystic urns and quartz flasks - count = (saveHealth+24)/25; - saveHealth -= count*25; - for(i = 0; i < count; i++) - { - player->health += 25; - P_PlayerRemoveArtifact(player, normalSlot); - } - count = (saveHealth+99)/100; - for(i = 0; i < count; i++) - { - player->health += 100; - P_PlayerRemoveArtifact(player, normalSlot); - } - } - player->mo->health = player->health; + int i; + int count; + int normalCount; + int normalSlot = 0; + int superCount; + int superSlot = 0; + + normalCount = superCount = 0; + for (i = 0; i < player->inventorySlotNum; i++) + { + if (player->inventory[i].type == arti_health) + { + normalSlot = i; + normalCount = player->inventory[i].count; + } + else if (player->inventory[i].type == arti_superhealth) + { + superSlot = i; + superCount = player->inventory[i].count; + } + } + if ((gameskill == sk_baby) && (normalCount * 25 >= saveHealth)) + { // Use quartz flasks + count = (saveHealth + 24) / 25; + for (i = 0; i < count; i++) + { + player->health += 25; + P_PlayerRemoveArtifact(player, normalSlot); + } + } + else if (superCount * 100 >= saveHealth) + { // Use mystic urns + count = (saveHealth + 99) / 100; + for (i = 0; i < count; i++) + { + player->health += 100; + P_PlayerRemoveArtifact(player, superSlot); + } + } + else if ((gameskill == sk_baby) + && (superCount * 100 + normalCount * 25 >= saveHealth)) + { // Use mystic urns and quartz flasks + count = (saveHealth + 24) / 25; + saveHealth -= count * 25; + for (i = 0; i < count; i++) + { + player->health += 25; + P_PlayerRemoveArtifact(player, normalSlot); + } + count = (saveHealth + 99) / 100; + for (i = 0; i < count; i++) + { + player->health += 100; + P_PlayerRemoveArtifact(player, normalSlot); + } + } + player->mo->health = player->health; } /* @@ -1749,375 +1757,371 @@ void P_AutoUseHealth(player_t *player, int saveHealth) */ void P_DamageMobj -( - mobj_t *target, - mobj_t *inflictor, - mobj_t *source, - int damage -) + (mobj_t * target, mobj_t * inflictor, mobj_t * source, int damage) { - unsigned ang; - int saved; - fixed_t savedPercent; - player_t *player; - mobj_t *master; - fixed_t thrust; - int temp; - int i; - - if(!(target->flags&MF_SHOOTABLE)) - { - // Shouldn't happen - return; - } - if(target->health <= 0) - { - if (inflictor && inflictor->flags2&MF2_ICEDAMAGE) - { - return; - } - else if (target->flags&MF_ICECORPSE) // frozen - { - target->tics = 1; - target->momx = target->momy = 0; - } - return; - } - if ((target->flags2&MF2_INVULNERABLE) && damage < 10000) - { // mobj is invulnerable - if(target->player) return; // for player, no exceptions - if(inflictor) - { - switch(inflictor->type) - { - // These inflictors aren't foiled by invulnerability - case MT_HOLY_FX: - case MT_POISONCLOUD: - case MT_FIREBOMB: - break; - default: - return; - } - } - else - { - return; - } - } - if(target->player) - { - if(damage < 1000 && ((target->player->cheats&CF_GODMODE) - || target->player->powers[pw_invulnerability])) - { - return; - } - } - if(target->flags&MF_SKULLFLY) - { - target->momx = target->momy = target->momz = 0; - } - if(target->flags2&MF2_DORMANT) - { - // Invulnerable, and won't wake up - return; - } - player = target->player; - if(player && gameskill == sk_baby) - { - // Take half damage in trainer mode - damage >>= 1; - } - // Special damage types - if(inflictor) - { - switch(inflictor->type) - { - case MT_EGGFX: - if(player) - { - P_MorphPlayer(player); - } - else - { - P_MorphMonster(target); - } - return; // Always return - case MT_TELOTHER_FX1: - case MT_TELOTHER_FX2: - case MT_TELOTHER_FX3: - case MT_TELOTHER_FX4: - case MT_TELOTHER_FX5: - if ((target->flags&MF_COUNTKILL) && - (target->type != MT_SERPENT) && - (target->type != MT_SERPENTLEADER) && - (!(target->flags2 & MF2_BOSS))) - { - P_TeleportOther(target); - } - return; - case MT_MINOTAUR: - if(inflictor->flags&MF_SKULLFLY) - { // Slam only when in charge mode - P_MinotaurSlam(inflictor, target); - return; - } - break; - case MT_BISH_FX: - // Bishops are just too nasty - damage >>= 1; - break; - case MT_SHARDFX1: - switch(inflictor->special2) - { - case 3: - damage <<= 3; - break; - case 2: - damage <<= 2; - break; - case 1: - damage <<= 1; - break; - default: - break; - } - break; - case MT_CSTAFF_MISSILE: - // Cleric Serpent Staff does poison damage - if(target->player) - { - P_PoisonPlayer(target->player, source, 20); - damage >>= 1; - } - break; - case MT_ICEGUY_FX2: - damage >>= 1; - break; - case MT_POISONDART: - if(target->player) - { - P_PoisonPlayer(target->player, source, 20); - damage >>= 1; - } - break; - case MT_POISONCLOUD: - if(target->player) - { - if(target->player->poisoncount < 4) - { - P_PoisonDamage(target->player, source, - 15+(P_Random()&15), false); // Don't play painsound - P_PoisonPlayer(target->player, source, 50); - S_StartSound(target, SFX_PLAYER_POISONCOUGH); - } - return; - } - else if(!(target->flags&MF_COUNTKILL)) - { // only damage monsters/players with the poison cloud - return; - } - break; - case MT_FSWORD_MISSILE: - if(target->player) - { - damage -= damage>>2; - } - break; - default: - break; - } - } - // Push the target unless source is using the gauntlets - if(inflictor && (!source || !source->player) - && !(inflictor->flags2&MF2_NODMGTHRUST)) - { - ang = R_PointToAngle2(inflictor->x, inflictor->y, - target->x, target->y); - //thrust = damage*(FRACUNIT>>3)*100/target->info->mass; - thrust = damage*(FRACUNIT>>3)*150/target->info->mass; - // make fall forwards sometimes - if((damage < 40) && (damage > target->health) - && (target->z-inflictor->z > 64*FRACUNIT) && (P_Random()&1)) - { - ang += ANG180; - thrust *= 4; - } - ang >>= ANGLETOFINESHIFT; - target->momx += FixedMul(thrust, finecosine[ang]); - target->momy += FixedMul(thrust, finesine[ang]); - } - - // - // player specific - // - if(player) - { - savedPercent = AutoArmorSave[player->class] - +player->armorpoints[ARMOR_ARMOR]+player->armorpoints[ARMOR_SHIELD] - +player->armorpoints[ARMOR_HELMET] - +player->armorpoints[ARMOR_AMULET]; - if(savedPercent) - { // armor absorbed some damage - if(savedPercent > 100*FRACUNIT) - { - savedPercent = 100*FRACUNIT; - } - for(i = 0; i < NUMARMOR; i++) - { - if(player->armorpoints[i]) - { - player->armorpoints[i] -= - FixedDiv(FixedMul(damage<<FRACBITS, - ArmorIncrement[player->class][i]), 300*FRACUNIT); - if(player->armorpoints[i] < 2*FRACUNIT) - { - player->armorpoints[i] = 0; - } - } - } - saved = FixedDiv(FixedMul(damage<<FRACBITS, savedPercent), - 100*FRACUNIT); - if(saved > savedPercent*2) - { - saved = savedPercent*2; - } - damage -= saved>>FRACBITS; - } - if(damage >= player->health - && ((gameskill == sk_baby) || deathmatch) - && !player->morphTics) - { // Try to use some inventory health - P_AutoUseHealth(player, damage-player->health+1); - } - player->health -= damage; // mirror mobj health here for Dave - if(player->health < 0) - { - player->health = 0; - } - player->attacker = source; - player->damagecount += damage; // add damage after armor / invuln - if(player->damagecount > 100) - { - player->damagecount = 100; // teleport stomp does 10k points... - } - temp = damage < 100 ? damage : 100; - if(player == &players[consoleplayer]) - { - I_Tactile(40, 10, 40+temp*2); - SB_PaletteFlash(false); - } - } - - // - // do the damage - // - target->health -= damage; - if(target->health <= 0) - { // Death - if(inflictor) - { // check for special fire damage or ice damage deaths - if(inflictor->flags2&MF2_FIREDAMAGE) - { - if(player && !player->morphTics) - { // Check for flame death - if(target->health > -50 && damage > 25) - { - target->flags2 |= MF2_FIREDAMAGE; - } - } - else - { - target->flags2 |= MF2_FIREDAMAGE; - } - } - else if(inflictor->flags2&MF2_ICEDAMAGE) - { - target->flags2 |= MF2_ICEDAMAGE; - } - } - if(source && (source->type == MT_MINOTAUR)) - { // Minotaur's kills go to his master - master = (mobj_t *)(source->special1); - // Make sure still alive and not a pointer to fighter head - if (master->player && (master->player->mo == master)) - { - source = master; - } - } - if(source && (source->player) && - (source->player->readyweapon == WP_FOURTH)) - { - // Always extreme death from fourth weapon - target->health = -5000; - } - P_KillMobj(source, target); - return; - } - if((P_Random() < target->info->painchance) - && !(target->flags&MF_SKULLFLY)) - { - if(inflictor && (inflictor->type >= MT_LIGHTNING_FLOOR - && inflictor->type <= MT_LIGHTNING_ZAP)) - { - if(P_Random() < 96) - { - target->flags |= MF_JUSTHIT; // fight back! - P_SetMobjState(target, target->info->painstate); - } - else - { // "electrocute" the target - target->frame |= FF_FULLBRIGHT; - if(target->flags&MF_COUNTKILL && P_Random() < 128 - && !S_GetSoundPlayingInfo(target, SFX_PUPPYBEAT)) - { - if ((target->type == MT_CENTAUR) || - (target->type == MT_CENTAURLEADER) || - (target->type == MT_ETTIN)) - { - S_StartSound(target, SFX_PUPPYBEAT); - } - } - } - } - else - { - target->flags |= MF_JUSTHIT; // fight back! - P_SetMobjState(target, target->info->painstate); - if(inflictor && inflictor->type == MT_POISONCLOUD) - { - if(target->flags&MF_COUNTKILL && P_Random() < 128 - && !S_GetSoundPlayingInfo(target, SFX_PUPPYBEAT)) - { - if ((target->type == MT_CENTAUR) || - (target->type == MT_CENTAURLEADER) || - (target->type == MT_ETTIN)) - { - S_StartSound(target, SFX_PUPPYBEAT); - } - } - } - } - } - target->reactiontime = 0; // we're awake now... - if(!target->threshold && source && !(source->flags2&MF2_BOSS) - && !(target->type == MT_BISHOP) && !(target->type == MT_MINOTAUR)) - { - // Target actor is not intent on another actor, - // so make him chase after source - if((target->type == MT_CENTAUR && source->type == MT_CENTAURLEADER) - || (target->type == MT_CENTAURLEADER - && source->type == MT_CENTAUR)) - { - return; - } - target->target = source; - target->threshold = BASETHRESHOLD; - if(target->state == &states[target->info->spawnstate] - && target->info->seestate != S_NULL) - { - P_SetMobjState(target, target->info->seestate); - } - } + unsigned ang; + int saved; + fixed_t savedPercent; + player_t *player; + mobj_t *master; + fixed_t thrust; + int temp; + int i; + + if (!(target->flags & MF_SHOOTABLE)) + { + // Shouldn't happen + return; + } + if (target->health <= 0) + { + if (inflictor && inflictor->flags2 & MF2_ICEDAMAGE) + { + return; + } + else if (target->flags & MF_ICECORPSE) // frozen + { + target->tics = 1; + target->momx = target->momy = 0; + } + return; + } + if ((target->flags2 & MF2_INVULNERABLE) && damage < 10000) + { // mobj is invulnerable + if (target->player) + return; // for player, no exceptions + if (inflictor) + { + switch (inflictor->type) + { + // These inflictors aren't foiled by invulnerability + case MT_HOLY_FX: + case MT_POISONCLOUD: + case MT_FIREBOMB: + break; + default: + return; + } + } + else + { + return; + } + } + if (target->player) + { + if (damage < 1000 && ((target->player->cheats & CF_GODMODE) + || target->player->powers[pw_invulnerability])) + { + return; + } + } + if (target->flags & MF_SKULLFLY) + { + target->momx = target->momy = target->momz = 0; + } + if (target->flags2 & MF2_DORMANT) + { + // Invulnerable, and won't wake up + return; + } + player = target->player; + if (player && gameskill == sk_baby) + { + // Take half damage in trainer mode + damage >>= 1; + } + // Special damage types + if (inflictor) + { + switch (inflictor->type) + { + case MT_EGGFX: + if (player) + { + P_MorphPlayer(player); + } + else + { + P_MorphMonster(target); + } + return; // Always return + case MT_TELOTHER_FX1: + case MT_TELOTHER_FX2: + case MT_TELOTHER_FX3: + case MT_TELOTHER_FX4: + case MT_TELOTHER_FX5: + if ((target->flags & MF_COUNTKILL) && + (target->type != MT_SERPENT) && + (target->type != MT_SERPENTLEADER) && + (!(target->flags2 & MF2_BOSS))) + { + P_TeleportOther(target); + } + return; + case MT_MINOTAUR: + if (inflictor->flags & MF_SKULLFLY) + { // Slam only when in charge mode + P_MinotaurSlam(inflictor, target); + return; + } + break; + case MT_BISH_FX: + // Bishops are just too nasty + damage >>= 1; + break; + case MT_SHARDFX1: + switch (inflictor->special2) + { + case 3: + damage <<= 3; + break; + case 2: + damage <<= 2; + break; + case 1: + damage <<= 1; + break; + default: + break; + } + break; + case MT_CSTAFF_MISSILE: + // Cleric Serpent Staff does poison damage + if (target->player) + { + P_PoisonPlayer(target->player, source, 20); + damage >>= 1; + } + break; + case MT_ICEGUY_FX2: + damage >>= 1; + break; + case MT_POISONDART: + if (target->player) + { + P_PoisonPlayer(target->player, source, 20); + damage >>= 1; + } + break; + case MT_POISONCLOUD: + if (target->player) + { + if (target->player->poisoncount < 4) + { + P_PoisonDamage(target->player, source, 15 + (P_Random() & 15), false); // Don't play painsound + P_PoisonPlayer(target->player, source, 50); + S_StartSound(target, SFX_PLAYER_POISONCOUGH); + } + return; + } + else if (!(target->flags & MF_COUNTKILL)) + { // only damage monsters/players with the poison cloud + return; + } + break; + case MT_FSWORD_MISSILE: + if (target->player) + { + damage -= damage >> 2; + } + break; + default: + break; + } + } + // Push the target unless source is using the gauntlets + if (inflictor && (!source || !source->player) + && !(inflictor->flags2 & MF2_NODMGTHRUST)) + { + ang = R_PointToAngle2(inflictor->x, inflictor->y, + target->x, target->y); + //thrust = damage*(FRACUNIT>>3)*100/target->info->mass; + thrust = damage * (FRACUNIT >> 3) * 150 / target->info->mass; + // make fall forwards sometimes + if ((damage < 40) && (damage > target->health) + && (target->z - inflictor->z > 64 * FRACUNIT) && (P_Random() & 1)) + { + ang += ANG180; + thrust *= 4; + } + ang >>= ANGLETOFINESHIFT; + target->momx += FixedMul(thrust, finecosine[ang]); + target->momy += FixedMul(thrust, finesine[ang]); + } + + // + // player specific + // + if (player) + { + savedPercent = AutoArmorSave[player->class] + + player->armorpoints[ARMOR_ARMOR] + + player->armorpoints[ARMOR_SHIELD] + + player->armorpoints[ARMOR_HELMET] + + player->armorpoints[ARMOR_AMULET]; + if (savedPercent) + { // armor absorbed some damage + if (savedPercent > 100 * FRACUNIT) + { + savedPercent = 100 * FRACUNIT; + } + for (i = 0; i < NUMARMOR; i++) + { + if (player->armorpoints[i]) + { + player->armorpoints[i] -= + FixedDiv(FixedMul(damage << FRACBITS, + ArmorIncrement[player->class][i]), + 300 * FRACUNIT); + if (player->armorpoints[i] < 2 * FRACUNIT) + { + player->armorpoints[i] = 0; + } + } + } + saved = FixedDiv(FixedMul(damage << FRACBITS, savedPercent), + 100 * FRACUNIT); + if (saved > savedPercent * 2) + { + saved = savedPercent * 2; + } + damage -= saved >> FRACBITS; + } + if (damage >= player->health + && ((gameskill == sk_baby) || deathmatch) && !player->morphTics) + { // Try to use some inventory health + P_AutoUseHealth(player, damage - player->health + 1); + } + player->health -= damage; // mirror mobj health here for Dave + if (player->health < 0) + { + player->health = 0; + } + player->attacker = source; + player->damagecount += damage; // add damage after armor / invuln + if (player->damagecount > 100) + { + player->damagecount = 100; // teleport stomp does 10k points... + } + temp = damage < 100 ? damage : 100; + if (player == &players[consoleplayer]) + { + I_Tactile(40, 10, 40 + temp * 2); + SB_PaletteFlash(false); + } + } + + // + // do the damage + // + target->health -= damage; + if (target->health <= 0) + { // Death + if (inflictor) + { // check for special fire damage or ice damage deaths + if (inflictor->flags2 & MF2_FIREDAMAGE) + { + if (player && !player->morphTics) + { // Check for flame death + if (target->health > -50 && damage > 25) + { + target->flags2 |= MF2_FIREDAMAGE; + } + } + else + { + target->flags2 |= MF2_FIREDAMAGE; + } + } + else if (inflictor->flags2 & MF2_ICEDAMAGE) + { + target->flags2 |= MF2_ICEDAMAGE; + } + } + if (source && (source->type == MT_MINOTAUR)) + { // Minotaur's kills go to his master + master = (mobj_t *) (source->special1); + // Make sure still alive and not a pointer to fighter head + if (master->player && (master->player->mo == master)) + { + source = master; + } + } + if (source && (source->player) && + (source->player->readyweapon == WP_FOURTH)) + { + // Always extreme death from fourth weapon + target->health = -5000; + } + P_KillMobj(source, target); + return; + } + if ((P_Random() < target->info->painchance) + && !(target->flags & MF_SKULLFLY)) + { + if (inflictor && (inflictor->type >= MT_LIGHTNING_FLOOR + && inflictor->type <= MT_LIGHTNING_ZAP)) + { + if (P_Random() < 96) + { + target->flags |= MF_JUSTHIT; // fight back! + P_SetMobjState(target, target->info->painstate); + } + else + { // "electrocute" the target + target->frame |= FF_FULLBRIGHT; + if (target->flags & MF_COUNTKILL && P_Random() < 128 + && !S_GetSoundPlayingInfo(target, SFX_PUPPYBEAT)) + { + if ((target->type == MT_CENTAUR) || + (target->type == MT_CENTAURLEADER) || + (target->type == MT_ETTIN)) + { + S_StartSound(target, SFX_PUPPYBEAT); + } + } + } + } + else + { + target->flags |= MF_JUSTHIT; // fight back! + P_SetMobjState(target, target->info->painstate); + if (inflictor && inflictor->type == MT_POISONCLOUD) + { + if (target->flags & MF_COUNTKILL && P_Random() < 128 + && !S_GetSoundPlayingInfo(target, SFX_PUPPYBEAT)) + { + if ((target->type == MT_CENTAUR) || + (target->type == MT_CENTAURLEADER) || + (target->type == MT_ETTIN)) + { + S_StartSound(target, SFX_PUPPYBEAT); + } + } + } + } + } + target->reactiontime = 0; // we're awake now... + if (!target->threshold && source && !(source->flags2 & MF2_BOSS) + && !(target->type == MT_BISHOP) && !(target->type == MT_MINOTAUR)) + { + // Target actor is not intent on another actor, + // so make him chase after source + if ((target->type == MT_CENTAUR && source->type == MT_CENTAURLEADER) + || (target->type == MT_CENTAURLEADER + && source->type == MT_CENTAUR)) + { + return; + } + target->target = source; + target->threshold = BASETHRESHOLD; + if (target->state == &states[target->info->spawnstate] + && target->info->seestate != S_NULL) + { + P_SetMobjState(target, target->info->seestate); + } + } } //========================================================================== @@ -2126,28 +2130,28 @@ void P_DamageMobj // //========================================================================== -void P_FallingDamage(player_t *player) +void P_FallingDamage(player_t * player) { - int damage; - int mom; - int dist; - - mom = abs(player->mo->momz); - dist = FixedMul(mom, 16*FRACUNIT/23); - - if(mom >= 63*FRACUNIT) - { // automatic death - P_DamageMobj(player->mo, NULL, NULL, 10000); - return; - } - damage = ((FixedMul(dist, dist)/10)>>FRACBITS)-24; - if(player->mo->momz > -39*FRACUNIT && damage > player->mo->health - && player->mo->health != 1) - { // No-death threshold - damage = player->mo->health-1; - } - S_StartSound(player->mo, SFX_PLAYER_LAND); - P_DamageMobj(player->mo, NULL, NULL, damage); + int damage; + int mom; + int dist; + + mom = abs(player->mo->momz); + dist = FixedMul(mom, 16 * FRACUNIT / 23); + + if (mom >= 63 * FRACUNIT) + { // automatic death + P_DamageMobj(player->mo, NULL, NULL, 10000); + return; + } + damage = ((FixedMul(dist, dist) / 10) >> FRACBITS) - 24; + if (player->mo->momz > -39 * FRACUNIT && damage > player->mo->health + && player->mo->health != 1) + { // No-death threshold + damage = player->mo->health - 1; + } + S_StartSound(player->mo, SFX_PLAYER_LAND); + P_DamageMobj(player->mo, NULL, NULL, damage); } //========================================================================== @@ -2156,18 +2160,18 @@ void P_FallingDamage(player_t *player) // //========================================================================== -void P_PoisonPlayer(player_t *player, mobj_t *poisoner, int poison) +void P_PoisonPlayer(player_t * player, mobj_t * poisoner, int poison) { - if((player->cheats&CF_GODMODE) || player->powers[pw_invulnerability]) - { - return; - } - player->poisoncount += poison; - player->poisoner = poisoner; - if(player->poisoncount > 100) - { - player->poisoncount = 100; - } + if ((player->cheats & CF_GODMODE) || player->powers[pw_invulnerability]) + { + return; + } + player->poisoncount += poison; + player->poisoner = poisoner; + if (player->poisoncount > 100) + { + player->poisoncount = 100; + } } //========================================================================== @@ -2176,71 +2180,70 @@ void P_PoisonPlayer(player_t *player, mobj_t *poisoner, int poison) // //========================================================================== -void P_PoisonDamage(player_t *player, mobj_t *source, int damage, - boolean playPainSound) +void P_PoisonDamage(player_t * player, mobj_t * source, int damage, + boolean playPainSound) { - mobj_t *target; - mobj_t *inflictor; - - target = player->mo; - inflictor = source; - if(target->health <= 0) - { - return; - } - if(target->flags2&MF2_INVULNERABLE && damage < 10000) - { // mobj is invulnerable - return; - } - if(player && gameskill == sk_baby) - { - // Take half damage in trainer mode - damage >>= 1; - } - if(damage < 1000 && ((player->cheats&CF_GODMODE) - || player->powers[pw_invulnerability])) - { - return; - } - if(damage >= player->health - && ((gameskill == sk_baby) || deathmatch) - && !player->morphTics) - { // Try to use some inventory health - P_AutoUseHealth(player, damage-player->health+1); - } - player->health -= damage; // mirror mobj health here for Dave - if(player->health < 0) - { - player->health = 0; - } - player->attacker = source; - - // - // do the damage - // - target->health -= damage; - if(target->health <= 0) - { // Death - target->special1 = damage; - if(player && inflictor && !player->morphTics) - { // Check for flame death - if((inflictor->flags2&MF2_FIREDAMAGE) - && (target->health > -50) && (damage > 25)) - { - target->flags2 |= MF2_FIREDAMAGE; - } - if(inflictor->flags2&MF2_ICEDAMAGE) - { - target->flags2 |= MF2_ICEDAMAGE; - } - } - P_KillMobj(source, target); - return; - } - if(!(leveltime&63) && playPainSound) - { - P_SetMobjState(target, target->info->painstate); - } + mobj_t *target; + mobj_t *inflictor; + + target = player->mo; + inflictor = source; + if (target->health <= 0) + { + return; + } + if (target->flags2 & MF2_INVULNERABLE && damage < 10000) + { // mobj is invulnerable + return; + } + if (player && gameskill == sk_baby) + { + // Take half damage in trainer mode + damage >>= 1; + } + if (damage < 1000 && ((player->cheats & CF_GODMODE) + || player->powers[pw_invulnerability])) + { + return; + } + if (damage >= player->health + && ((gameskill == sk_baby) || deathmatch) && !player->morphTics) + { // Try to use some inventory health + P_AutoUseHealth(player, damage - player->health + 1); + } + player->health -= damage; // mirror mobj health here for Dave + if (player->health < 0) + { + player->health = 0; + } + player->attacker = source; + + // + // do the damage + // + target->health -= damage; + if (target->health <= 0) + { // Death + target->special1 = damage; + if (player && inflictor && !player->morphTics) + { // Check for flame death + if ((inflictor->flags2 & MF2_FIREDAMAGE) + && (target->health > -50) && (damage > 25)) + { + target->flags2 |= MF2_FIREDAMAGE; + } + if (inflictor->flags2 & MF2_ICEDAMAGE) + { + target->flags2 |= MF2_ICEDAMAGE; + } + } + P_KillMobj(source, target); + return; + } + if (!(leveltime & 63) && playPainSound) + { + P_SetMobjState(target, target->info->painstate); + } /* if((P_Random() < target->info->painchance) && !(target->flags&MF_SKULLFLY)) |