dd_bool P_GivePower(player_t* player, int power) { player->update |= PSF_POWERS; switch(power) { case PT_INVULNERABILITY: player->powers[power] = INVULNTICS; break; case PT_INVISIBILITY: player->powers[power] = INVISTICS; player->plr->mo->flags |= MF_SHADOW;; break; case PT_FLIGHT: player->powers[power] = 1; player->plr->mo->flags2 |= MF2_FLY; player->plr->mo->flags |= MF_NOGRAVITY; if(player->plr->mo->origin[VZ] <= player->plr->mo->floorZ) { player->flyHeight = 10; // Thrust the player in the air a bit. player->plr->mo->flags |= DDPF_FIXMOM; } break; case PT_INFRARED: player->powers[power] = INFRATICS; break; case PT_IRONFEET: player->powers[power] = IRONTICS; break; case PT_STRENGTH: P_GiveBody(player, maxHealth); player->powers[power] = 1; break; default: if(player->powers[power]) return false; // Already got it. player->powers[power] = 1; break; } if(power == PT_ALLMAP) ST_RevealAutomap(player - players, true); // Maybe unhide the HUD? ST_HUDUnHide(player - players, HUE_ON_PICKUP_POWER); return true; }
bool AHealthFillup::TryPickup (AActor *&toucher) { static const int skillhealths[5] = { -100, -75, -50, -50, -100 }; int index = clamp<int>(gameskill, 0,4); if (!P_GiveBody (toucher, skillhealths[index])) { return false; } GoAwayAndDie (); return true; }
bool AUpgradeStamina::TryPickup (AActor *&toucher) { if (toucher->player == NULL) return false; toucher->player->mo->stamina += Amount; if (toucher->player->mo->stamina >= MaxAmount) toucher->player->mo->stamina = MaxAmount; P_GiveBody (toucher, -100); GoAwayAndDie (); return true; }
bool AHealth::TryPickup (AActor *&other) { PrevHealth = other->player != NULL ? other->player->health : other->health; // P_GiveBody adds one new feature, applied only if it is possible to pick up negative health: // Negative values are treated as positive percentages, ie Amount -100 means 100% health, ignoring max amount. if (P_GiveBody(other, Amount, MaxAmount)) { GoAwayAndDie(); return true; } return false; }
// // P_GivePower // dboolean P_GivePower(player_t* player, int power) { if(power == pw_invulnerability) { player->powers[power] = INVULNTICS; return true; } if(power == pw_invisibility) { player->powers[power] = INVISTICS; player->mo->flags |= MF_SHADOW; return true; } if(power == pw_infrared) { player->powers[power] = INFRATICS; if(&players[displayplayer] == player) { infraredFactor = 300; R_RefreshBrightness(); } return true; } if(power == pw_ironfeet) { player->powers[power] = IRONTICS; return true; } if(power == pw_strength) { P_GiveBody(player, 100); player->powers[power] = STRTICS; return true; } if(player->powers[power]) { return false; // already got it } player->powers[power] = 1; return true; }
// // P_GiveItemToPlayer // // [STRIFE] New function // haleyjd 09/03/10: Sorts out how to give something to the player. // Not strictly just for inventory items. // villsa 09/09/10: Fleshed out function // boolean P_GiveItemToPlayer(player_t *player, int sprnum, mobjtype_t type) { int i = 0; line_t junk; int sound = sfx_itemup; // haleyjd 09/21/10: different sounds for items // set quest if mf_givequest flag is set if(mobjinfo[type].flags & MF_GIVEQUEST) player->questflags |= 1 << (mobjinfo[type].speed - 1); // check for keys if(type >= MT_KEY_BASE && type <= MT_NEWKEY5) { P_GiveCard(player, type - MT_KEY_BASE); return true; } // check for quest tokens if(type >= MT_TOKEN_QUEST1 && type <= MT_TOKEN_QUEST31) { if(mobjinfo[type].name) { M_StringCopy(pickupstring, DEH_String(mobjinfo[type].name), 39); player->message = pickupstring; } player->questflags |= 1 << (type - MT_TOKEN_QUEST1); if(player == &players[consoleplayer]) S_StartSound(NULL, sound); return true; } // haleyjd 09/22/10: Refactored to give sprites higher priority than // mobjtypes and to implement missing logic. switch(sprnum) { case SPR_HELT: // This is given only by the "DONNYTRUMP" cheat (aka Midas) P_GiveInventoryItem(player, SPR_HELT, MT_TOKEN_TOUGHNESS); P_GiveInventoryItem(player, SPR_GUNT, MT_TOKEN_ACCURACY); // [STRIFE] Bizarre... for(i = 0; i < 5 * player->accuracy + 300; i++) P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1); break; case SPR_ARM1: // Armor 1 if(!P_GiveArmor(player, -2)) P_GiveInventoryItem(player, sprnum, type); break; case SPR_ARM2: // Armor 2 if(!P_GiveArmor(player, -1)) P_GiveInventoryItem(player, sprnum, type); break; case SPR_COIN: // 1 Gold P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1); break; case SPR_CRED: // 10 Gold for(i = 0; i < 10; i++) P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1); break; case SPR_SACK: // 25 gold for(i = 0; i < 25; i++) P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1); break; case SPR_CHST: // 50 gold for(i = 0; i < 50; i++) P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1); case SPR_BBOX: // Box of Bullets if(!P_GiveAmmo(player, am_bullets, 5)) return false; break; case SPR_BLIT: // Bullet Clip if(!P_GiveAmmo(player, am_bullets, 1)) return false; break; case SPR_PMAP: // Map powerup if(!P_GivePower(player, pw_allmap)) return false; sound = sfx_yeah; // bluh-doop! break; case SPR_COMM: // Communicator if(!P_GivePower(player, pw_communicator)) return false; sound = sfx_yeah; // bluh-doop! break; case SPR_MSSL: // Mini-missile if(!P_GiveAmmo(player, am_missiles, 1)) return false; break; case SPR_ROKT: // Crate of missiles if(!P_GiveAmmo(player, am_missiles, 5)) return false; break; case SPR_BRY1: // Battery cell if(!P_GiveAmmo(player, am_cell, 1)) return false; break; case SPR_CPAC: // Cell pack if(!P_GiveAmmo(player, am_cell, 5)) return false; break; case SPR_PQRL: // Poison bolts if(!P_GiveAmmo(player, am_poisonbolts, 5)) return false; break; case SPR_XQRL: // Electric bolts if(!P_GiveAmmo(player, am_elecbolts, 5)) return false; break; case SPR_GRN1: // HE Grenades if(!P_GiveAmmo(player, am_hegrenades, 1)) return false; break; case SPR_GRN2: // WP Grenades if(!P_GiveAmmo(player, am_wpgrenades, 1)) return false; break; case SPR_BKPK: // Backpack (aka Ammo Satchel) if(!player->backpack) { for(i = 0; i < NUMAMMO; i++) player->maxammo[i] *= 2; player->backpack = true; } for(i = 0; i < NUMAMMO; i++) P_GiveAmmo(player, i, 1); break; case SPR_RIFL: // Assault Rifle if(player->weaponowned[wp_rifle]) return false; if(!P_GiveWeapon(player, wp_rifle, false)) return false; sound = sfx_wpnup; // SHK-CHK! break; case SPR_FLAM: // Flamethrower if(player->weaponowned[wp_flame]) return false; if(!P_GiveWeapon(player, wp_flame, false)) return false; sound = sfx_wpnup; // SHK-CHK! break; case SPR_MMSL: // Mini-missile Launcher if(player->weaponowned[wp_missile]) return false; if(!P_GiveWeapon(player, wp_missile, false)) return false; sound = sfx_wpnup; // SHK-CHK! break; case SPR_TRPD: // Mauler if(player->weaponowned[wp_mauler]) return false; if(!P_GiveWeapon(player, wp_mauler, false)) return false; sound = sfx_wpnup; // SHK-CHK! break; case SPR_CBOW: // Here's a crossbow. Just aim straight, and *SPLAT!* if(player->weaponowned[wp_elecbow]) return false; if(!P_GiveWeapon(player, wp_elecbow, false)) return false; sound = sfx_wpnup; // SHK-CHK! break; case SPR_TOKN: // Miscellaneous items - These are determined by thingtype. switch(type) { case MT_KEY_HAND: // Severed hand P_GiveCard(player, key_SeveredHand); break; case MT_MONY_300: // 300 Gold (this is the only way to get it, in fact) for(i = 0; i < 300; i++) P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1); break; case MT_TOKEN_AMMO: // Ammo token - you get this from the Weapons Trainer if(player->ammo[am_bullets] >= 50) return false; player->ammo[am_bullets] = 50; break; case MT_TOKEN_HEALTH: // Health token - from the Front's doctor if(!P_GiveBody(player, healthamounts[gameskill])) return false; break; case MT_TOKEN_ALARM: // Alarm token - particularly from the Oracle. P_NoiseAlert(player->mo, player->mo); A_AlertSpectreC(dialogtalker); // BUG: assumes in a dialog o_O break; case MT_TOKEN_DOOR1: // Door special 1 junk.tag = 222; EV_DoDoor(&junk, vld_open); break; case MT_TOKEN_PRISON_PASS: // Door special 1 - Prison pass junk.tag = 223; EV_DoDoor(&junk, vld_open); if(gamemap == 2) // If on Tarnhill, give Prison pass object P_GiveInventoryItem(player, sprnum, type); break; case MT_TOKEN_SHOPCLOSE: // Door special 3 - "Shop close" - unused? junk.tag = 222; EV_DoDoor(&junk, vld_close); break; case MT_TOKEN_DOOR3: // Door special 4 (or 3? :P ) junk.tag = 224; EV_DoDoor(&junk, vld_close); break; case MT_TOKEN_STAMINA: // Stamina upgrade if(player->stamina >= 100) return false; player->stamina += 10; P_GiveBody(player, 200); // full healing break; case MT_TOKEN_NEW_ACCURACY: // Accuracy upgrade if(player->accuracy >= 100) return false; player->accuracy += 10; break; case MT_SLIDESHOW: // Slideshow (start a finale) gameaction = ga_victory; if(gamemap == 10) P_GiveItemToPlayer(player, SPR_TOKN, MT_TOKEN_QUEST17); break; default: // The default is to just give it as an inventory item. P_GiveInventoryItem(player, sprnum, type); break; } break; default: // The ultimate default: Give it as an inventory item. if(!P_GiveInventoryItem(player, sprnum, type)) return false; break; } // Play sound. if(player == &players[consoleplayer]) S_StartSound(NULL, sound); return true; }
// // P_PlayerInSpecialSector // Called every tic frame // that the player origin is in a special sector // void P_PlayerInSpecialSector (player_t *player, sector_t * sector) { if (sector == NULL) { // Falling, not all the way down yet? sector = player->mo->Sector; if (!player->mo->isAtZ(sector->LowestFloorAt(player->mo)) && !player->mo->waterlevel) { return; } } // Has hit ground. AInventory *ironfeet; // [RH] Apply any customizable damage if (sector->damageamount > 0) { // Allow subclasses. Better would be to implement it as armor and let that reduce // the damage as part of the normal damage procedure. Unfortunately, I don't have // different damage types yet, so that's not happening for now. for (ironfeet = player->mo->Inventory; ironfeet != NULL; ironfeet = ironfeet->Inventory) { if (ironfeet->IsKindOf (RUNTIME_CLASS(APowerIronFeet))) break; } if (sector->Flags & SECF_ENDGODMODE) player->cheats &= ~CF_GODMODE; if ((ironfeet == NULL || pr_playerinspecialsector() < sector->leakydamage)) { if (sector->Flags & SECF_HAZARD) { player->hazardcount += sector->damageamount; player->hazardtype = sector->damagetype; player->hazardinterval = sector->damageinterval; } else if (level.time % sector->damageinterval == 0) { if (!(player->cheats & (CF_GODMODE|CF_GODMODE2))) P_DamageMobj(player->mo, NULL, NULL, sector->damageamount, sector->damagetype); if ((sector->Flags & SECF_ENDLEVEL) && player->health <= 10 && (!deathmatch || !(dmflags & DF_NO_EXIT))) { G_ExitLevel(0, false); } if (sector->Flags & SECF_DMGTERRAINFX) { P_HitWater(player->mo, player->mo->Sector, player->mo->Pos(), false, true, true); } } } } else if (sector->damageamount < 0) { if (level.time % sector->damageinterval == 0) { P_GiveBody(player->mo, -sector->damageamount, 100); } } if (sector->isSecret()) { sector->ClearSecret(); P_GiveSecret(player->mo, true, true, int(sector - sectors)); } }
bool AHealthPickup::Use (bool pickup) { return P_GiveBody (Owner, health); }
void cht_DoCheat (player_t *player, int cheat) { static const char * const BeholdPowers[9] = { "PowerInvulnerable", "PowerStrength", "PowerInvisibility", "PowerIronFeet", "MapRevealer", "PowerLightAmp", "PowerShadow", "PowerMask", "PowerTargeter", }; PClassActor *type; AInventory *item; const char *msg = ""; char msgbuild[32]; int i; switch (cheat) { case CHT_IDDQD: if (!(player->cheats & CF_GODMODE) && player->playerstate == PST_LIVE) { if (player->mo) player->mo->health = deh.GodHealth; player->health = deh.GodHealth; } // fall through to CHT_GOD case CHT_GOD: player->cheats ^= CF_GODMODE; if (player->cheats & CF_GODMODE) msg = GStrings("STSTR_DQDON"); else msg = GStrings("STSTR_DQDOFF"); ST_SetNeedRefresh(); break; case CHT_BUDDHA: player->cheats ^= CF_BUDDHA; if (player->cheats & CF_BUDDHA) msg = GStrings("TXT_BUDDHAON"); else msg = GStrings("TXT_BUDDHAOFF"); break; case CHT_GOD2: player->cheats ^= CF_GODMODE2; if (player->cheats & CF_GODMODE2) msg = GStrings("STSTR_DQD2ON"); else msg = GStrings("STSTR_DQD2OFF"); ST_SetNeedRefresh(); break; case CHT_BUDDHA2: player->cheats ^= CF_BUDDHA2; if (player->cheats & CF_BUDDHA2) msg = GStrings("TXT_BUDDHA2ON"); else msg = GStrings("TXT_BUDDHA2OFF"); break; case CHT_NOCLIP: player->cheats ^= CF_NOCLIP; if (player->cheats & CF_NOCLIP) msg = GStrings("STSTR_NCON"); else msg = GStrings("STSTR_NCOFF"); break; case CHT_NOCLIP2: player->cheats ^= CF_NOCLIP2; if (player->cheats & CF_NOCLIP2) { player->cheats |= CF_NOCLIP; msg = GStrings("STSTR_NC2ON"); } else { player->cheats &= ~CF_NOCLIP; msg = GStrings("STSTR_NCOFF"); } if (player->mo->Vel.X == 0) player->mo->Vel.X = MinVel; // force some lateral movement so that internal variables are up to date break; case CHT_NOVELOCITY: player->cheats ^= CF_NOVELOCITY; if (player->cheats & CF_NOVELOCITY) msg = GStrings("TXT_LEADBOOTSON"); else msg = GStrings("TXT_LEADBOOTSOFF"); break; case CHT_FLY: if (player->mo != NULL) { player->mo->flags7 ^= MF7_FLYCHEAT; if (player->mo->flags7 & MF7_FLYCHEAT) { player->mo->flags |= MF_NOGRAVITY; player->mo->flags2 |= MF2_FLY; msg = GStrings("TXT_LIGHTER"); } else { player->mo->flags &= ~MF_NOGRAVITY; player->mo->flags2 &= ~MF2_FLY; msg = GStrings("TXT_GRAVITY"); } } break; case CHT_MORPH: msg = cht_Morph (player, static_cast<PClassPlayerPawn *>(PClass::FindClass (gameinfo.gametype == GAME_Heretic ? NAME_ChickenPlayer : NAME_PigPlayer)), true); break; case CHT_NOTARGET: player->cheats ^= CF_NOTARGET; if (player->cheats & CF_NOTARGET) msg = "notarget ON"; else msg = "notarget OFF"; break; case CHT_ANUBIS: player->cheats ^= CF_FRIGHTENING; if (player->cheats & CF_FRIGHTENING) msg = "\"Quake with fear!\""; else msg = "No more ogre armor"; break; case CHT_CHASECAM: player->cheats ^= CF_CHASECAM; if (player->cheats & CF_CHASECAM) msg = "chasecam ON"; else msg = "chasecam OFF"; R_ResetViewInterpolation (); break; case CHT_CHAINSAW: if (player->mo != NULL && player->health >= 0) { type = PClass::FindActor("Chainsaw"); if (player->mo->FindInventory (type) == NULL) { player->mo->GiveInventoryType (type); } msg = GStrings("STSTR_CHOPPERS"); } // [RH] The original cheat also set powers[pw_invulnerability] to true. // Since this is a timer and not a boolean, it effectively turned off // the invulnerability powerup, although it looks like it was meant to // turn it on. break; case CHT_POWER: if (player->mo != NULL && player->health >= 0) { item = player->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true); if (item != NULL) { item->Destroy (); msg = GStrings("TXT_CHEATPOWEROFF"); } else { player->mo->GiveInventoryType (RUNTIME_CLASS(APowerWeaponLevel2)); msg = GStrings("TXT_CHEATPOWERON"); } } break; case CHT_IDKFA: cht_Give (player, "backpack"); cht_Give (player, "weapons"); cht_Give (player, "ammo"); cht_Give (player, "keys"); cht_Give (player, "armor"); msg = GStrings("STSTR_KFAADDED"); break; case CHT_IDFA: cht_Give (player, "backpack"); cht_Give (player, "weapons"); cht_Give (player, "ammo"); cht_Give (player, "armor"); msg = GStrings("STSTR_FAADDED"); break; case CHT_BEHOLDV: case CHT_BEHOLDS: case CHT_BEHOLDI: case CHT_BEHOLDR: case CHT_BEHOLDA: case CHT_BEHOLDL: case CHT_PUMPUPI: case CHT_PUMPUPM: case CHT_PUMPUPT: i = cheat - CHT_BEHOLDV; if (i == 4) { level.flags2 ^= LEVEL2_ALLMAP; } else if (player->mo != NULL && player->health >= 0) { item = player->mo->FindInventory(PClass::FindActor(BeholdPowers[i])); if (item == NULL) { if (i != 0) { cht_Give(player, BeholdPowers[i]); if (cheat == CHT_BEHOLDS) { P_GiveBody (player->mo, -100); } } else { // Let's give the item here so that the power doesn't need colormap information. cht_Give(player, "InvulnerabilitySphere"); } } else { item->Destroy (); } } msg = GStrings("STSTR_BEHOLDX"); break; case CHT_MASSACRE: { int killcount = P_Massacre (); // killough 3/22/98: make more intelligent about plural // Ty 03/27/98 - string(s) *not* externalized mysnprintf (msgbuild, countof(msgbuild), "%d Monster%s Killed", killcount, killcount==1 ? "" : "s"); msg = msgbuild; } break; case CHT_HEALTH: if (player->mo != NULL && player->playerstate == PST_LIVE) { player->health = player->mo->health = player->mo->GetDefault()->health; msg = GStrings("TXT_CHEATHEALTH"); } break; case CHT_KEYS: cht_Give (player, "keys"); msg = GStrings("TXT_CHEATKEYS"); break; // [GRB] case CHT_RESSURECT: if (player->playerstate != PST_LIVE && player->mo != nullptr) { if (player->mo->IsKindOf(RUNTIME_CLASS(APlayerChunk))) { Printf("Unable to resurrect. Player is no longer connected to its body.\n"); } else { player->playerstate = PST_LIVE; player->health = player->mo->health = player->mo->GetDefault()->health; player->viewheight = ((APlayerPawn *)player->mo->GetDefault())->ViewHeight; player->mo->flags = player->mo->GetDefault()->flags; player->mo->flags2 = player->mo->GetDefault()->flags2; player->mo->flags3 = player->mo->GetDefault()->flags3; player->mo->flags4 = player->mo->GetDefault()->flags4; player->mo->flags5 = player->mo->GetDefault()->flags5; player->mo->flags6 = player->mo->GetDefault()->flags6; player->mo->flags7 = player->mo->GetDefault()->flags7; player->mo->renderflags &= ~RF_INVISIBLE; player->mo->Height = player->mo->GetDefault()->Height; player->mo->radius = player->mo->GetDefault()->radius; player->mo->special1 = 0; // required for the Hexen fighter's fist attack. // This gets set by AActor::Die as flag for the wimpy death and must be reset here. player->mo->SetState (player->mo->SpawnState); if (!(player->mo->flags2 & MF2_DONTTRANSLATE)) { player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players)); } player->mo->DamageType = NAME_None; if (player->ReadyWeapon != nullptr) { P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetUpState()); } if (player->morphTics > 0) { P_UndoPlayerMorph(player, player); } } } break; case CHT_GIMMIEA: cht_Give (player, "ArtiInvulnerability"); msg = "Valador's Ring of Invunerability"; break; case CHT_GIMMIEB: cht_Give (player, "ArtiInvisibility"); msg = "Shadowsphere"; break; case CHT_GIMMIEC: cht_Give (player, "ArtiHealth"); msg = "Quartz Flask"; break; case CHT_GIMMIED: cht_Give (player, "ArtiSuperHealth"); msg = "Mystic Urn"; break; case CHT_GIMMIEE: cht_Give (player, "ArtiTomeOfPower"); msg = "Tyketto's Tome of Power"; break; case CHT_GIMMIEF: cht_Give (player, "ArtiTorch"); msg = "Torch"; break; case CHT_GIMMIEG: cht_Give (player, "ArtiTimeBomb"); msg = "Delmintalintar's Time Bomb of the Ancients"; break; case CHT_GIMMIEH: cht_Give (player, "ArtiEgg"); msg = "Torpol's Morph Ovum"; break; case CHT_GIMMIEI: cht_Give (player, "ArtiFly"); msg = "Inhilicon's Wings of Wrath"; break; case CHT_GIMMIEJ: cht_Give (player, "ArtiTeleport"); msg = "Darchala's Chaos Device"; break; case CHT_GIMMIEZ: for (int i=0; i<16; i++) { cht_Give (player, "artifacts"); } msg = "All artifacts!"; break; case CHT_TAKEWEAPS: if (player->morphTics || player->mo == NULL || player->mo->health <= 0) { return; } { // Take away all weapons that are either non-wimpy or use ammo. AInventory **invp = &player->mo->Inventory, **lastinvp; for (item = *invp; item != NULL; item = *invp) { lastinvp = invp; invp = &(*invp)->Inventory; if (item->IsKindOf (RUNTIME_CLASS(AWeapon))) { AWeapon *weap = static_cast<AWeapon *> (item); if (!(weap->WeaponFlags & WIF_WIMPY_WEAPON) || weap->AmmoType1 != NULL) { item->Destroy (); invp = lastinvp; } } } } msg = GStrings("TXT_CHEATIDKFA"); break; case CHT_NOWUDIE: cht_Suicide (player); msg = GStrings("TXT_CHEATIDDQD"); break; case CHT_ALLARTI: for (int i=0; i<25; i++) { cht_Give (player, "artifacts"); } msg = GStrings("TXT_CHEATARTIFACTS3"); break; case CHT_PUZZLE: cht_Give (player, "puzzlepieces"); msg = GStrings("TXT_CHEATARTIFACTS3"); break; case CHT_MDK: if (player->mo == NULL) { Printf ("What do you want to kill outside of a game?\n"); } else if (!deathmatch) { // Don't allow this in deathmatch even with cheats enabled, because it's // a very very cheap kill. P_LineAttack (player->mo, player->mo->Angles.Yaw, PLAYERMISSILERANGE, P_AimLineAttack (player->mo, player->mo->Angles.Yaw, PLAYERMISSILERANGE), TELEFRAG_DAMAGE, NAME_MDK, NAME_BulletPuff); } break; case CHT_DONNYTRUMP: cht_Give (player, "HealthTraining"); msg = GStrings("TXT_MIDASTOUCH"); break; case CHT_LEGO: if (player->mo != NULL && player->health >= 0) { int oldpieces = ASigil::GiveSigilPiece (player->mo); item = player->mo->FindInventory (RUNTIME_CLASS(ASigil)); if (item != NULL) { if (oldpieces == 5) { item->Destroy (); } else { player->PendingWeapon = static_cast<AWeapon *> (item); } } } break; case CHT_PUMPUPH: cht_Give (player, "MedPatch"); cht_Give (player, "MedicalKit"); cht_Give (player, "SurgeryKit"); msg = GStrings("TXT_GOTSTUFF"); break; case CHT_PUMPUPP: cht_Give (player, "AmmoSatchel"); msg = GStrings("TXT_GOTSTUFF"); break; case CHT_PUMPUPS: cht_Give (player, "UpgradeStamina", 10); cht_Give (player, "UpgradeAccuracy"); msg = GStrings("TXT_GOTSTUFF"); break; case CHT_CLEARFROZENPROPS: player->cheats &= ~(CF_FROZEN|CF_TOTALLYFROZEN); msg = "Frozen player properties turned off"; break; case CHT_FREEZE: bglobal.changefreeze ^= 1; if (bglobal.freeze ^ bglobal.changefreeze) { msg = GStrings("TXT_FREEZEON"); } else { msg = GStrings("TXT_FREEZEOFF"); } break; } if (!*msg) // [SO] Don't print blank lines! return; if (player == &players[consoleplayer]) Printf ("%s\n", msg); else if (cheat != CHT_CHASECAM) Printf ("%s cheats: %s\n", player->userinfo.GetName(), msg); }
/** * @param plr Player being given item. * @param item Type of item being given. * @param dropped @c true = the item was dropped by some entity. * * @return @c true iff the item should be destroyed. */ static dd_bool giveItem(player_t* plr, itemtype_t item, dd_bool dropped) { if(!plr) return false; switch(item) { case IT_ARMOR_GREEN: if(!P_GiveArmor(plr, armorClass[0], armorPoints[MINMAX_OF(0, armorClass[0] - 1, 1)])) return false; P_SetMessage(plr, GOTARMOR); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_ARMOR_BLUE: if(!P_GiveArmor(plr, armorClass[1], armorPoints[MINMAX_OF(0, armorClass[1] - 1, 1)])) return false; P_SetMessage(plr, GOTMEGA); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_ARMOR_BONUS: if(!plr->armorType) P_PlayerSetArmorType(plr, armorClass[0]); if(plr->armorPoints < armorPoints[1]) P_PlayerGiveArmorBonus(plr, 2); P_SetMessage(plr, GOTARMBONUS); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); // Maybe unhide the HUD? ST_HUDUnHide(plr - players, HUE_ON_PICKUP_ARMOR); break; case IT_HEALTH_BONUS: //plr->health++; // Can go over 100% plr->health += 2; // jd64 Can go over 100% if(plr->health > healthLimit) plr->health = healthLimit; plr->plr->mo->health = plr->health; plr->update |= PSF_HEALTH; P_SetMessage(plr, GOTHTHBONUS); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); // Maybe unhide the HUD? ST_HUDUnHide(plr - players, HUE_ON_PICKUP_HEALTH); break; case IT_HEALTH_SOULSPHERE: plr->health += soulSphereHealth; if(plr->health > soulSphereLimit) plr->health = soulSphereLimit; plr->plr->mo->health = plr->health; plr->update |= PSF_HEALTH; P_SetMessage(plr, GOTSUPER); S_ConsoleSound(SFX_GETPOW, NULL, plr - players); // Maybe unhide the HUD? ST_HUDUnHide(plr - players, HUE_ON_PICKUP_HEALTH); break; case IT_MEGASPHERE: plr->health = megaSphereHealth; plr->plr->mo->health = plr->health; plr->update |= PSF_HEALTH; P_GiveArmor(plr, armorClass[1], armorPoints[MINMAX_OF(0, armorClass[1] - 1, 1)]); P_SetMessage(plr, GOTMSPHERE); S_ConsoleSound(SFX_GETPOW, NULL, plr - players); // Maybe unhide the HUD? ST_HUDUnHide(plr - players, HUE_ON_PICKUP_HEALTH); break; case IT_KEY_BLUE: if(!plr->keys[KT_BLUECARD]) P_SetMessage(plr, GOTBLUECARD); P_GiveKey(plr, KT_BLUECARD); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); if(IS_NETGAME) return false; break; case IT_KEY_YELLOW: if(!plr->keys[KT_YELLOWCARD]) P_SetMessage(plr, GOTYELWCARD); P_GiveKey(plr, KT_YELLOWCARD); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); if(IS_NETGAME) return false; break; case IT_KEY_RED: if(!plr->keys[KT_REDCARD]) P_SetMessage(plr, GOTREDCARD); P_GiveKey(plr, KT_REDCARD); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); if(IS_NETGAME) return false; break; case IT_KEY_BLUESKULL: if(!plr->keys[KT_BLUESKULL]) P_SetMessage(plr, GOTBLUESKUL); P_GiveKey(plr, KT_BLUESKULL); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); if(IS_NETGAME) return false; break; case IT_KEY_YELLOWSKULL: if(!plr->keys[KT_YELLOWSKULL]) P_SetMessage(plr, GOTYELWSKUL); P_GiveKey(plr, KT_YELLOWSKULL); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); if(IS_NETGAME) return false; break; case IT_KEY_REDSKULL: if(!plr->keys[KT_REDSKULL]) P_SetMessage(plr, GOTREDSKULL); P_GiveKey(plr, KT_REDSKULL); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); if(IS_NETGAME) return false; break; case IT_HEALTH_PACK: if(!P_GiveBody(plr, 10)) return false; P_SetMessage(plr, GOTSTIM); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_HEALTH_KIT: { int oldHealth = plr->health; /** * DOOM bug: * The following test was originaly placed AFTER the call to * P_GiveBody thereby making the first outcome impossible as * the medikit gives 25 points of health. This resulted that * the GOTMEDINEED "Picked up a medikit that you REALLY need" * was never used. */ if(!P_GiveBody(plr, 25)) return false; P_SetMessage(plr, GET_TXT((oldHealth < 25)? TXT_GOTMEDINEED : TXT_GOTMEDIKIT)); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; } case IT_INVUL: if(!P_GivePower(plr, PT_INVULNERABILITY)) return false; P_SetMessage(plr, GOTINVUL); S_ConsoleSound(SFX_GETPOW, NULL, plr - players); break; case IT_BESERK: if(!P_GivePower(plr, PT_STRENGTH)) return false; P_SetMessage(plr, GOTBERSERK); if(plr->readyWeapon != WT_FIRST && cfg.berserkAutoSwitch) { plr->pendingWeapon = WT_FIRST; plr->update |= PSF_PENDING_WEAPON | PSF_READY_WEAPON; } S_ConsoleSound(SFX_GETPOW, NULL, plr - players); break; case IT_INVIS: if(!P_GivePower(plr, PT_INVISIBILITY)) return false; P_SetMessage(plr, GOTINVIS); S_ConsoleSound(SFX_GETPOW, NULL, plr - players); break; case IT_SUIT: if(!P_GivePower(plr, PT_IRONFEET)) return false; P_SetMessage(plr, GOTSUIT); S_ConsoleSound(SFX_GETPOW, NULL, plr - players); break; case IT_ALLMAP: if(!P_GivePower(plr, PT_ALLMAP)) return false; P_SetMessage(plr, GOTMAP); S_ConsoleSound(SFX_GETPOW, NULL, plr - players); break; case IT_VISOR: if(!P_GivePower(plr, PT_INFRARED)) return false; P_SetMessage(plr, GOTVISOR); S_ConsoleSound(SFX_GETPOW, NULL, plr - players); break; case IT_AMMO_CLIP: if(!P_GiveAmmo(plr, AT_CLIP, dropped? 0 : 1)) return false; P_SetMessage(plr, GOTCLIP); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_CLIP_BOX: if(!P_GiveAmmo(plr, AT_CLIP, 5)) return false; P_SetMessage(plr, GOTCLIPBOX); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_ROCKET: if(!P_GiveAmmo(plr, AT_MISSILE, 1)) return false; P_SetMessage(plr, GOTROCKET); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_ROCKET_BOX: if(!P_GiveAmmo(plr, AT_MISSILE, 5)) return false; P_SetMessage(plr, GOTROCKBOX); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_CELL: if(!P_GiveAmmo(plr, AT_CELL, 1)) return false; P_SetMessage(plr, GOTCELL); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_CELL_BOX: if(!P_GiveAmmo(plr, AT_CELL, 5)) return false; P_SetMessage(plr, GOTCELLBOX); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_SHELL: if(!P_GiveAmmo(plr, AT_SHELL, 1)) return false; P_SetMessage(plr, GOTSHELLS); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_SHELL_BOX: if(!P_GiveAmmo(plr, AT_SHELL, 5)) return false; P_SetMessage(plr, GOTSHELLBOX); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_BACKPACK: P_GiveBackpack(plr); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_WEAPON_BFG: if(!P_GiveWeapon(plr, WT_SEVENTH, dropped)) return false; P_SetMessage(plr, GOTBFG9000); S_ConsoleSound(SFX_WPNUP, NULL, plr - players); break; case IT_WEAPON_CHAINGUN: if(!P_GiveWeapon(plr, WT_FOURTH, dropped)) return false; P_SetMessage(plr, GOTCHAINGUN); S_ConsoleSound(SFX_WPNUP, NULL, plr - players); break; case IT_WEAPON_CHAINSAW: if(!P_GiveWeapon(plr, WT_EIGHTH, dropped)) return false; P_SetMessage(plr, GOTCHAINSAW); S_ConsoleSound(SFX_WPNUP, NULL, plr - players); break; case IT_WEAPON_RLAUNCHER: if(!P_GiveWeapon(plr, WT_FIFTH, dropped)) return false; P_SetMessage(plr, GOTLAUNCHER); S_ConsoleSound(SFX_WPNUP, NULL, plr - players); break; case IT_WEAPON_PLASMARIFLE: if(!P_GiveWeapon(plr, WT_SIXTH, dropped)) return false; P_SetMessage(plr, GOTPLASMA); S_ConsoleSound(SFX_WPNUP, NULL, plr - players); break; case IT_WEAPON_SHOTGUN: if(!P_GiveWeapon(plr, WT_THIRD, dropped)) return false; P_SetMessage(plr, GOTSHOTGUN); S_ConsoleSound(SFX_WPNUP, NULL, plr - players); break; case IT_WEAPON_SSHOTGUN: if(!P_GiveWeapon(plr, WT_NINETH, dropped)) return false; P_SetMessage(plr, GOTSHOTGUN2); S_ConsoleSound(SFX_WPNUP, NULL, plr - players); break; case IT_WEAPON_LASERGUN: if(!P_GiveWeapon(plr, WT_TENTH, dropped)) return false; P_SetMessage(plr, GOTUNMAKER); S_ConsoleSound(SFX_WPNUP, NULL, plr - players); break; case IT_DEMONKEY1: if(P_InventoryCount(plr - players, IIT_DEMONKEY1)) { if(!(mapTime & 0x1f)) P_SetMessage(plr, NGOTPOWERUP1); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); return false; //Don't destroy item, can be collected later by other players. } else { P_GiveItem(plr, IIT_DEMONKEY1); P_SetMessage(plr, GOTPOWERUP1); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); } break; case IT_DEMONKEY2: if(P_InventoryCount(plr - players, IIT_DEMONKEY2)) { if(!(mapTime & 0x1f)) P_SetMessage(plr, NGOTPOWERUP2); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); return false; //Don't destroy item, can be collected later by other players. } else { P_GiveItem(plr, IIT_DEMONKEY2); P_SetMessage(plr, GOTPOWERUP2); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); } break; case IT_DEMONKEY3: if(P_InventoryCount(plr - players, IIT_DEMONKEY3)) { if(!(mapTime & 0x1f)) P_SetMessage(plr, NGOTPOWERUP3); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); return false; //Don't destroy item, can be collected later by other players. } else { P_GiveItem(plr, IIT_DEMONKEY3); P_SetMessage(plr, GOTPOWERUP3); S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); } break; default: Con_Error("giveItem: Unknown item %i.", (int) item); } return true; }
// // P_TouchSpecialThing // void P_TouchSpecialThing(mobj_t* special, mobj_t* toucher) { player_t* player; fixed_t delta; int sound; int i = 0; delta = special->z - toucher->z; if(delta > toucher->height || delta < -8*FRACUNIT) { // out of reach return; } sound = sfx_itemup; player = toucher->player; // Dead thing touching. // Can happen with a sliding player corpse. if(toucher->health <= 0) { return; } // Identify by sprite. switch(special->sprite) { // armor case SPR_ARM1: if(!P_GiveArmor(player, 1)) { return; } player->message = GOTARMOR; player->messagepic = 23; break; case SPR_ARM2: if(!P_GiveArmor(player, 2)) { return; } player->message = GOTMEGA; player->messagepic = 24; break; // bonus items case SPR_BON1: player->health+=2; // can go over 100% if(player->health > 200) { player->health = 200; } player->mo->health = player->health; player->message = GOTHTHBONUS; player->messagepic = 3; break; case SPR_BON2: player->armorpoints+=2; // can go over 100% if(player->armorpoints > 200) { player->armorpoints = 200; } if(!player->armortype) { player->armortype = 1; } player->message = GOTARMBONUS; player->messagepic = 4; break; case SPR_SOUL: player->health += 100; if(player->health > 200) { player->health = 200; } player->mo->health = player->health; player->message = GOTSUPER; player->messagepic = 5; sound = sfx_powerup; break; case SPR_MEGA: player->health = 200; player->mo->health = player->health; P_GiveArmor(player,2); player->message = GOTMSPHERE; player->messagepic = 6; sound = sfx_powerup; break; // cards // leave cards for everyone case SPR_BKEY: if(!(P_GiveCard(player, special, it_bluecard))) { return; } break; case SPR_YKEY: if(!(P_GiveCard(player, special, it_yellowcard))) { return; } break; case SPR_RKEY: if(!(P_GiveCard(player, special, it_redcard))) { return; } break; case SPR_BSKU: if(!(P_GiveCard(player, special, it_blueskull))) { return; } break; case SPR_YSKU: if(!(P_GiveCard(player, special, it_yellowskull))) { return; } break; case SPR_RSKU: if(!(P_GiveCard(player, special, it_redskull))) { return; } break; // medikits, heals case SPR_STIM: if(!P_GiveBody(player, 10)) { return; } player->message = GOTSTIM; player->messagepic = 31; break; case SPR_MEDI: if(!P_GiveBody(player, 25)) { return; } if(player->health < 25) { player->message = GOTMEDINEED; player->messagepic = 32; } else { player->message = GOTMEDIKIT; player->messagepic = 33; } break; // power ups case SPR_PINV: if(!P_GivePower(player, pw_invulnerability)) { return; } player->message = GOTINVUL; player->messagepic = 34; sound = sfx_powerup; break; case SPR_PSTR: if(!P_GivePower(player, pw_strength)) { return; } player->message = GOTBERSERK; player->messagepic = 35; if(player->readyweapon != wp_fist) { player->pendingweapon = wp_fist; } sound = sfx_powerup; break; case SPR_PINS: if(!P_GivePower(player, pw_invisibility)) { return; } player->message = GOTINVIS; player->messagepic = 36; sound = sfx_powerup; break; case SPR_SUIT: if(!P_GivePower(player, pw_ironfeet)) { return; } player->message = GOTSUIT; player->messagepic = 37; sound = sfx_powerup; break; case SPR_PMAP: if(!P_GivePower(player, pw_allmap)) { return; } player->message = GOTMAP; player->messagepic = 38; sound = sfx_powerup; break; case SPR_PVIS: if(!P_GivePower(player, pw_infrared)) { return; } player->message = GOTVISOR; player->messagepic = 39; sound = sfx_powerup; break; // ammo case SPR_CLIP: if(special->flags & MF_DROPPED) { if(!P_GiveAmmo(player,am_clip,0)) { return; } } else { if(!P_GiveAmmo(player,am_clip,1)) { return; } } player->message = GOTCLIP; player->messagepic = 7; break; case SPR_AMMO: if(!P_GiveAmmo(player, am_clip,5)) { return; } player->message = GOTCLIPBOX; player->messagepic = 8; break; case SPR_RCKT: if(!P_GiveAmmo(player, am_misl,1)) { return; } player->message = GOTROCKET; player->messagepic = 9; break; case SPR_BROK: if(!P_GiveAmmo(player, am_misl,5)) { return; } player->message = GOTROCKBOX; player->messagepic = 10; break; case SPR_CELL: if(!P_GiveAmmo(player, am_cell,1)) { return; } player->message = GOTCELL; player->messagepic = 11; break; case SPR_CELP: if(!P_GiveAmmo(player, am_cell,5)) { return; } player->message = GOTCELLBOX; player->messagepic = 12; break; case SPR_SHEL: if(!P_GiveAmmo(player, am_shell,1)) { return; } player->message = (gameskill == sk_baby)?GOTSHELLS2:GOTSHELLS; //villsa player->messagepic = 13; break; case SPR_SBOX: if(!P_GiveAmmo(player, am_shell,5)) { return; } player->message = GOTSHELLBOX; player->messagepic = 14; break; case SPR_BPAK: if(!player->backpack) { for(i = 0; i < NUMAMMO; i++) { player->maxammo[i] *= 2; } player->backpack = true; } for(i = 0; i < NUMAMMO; i++) { P_GiveAmmo(player, i, 1); } player->message = GOTBACKPACK; player->messagepic = 15; break; // weapons case SPR_BFUG: if(!P_GiveWeapon(player, special, wp_bfg, false)) { return; } player->message = GOTBFG9000; player->messagepic = 16; sound = sfx_sgcock; break; case SPR_MGUN: if(!P_GiveWeapon(player, special, wp_chaingun, special->flags&MF_DROPPED)) { return; } player->message = GOTCHAINGUN; player->messagepic = 17; sound = sfx_sgcock; break; case SPR_CSAW: if(!P_GiveWeapon(player, special, wp_chainsaw, false)) { return; } player->message = GOTCHAINSAW; player->messagepic = 18; sound = sfx_sgcock; break; case SPR_LAUN: if(!P_GiveWeapon(player, special, wp_missile, false)) { return; } player->message = GOTLAUNCHER; player->messagepic = 19; sound = sfx_sgcock; break; case SPR_PLSM: if(!P_GiveWeapon(player, special, wp_plasma, false)) { return; } player->message = GOTPLASMA; player->messagepic = 20; sound = sfx_sgcock; break; case SPR_SHOT: if(!P_GiveWeapon(player, special, wp_shotgun, special->flags&MF_DROPPED)) { return; } player->message = GOTSHOTGUN; player->messagepic = 21; sound = sfx_sgcock; break; case SPR_SGN2: if(!P_GiveWeapon(player, special, wp_supershotgun, special->flags&MF_DROPPED)) { return; } player->message = GOTSHOTGUN2; player->messagepic = 22; sound = sfx_sgcock; break; case SPR_LSRG: if(!P_GiveWeapon(player, special, wp_laser, false)) { return; } player->message = GOTLASER; sound = sfx_sgcock; break; case SPR_ART1: if(netgame && player->artifacts & (1<<ART_FAST)) { return; } player->artifacts |= (1<<ART_FAST); player->message = GOTARTIFACT1; player->messagepic = 41; break; case SPR_ART2: if(netgame && player->artifacts & (1<<ART_DOUBLE)) { return; } player->artifacts |= (1<<ART_DOUBLE); player->message = GOTARTIFACT2; player->messagepic = 42; break; case SPR_ART3: if(netgame && player->artifacts & (1<<ART_TRIPLE)) { return; } player->artifacts |= (1<<ART_TRIPLE); player->message = GOTARTIFACT3; player->messagepic = 43; break; default: if(special->type != MT_FAKEITEM) { CON_Printf(YELLOW, "P_SpecialThing: Unknown gettable thing: %s\n", sprnames[special->sprite]); special->flags &= ~MF_SPECIAL; return; } break; } if(special->flags & MF_TRIGTOUCH || special->type == MT_FAKEITEM) { if(special->tid) { P_QueueSpecial(special); } } if(special->type != MT_FAKEITEM) { if(special->flags & MF_COUNTITEM) { player->itemcount++; } if(special->flags & MF_COUNTSECRET) { player->secretcount++; } P_RemoveMobj(special); player->bonuscount += BONUSADD; if(player == &players[consoleplayer]) { S_StartSound(NULL, sound); } } }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) { PARAM_ACTION_PROLOGUE; PARAM_SOUND_OPT (fullsound) { fullsound = "weapons/sawfull"; } PARAM_SOUND_OPT (hitsound) { hitsound = "weapons/sawhit"; } PARAM_INT_OPT (damage) { damage = 2; } PARAM_CLASS_OPT (pufftype, AActor) { pufftype = NULL; } PARAM_INT_OPT (flags) { flags = 0; } PARAM_FLOAT_OPT (range) { range = 0; } PARAM_ANGLE_OPT (spread_xy) { spread_xy = 2.8125; } PARAM_ANGLE_OPT (spread_z) { spread_z = 0.; } PARAM_FLOAT_OPT (lifesteal) { lifesteal = 0; } PARAM_INT_OPT (lifestealmax) { lifestealmax = 0; } PARAM_CLASS_OPT (armorbonustype, ABasicArmorBonus) { armorbonustype = NULL; } DAngle angle; DAngle slope; player_t *player; FTranslatedLineTarget t; int actualdamage; if (NULL == (player = self->player)) { return 0; } if (pufftype == NULL) { pufftype = PClass::FindActor(NAME_BulletPuff); } if (damage == 0) { damage = 2; } if (!(flags & SF_NORANDOM)) { damage *= (pr_saw()%10+1); } if (range == 0) { range = SAWRANGE; } angle = self->Angles.Yaw + spread_xy * (pr_saw.Random2() / 255.); slope = P_AimLineAttack (self, angle, range, &t) + spread_z * (pr_saw.Random2() / 255.); AWeapon *weapon = self->player->ReadyWeapon; if ((weapon != NULL) && !(flags & SF_NOUSEAMMO) && !(!t.linetarget && (flags & SF_NOUSEAMMOMISS)) && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_WEAPON()) { if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } P_LineAttack (self, angle, range, slope, damage, NAME_Melee, pufftype, false, &t, &actualdamage); if (!t.linetarget) { if ((flags & SF_RANDOMLIGHTMISS) && (pr_saw() > 64)) { player->extralight = !player->extralight; } S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM); return 0; } if (flags & SF_RANDOMLIGHTHIT) { int randVal = pr_saw(); if (randVal < 64) { player->extralight = 0; } else if (randVal < 160) { player->extralight = 1; } else { player->extralight = 2; } } if (lifesteal && !(t.linetarget->flags5 & MF5_DONTDRAIN)) { if (flags & SF_STEALARMOR) { if (armorbonustype == NULL) { armorbonustype = dyn_cast<ABasicArmorBonus::MetaClass>(PClass::FindClass("ArmorBonus")); } if (armorbonustype != NULL) { assert(armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus))); ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn(armorbonustype)); armorbonus->SaveAmount = int(armorbonus->SaveAmount * actualdamage * lifesteal); armorbonus->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax; armorbonus->flags |= MF_DROPPED; armorbonus->ClearCounters(); if (!armorbonus->CallTryPickup (self)) { armorbonus->Destroy (); } } } else { P_GiveBody (self, int(actualdamage * lifesteal), lifestealmax); } } S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM); // turn to face target if (!(flags & SF_NOTURN)) { DAngle anglediff = deltaangle(self->Angles.Yaw, t.angleFromSource); if (anglediff < 0.0) { if (anglediff < -4.5) self->Angles.Yaw = angle + 90.0 / 21; else self->Angles.Yaw -= 4.5; } else { if (anglediff > 4.5) self->Angles.Yaw = angle - 90.0 / 21; else self->Angles.Yaw += 4.5; } } if (!(flags & SF_NOPULLIN)) self->flags |= MF_JUSTATTACKED; return 0; }