- scriptified the weapon piece functions.

- fixed: ClearInventory did not process depleted items properly.
- changed HexenArmor from UNDROPPABLE to UNTOSSABLE because this allowed to remove some special handling in ClearInventory. The only other place which checks this flag also checks UNTOSSABLE.
This commit is contained in:
Christoph Oelckers 2017-01-18 17:26:12 +01:00
commit 30a8541a15
12 changed files with 290 additions and 313 deletions

View file

@ -3183,7 +3183,7 @@ bool ADehackedPickup::ShouldRespawn ()
void ADehackedPickup::PlayPickupSound (AActor *toucher)
{
if (RealPickup != nullptr)
RealPickup->PlayPickupSound (toucher);
RealPickup->CallPlayPickupSound (toucher);
}
void ADehackedPickup::DoPickupSpecial (AActor *toucher)

View file

@ -79,71 +79,6 @@ void PClassInventory::Finalize(FStateDefinitions &statedef)
((AActor*)Defaults)->flags |= MF_SPECIAL;
}
//---------------------------------------------------------------------------
//
// PROC A_RestoreSpecialThing1
//
// Make a special thing visible again.
//
//---------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AInventory, A_RestoreSpecialThing1)
{
PARAM_SELF_PROLOGUE(AInventory);
self->renderflags &= ~RF_INVISIBLE;
if (self->DoRespawn ())
{
S_Sound (self, CHAN_VOICE, "misc/spawn", 1, ATTN_IDLE);
}
return 0;
}
//---------------------------------------------------------------------------
//
// PROC A_RestoreSpecialThing2
//
//---------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AInventory, A_RestoreSpecialThing2)
{
PARAM_SELF_PROLOGUE(AInventory);
self->flags |= MF_SPECIAL;
if (!(self->GetDefault()->flags & MF_NOGRAVITY))
{
self->flags &= ~MF_NOGRAVITY;
}
self->SetState (self->SpawnState);
return 0;
}
//---------------------------------------------------------------------------
//
// PROC A_RestoreSpecialDoomThing
//
//---------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AInventory, A_RestoreSpecialDoomThing)
{
PARAM_SELF_PROLOGUE(AInventory);
self->renderflags &= ~RF_INVISIBLE;
self->flags |= MF_SPECIAL;
if (!(self->GetDefault()->flags & MF_NOGRAVITY))
{
self->flags &= ~MF_NOGRAVITY;
}
if (self->DoRespawn ())
{
self->SetState (self->SpawnState);
S_Sound (self, CHAN_VOICE, "misc/spawn", 1, ATTN_IDLE);
Spawn ("ItemFog", self->Pos(), ALLOW_REPLACE);
}
return 0;
}
int AInventory::StaticLastMessageTic;
FString AInventory::StaticLastMessage;
@ -907,7 +842,7 @@ void AInventory::Touch (AActor *toucher)
// real player to make noise.
if (player != NULL)
{
PlayPickupSound (player->mo);
CallPlayPickupSound (player->mo);
if (!(ItemFlags & IF_NOSCREENFLASH))
{
player->bonuscount = BONUSADD;
@ -915,7 +850,7 @@ void AInventory::Touch (AActor *toucher)
}
else
{
PlayPickupSound (toucher);
CallPlayPickupSound (toucher);
}
}
@ -1272,6 +1207,11 @@ bool AInventory::DoRespawn ()
return true;
}
DEFINE_ACTION_FUNCTION(AInventory, DoRespawn)
{
PARAM_SELF_PROLOGUE(AInventory);
ACTION_RETURN_BOOL(self->DoRespawn());
}
//===========================================================================
//

View file

@ -78,181 +78,6 @@ void AWeaponPiece::Serialize(FSerializer &arc)
("piecevalue", PieceValue, def->PieceValue);
}
//==========================================================================
//
// TryPickupWeaponPiece
//
//==========================================================================
bool AWeaponPiece::TryPickupRestricted (AActor *&toucher)
{
// Wrong class, but try to pick up for ammo
if (CallShouldStay())
{ // 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;
}
//==========================================================================
//
// TryPickupWeaponPiece
//
//==========================================================================
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)));
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));
// 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 AWeaponPiece::ShouldStay ()
{
return PrivateShouldStay ();
}
//===========================================================================
//
//
//
//===========================================================================
bool AWeaponPiece::PrivateShouldStay ()
{
// We want a weapon piece to behave like a weapon, so follow the exact
// same logic as weapons when deciding whether or not to stay.
if (((multiplayer &&
(!deathmatch && !alwaysapplydmflags)) || (dmflags & DF_WEAPONS_STAY)) &&
!(flags&MF_DROPPED))
{
return true;
}
return false;
}
//===========================================================================
//
// PickupMessage
//
// Returns the message to print when this actor is picked up.
//
//===========================================================================
FString AWeaponPiece::PickupMessage ()
{
if (FullWeapon)
{
return FullWeapon->PickupMessage();
}
else
{
return Super::PickupMessage();
}
}
//===========================================================================
//
// DoPlayPickupSound
//
// Plays a sound when this actor is picked up.
//
//===========================================================================
void AWeaponPiece::PlayPickupSound (AActor *toucher)
{
if (FullWeapon)
{
FullWeapon->PlayPickupSound(toucher);
}
else
{
Super::PlayPickupSound(toucher);
}
}
DEFINE_FIELD(AWeaponPiece, PieceValue);
DEFINE_FIELD(AWeaponPiece, WeaponClass);
DEFINE_FIELD(AWeaponPiece, FullWeapon);

View file

@ -11,11 +11,6 @@ protected:
public:
virtual void Serialize(FSerializer &arc) override;
virtual bool TryPickup (AActor *&toucher) override;
virtual bool TryPickupRestricted (AActor *&toucher) override;
virtual bool ShouldStay () override;
virtual FString PickupMessage () override;
virtual void PlayPickupSound (AActor *toucher) override;
int PieceValue;
PClassActor *WeaponClass;

View file

@ -3691,3 +3691,5 @@ SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc)
sc.MustGetToken('}');
return NULL;
}

View file

@ -1211,12 +1211,7 @@ void AActor::ClearInventory()
if (!(inv->ItemFlags & IF_UNDROPPABLE))
{
inv->DepleteOrDestroy();
}
else if (inv->GetClass() == RUNTIME_CLASS(AHexenArmor))
{
AHexenArmor *harmor = static_cast<AHexenArmor *> (inv);
harmor->Slots[3] = harmor->Slots[2] = harmor->Slots[1] = harmor->Slots[0] = 0;
invp = &inv->Inventory;
if (!(inv->ObjectFlags & OF_EuthanizeMe)) invp = &inv->Inventory; // was only depleted so advance the pointer manually.
}
else
{