bool AWeaponGiver::TryPickup(AActor *&toucher) { FDropItem *di = GetDropItems(); AWeapon *weap; if (di != NULL) { const PClass *ti = PClass::FindClass(di->Name); if (ti->IsDescendantOf(RUNTIME_CLASS(AWeapon))) { if (master == NULL) { master = weap = static_cast<AWeapon*>(Spawn(di->Name, 0, 0, 0, NO_REPLACE)); if (weap != NULL) { weap->ItemFlags &= ~IF_ALWAYSPICKUP; // use the flag of this item only. if (AmmoGive1 >= 0) weap->AmmoGive1 = AmmoGive1; if (AmmoGive2 >= 0) weap->AmmoGive2 = AmmoGive2; weap->BecomeItem(); } else return false; } weap = barrier_cast<AWeapon*>(master); bool res = weap->CallTryPickup(toucher); if (res) GoAwayAndDie(); return res; } } return false; }
bool AAmmoFillup::TryPickup (AActor *&toucher) { PClassActor *clip = PClass::FindActor(NAME_ClipOfBullets); if (clip != NULL) { AInventory *item = toucher->FindInventory(clip); if (item == NULL) { item = toucher->GiveInventoryType (clip); if (item != NULL) { item->Amount = 50; } } else if (item->Amount < 50) { item->Amount = 50; } else { return false; } GoAwayAndDie (); } return true; }
bool ARaiseAlarm::TryPickup (AActor *&toucher) { P_NoiseAlert (toucher, toucher); CALL_ACTION(A_WakeOracleSpectre, toucher); GoAwayAndDie (); return true; }
bool AClericWeaponPiece::TryPickup (AActor *&toucher) { if (!toucher->IsKindOf (PClass::FindClass(NAME_MagePlayer)) && !toucher->IsKindOf (PClass::FindClass(NAME_FighterPlayer))) { return Super::TryPickup(toucher); } else { // Wrong class, but try to pick up for ammo if (ShouldStay()) { // Can't pick up weapons for other classes in coop netplay return false; } AWeapon * Defaults=(AWeapon*)GetDefaultByType(WeaponClass); bool gaveSome = !!(toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1) + toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2)); if (gaveSome) { GoAwayAndDie (); } return gaveSome; } }
bool AUpgradeAccuracy::TryPickup (AActor *&toucher) { if (toucher->player == NULL || toucher->player->mo->accuracy >= 100) return false; toucher->player->mo->accuracy += 10; GoAwayAndDie (); return true; }
AInventory *ASigil::CreateCopy (AActor *other) { ASigil *copy = Spawn<ASigil> (); copy->Amount = Amount; copy->MaxAmount = MaxAmount; copy->NumPieces = NumPieces; copy->Icon = Icon; GoAwayAndDie (); return copy; }
bool ASlideshowStarter::TryPickup (AActor *&toucher) { gameaction = ga_slideshow; if (level.levelnum == 10) { toucher->GiveInventoryType (QuestItemClasses[16]); } GoAwayAndDie (); return true; }
AInventory *ACoin::CreateCopy (AActor *other) { if (GetClass() == RUNTIME_CLASS(ACoin)) { return Super::CreateCopy (other); } AInventory *copy = Spawn<ACoin> (0,0,0, NO_REPLACE); copy->Amount = Amount; copy->BecomeItem (); GoAwayAndDie (); return copy; }
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; }
bool ACustomInventory::TryPickup (AActor *&toucher) { FState *pickupstate = FindState(NAME_Pickup); bool useok = CallStateChain (toucher, pickupstate); if ((useok || pickupstate == NULL) && FindState(NAME_Use) != NULL) { useok = Super::TryPickup (toucher); } else if (useok) { GoAwayAndDie(); } return useok; }
bool AWeapon::TryPickupRestricted (AActor *&toucher) { // Wrong class, but try to pick up for ammo if (ShouldStay()) { // Can't pick up weapons for other classes in coop netplay return false; } bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1)); gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2)); if (gaveSome) { GoAwayAndDie (); } return gaveSome; }
bool AInventory::CallTryPickup (AActor *toucher, AActor **toucher_return) { TObjPtr<AInventory> Invstack = Inventory; // A pointer of the inventories item stack. // unmorphed versions of a currently morphed actor cannot pick up anything. if (toucher->flags & MF_UNMORPHED) return false; bool res; if (CanPickup(toucher)) res = TryPickup(toucher); else if (!(ItemFlags & IF_RESTRICTABSOLUTELY)) res = TryPickupRestricted(toucher); // let an item decide for itself how it will handle this else return false; // Morph items can change the toucher so we need an option to return this info. if (toucher_return != NULL) *toucher_return = toucher; if (!res && (ItemFlags & IF_ALWAYSPICKUP) && !ShouldStay()) { res = true; GoAwayAndDie(); } if (res) { GiveQuest(toucher); // Transfer all inventory accross that the old object had, if requested. if ((ItemFlags & IF_TRANSFER)) { while (Invstack) { AInventory* titem = Invstack; Invstack = titem->Inventory; if (titem->Owner == this) { if (!titem->CallTryPickup(toucher)) // The object no longer can exist { titem->Destroy(); } } } } } return res; }
bool AWeaponGiver::TryPickup(AActor *&toucher) { DDropItem *di = GetDropItems(); AWeapon *weap; if (di != NULL) { PClassWeapon *ti = dyn_cast<PClassWeapon>(PClass::FindClass(di->Name)); if (ti != NULL) { if (master == NULL) { master = weap = static_cast<AWeapon*>(Spawn(di->Name)); if (weap != NULL) { weap->ItemFlags &= ~IF_ALWAYSPICKUP; // use the flag of this item only. weap->flags = (weap->flags & ~MF_DROPPED) | (this->flags & MF_DROPPED); // If our ammo gives are non-negative, transfer them to the real weapon. if (AmmoGive1 >= 0) weap->AmmoGive1 = AmmoGive1; if (AmmoGive2 >= 0) weap->AmmoGive2 = AmmoGive2; // If DropAmmoFactor is non-negative, modify the given ammo amounts. if (DropAmmoFactor > 0) { weap->AmmoGive1 = int(weap->AmmoGive1 * DropAmmoFactor); weap->AmmoGive2 = int(weap->AmmoGive2 * DropAmmoFactor); } weap->BecomeItem(); } else return false; } weap = barrier_cast<AWeapon*>(master); bool res = weap->CallTryPickup(toucher); if (res) { GoAwayAndDie(); master = NULL; } return res; } } return false; }
bool AWeaponPiece::TryPickupRestricted (AActor *&toucher) { // Wrong class, but try to pick up for ammo if (ShouldStay()) { // Can't pick up weapons for other classes in coop netplay return false; } AWeapon * Defaults=(AWeapon*)GetDefaultByType(WeaponClass); bool gaveSome = !!(toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1) + toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2)); if (gaveSome) { GoAwayAndDie (); } return gaveSome; }
END_DEFAULTS bool AFighterWeapon::TryPickup (AActor *toucher) { // The Doom and Hexen players are not excluded from pickup in case // somebody wants to use these weapons with either of those games. if (toucher->IsKindOf (RUNTIME_CLASS(AClericPlayer)) || toucher->IsKindOf (RUNTIME_CLASS(AMagePlayer))) { // Wrong class, but try to pick up for mana if (ShouldStay()) { // Can't pick up weapons for other classes in coop netplay return false; } bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1)); gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2)); if (gaveSome) { GoAwayAndDie (); } return gaveSome; } return Super::TryPickup (toucher); }
bool AWeaponPiece::TryPickup (AActor *&toucher) { AInventory * inv; AWeaponHolder * hold=NULL; bool shouldStay = PrivateShouldStay (); int gaveAmmo; AWeapon * Defaults=(AWeapon*)GetDefaultByType(WeaponClass); FullWeapon=NULL; for(inv=toucher->Inventory;inv;inv=inv->Inventory) { if (inv->IsKindOf(RUNTIME_CLASS(AWeaponHolder))) { hold=static_cast<AWeaponHolder*>(inv); if (hold->PieceWeapon==WeaponClass) break; hold=NULL; } } if (!hold) { hold=static_cast<AWeaponHolder*>(Spawn(RUNTIME_CLASS(AWeaponHolder), 0, 0, 0, NO_REPLACE)); hold->BecomeItem(); hold->AttachToOwner(toucher); hold->PieceMask=0; hold->PieceWeapon=WeaponClass; } if (shouldStay) { // Cooperative net-game if (hold->PieceMask & PieceValue) { // Already has the piece return false; } toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1); toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2); } else { // Deathmatch or singleplayer game gaveAmmo = toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1) + toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2); if (hold->PieceMask & PieceValue) { // Already has the piece, check if mana needed if (!gaveAmmo) return false; GoAwayAndDie(); return true; } } hold->PieceMask |= PieceValue; // Check if weapon assembled if (hold->PieceMask== (1<<Defaults->health)-1) { if (!toucher->FindInventory (WeaponClass)) { FullWeapon= static_cast<AWeapon*>(Spawn(WeaponClass, 0, 0, 0, NO_REPLACE)); // [BB] The collection of weapon pieces is handled on the server, so we // need to tell the client that the weapon is completed. if (( NETWORK_GetState( ) == NETSTATE_SERVER ) && ( toucher ) && ( toucher->player )) SERVERCOMMANDS_GiveInventory( ULONG( toucher->player - players ), FullWeapon ); // The weapon itself should not give more ammo to the player! FullWeapon->AmmoGive1=0; FullWeapon->AmmoGive2=0; FullWeapon->AttachToOwner(toucher); FullWeapon->AmmoGive1=Defaults->AmmoGive1; FullWeapon->AmmoGive2=Defaults->AmmoGive2; } } // [Dusk] Update the ammo counts to the client if (( NETWORK_GetState( ) == NETSTATE_SERVER ) && ( toucher ) && ( toucher->player )) SERVERCOMMANDS_SyncPlayerAmmoAmount( ULONG( toucher->player - players )); GoAwayAndDie(); return true; }
bool AWeaponPiece::TryPickup (AActor *&toucher) { AInventory * inv; AWeaponHolder * hold=NULL; bool shouldStay = PrivateShouldStay (); int gaveAmmo; AWeapon * Defaults=(AWeapon*)GetDefaultByType(WeaponClass); FullWeapon=NULL; for(inv=toucher->Inventory;inv;inv=inv->Inventory) { if (inv->IsKindOf(RUNTIME_CLASS(AWeaponHolder))) { hold=static_cast<AWeaponHolder*>(inv); if (hold->PieceWeapon==WeaponClass) break; hold=NULL; } } if (!hold) { hold=static_cast<AWeaponHolder*>(Spawn(RUNTIME_CLASS(AWeaponHolder), 0, 0, 0, NO_REPLACE)); hold->BecomeItem(); hold->AttachToOwner(toucher); hold->PieceMask=0; hold->PieceWeapon=WeaponClass; } if (shouldStay) { // Cooperative net-game if (hold->PieceMask & PieceValue) { // Already has the piece return false; } toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1); toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2); } else { // Deathmatch or singleplayer game gaveAmmo = toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1) + toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2); if (hold->PieceMask & PieceValue) { // Already has the piece, check if mana needed if (!gaveAmmo) return false; GoAwayAndDie(); return true; } } hold->PieceMask |= PieceValue; // Check if weapon assembled if (hold->PieceMask== (1<<Defaults->health)-1) { if (!toucher->FindInventory (WeaponClass)) { FullWeapon= static_cast<AWeapon*>(Spawn(WeaponClass, 0, 0, 0, NO_REPLACE)); // The weapon itself should not give more ammo to the player! FullWeapon->AmmoGive1=0; FullWeapon->AmmoGive2=0; FullWeapon->AttachToOwner(toucher); FullWeapon->AmmoGive1=Defaults->AmmoGive1; FullWeapon->AmmoGive2=Defaults->AmmoGive2; } } GoAwayAndDie(); return true; }
bool AInventory::TryPickup (AActor *&toucher) { AActor *newtoucher = toucher; // in case changed by the powerup // If HandlePickup() returns true, it will set the IF_PICKUPGOOD flag // to indicate that this item has been picked up. If the item cannot be // picked up, then it leaves the flag cleared. ItemFlags &= ~IF_PICKUPGOOD; if (toucher->Inventory != NULL && toucher->Inventory->HandlePickup (this)) { // Let something else the player is holding intercept the pickup. if (!(ItemFlags & IF_PICKUPGOOD)) { return false; } ItemFlags &= ~IF_PICKUPGOOD; GoAwayAndDie (); } else if (MaxAmount == 0 && !IsKindOf(RUNTIME_CLASS(AAmmo))) { // Special case: If an item's MaxAmount is 0, you can still pick it // up if it is autoactivate-able. if (!(ItemFlags & IF_AUTOACTIVATE)) { return false; } // The item is placed in the inventory just long enough to be used. toucher->AddInventory (this); bool usegood = Use (true); toucher->RemoveInventory (this); if (usegood) { GoAwayAndDie (); } else { return false; } } else { // Add the item to the inventory. It is not already there, or HandlePickup // would have already taken care of it. AInventory *copy = CreateCopy (toucher); if (copy == NULL) { return false; } // Some powerups cannot activate absolutely, for // example, PowerMorph; fail the pickup if so. if (copy->ItemFlags & IF_INITEFFECTFAILED) { if (copy != this) copy->Destroy(); else ItemFlags &= ~IF_INITEFFECTFAILED; return false; } // Handle owner-changing powerups if (copy->ItemFlags & IF_CREATECOPYMOVED) { newtoucher = copy->Owner; copy->Owner = NULL; copy->ItemFlags &= ~IF_CREATECOPYMOVED; } // Continue onwards with the rest copy->AttachToOwner (newtoucher); if (ItemFlags & IF_AUTOACTIVATE) { if (copy->Use (true)) { if (--copy->Amount <= 0) { copy->flags &= ~MF_SPECIAL; copy->SetState (copy->FindState("HoldAndDestroy")); } } } } return true; }
bool AOpenDoor224::TryPickup (AActor *&toucher) { EV_DoDoor (DDoor::doorOpen, NULL, toucher, 224, 2., 0, 0, 0); GoAwayAndDie (); return true; }
bool ACloseDoor222::TryPickup (AActor *&toucher) { EV_DoDoor (DDoor::doorClose, NULL, toucher, 222, 2., 0, 0, 0); GoAwayAndDie (); return true; }
bool AScoreItem::TryPickup (AActor *&toucher) { toucher->Score += Amount; GoAwayAndDie(); return true; }
bool AMapRevealer::TryPickup (AActor *&toucher) { level.flags2 |= LEVEL2_ALLMAP; GoAwayAndDie (); return true; }