- moved ammo to its own file, including the backpack.
- moved weapon declarations to their own header.
This commit is contained in:
parent
78fa076079
commit
229c55ce61
23 changed files with 836 additions and 611 deletions
|
|
@ -20,8 +20,10 @@
|
|||
#include "p_spec.h"
|
||||
#include "serializer.h"
|
||||
#include "virtual.h"
|
||||
#include "a_ammo.h"
|
||||
|
||||
static FRandom pr_restore ("RestorePos");
|
||||
EXTERN_CVAR(Bool, sv_unlimited_pickup)
|
||||
|
||||
IMPLEMENT_CLASS(PClassInventory, false, false)
|
||||
|
||||
|
|
@ -70,179 +72,6 @@ void PClassInventory::Finalize(FStateDefinitions &statedef)
|
|||
((AActor*)Defaults)->flags |= MF_SPECIAL;
|
||||
}
|
||||
|
||||
IMPLEMENT_CLASS(PClassAmmo, false, false)
|
||||
|
||||
PClassAmmo::PClassAmmo()
|
||||
{
|
||||
DropAmount = 0;
|
||||
}
|
||||
|
||||
void PClassAmmo::DeriveData(PClass *newclass)
|
||||
{
|
||||
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassAmmo)));
|
||||
Super::DeriveData(newclass);
|
||||
PClassAmmo *newc = static_cast<PClassAmmo *>(newclass);
|
||||
|
||||
newc->DropAmount = DropAmount;
|
||||
}
|
||||
|
||||
IMPLEMENT_CLASS(AAmmo, false, false)
|
||||
|
||||
DEFINE_FIELD(AAmmo, BackpackAmount)
|
||||
DEFINE_FIELD(AAmmo, BackpackMaxAmount)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AAmmo :: Serialize
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void AAmmo::Serialize(FSerializer &arc)
|
||||
{
|
||||
Super::Serialize (arc);
|
||||
auto def = (AAmmo*)GetDefault();
|
||||
arc("backpackamount", BackpackAmount, def->BackpackAmount)
|
||||
("backpackmaxamount", BackpackMaxAmount, def->BackpackMaxAmount);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AAmmo :: GetParentAmmo
|
||||
//
|
||||
// Returns the least-derived ammo type that this ammo is a descendant of.
|
||||
// That is, if this ammo is an immediate subclass of Ammo, then this ammo's
|
||||
// type is returned. If this ammo's superclass is not Ammo, then this
|
||||
// function travels up the inheritance chain until it finds a type that is
|
||||
// an immediate subclass of Ammo and returns that.
|
||||
//
|
||||
// The intent of this is that all unique ammo types will be immediate
|
||||
// subclasses of Ammo. To make different pickups with different ammo amounts,
|
||||
// you subclass the type of ammo you want a different amount for and edit
|
||||
// that.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
PClassActor *AAmmo::GetParentAmmo () const
|
||||
{
|
||||
PClass *type = GetClass();
|
||||
|
||||
while (type->ParentClass != RUNTIME_CLASS(AAmmo) && type->ParentClass != NULL)
|
||||
{
|
||||
type = type->ParentClass;
|
||||
}
|
||||
return static_cast<PClassActor *>(type);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AAmmo :: HandlePickup
|
||||
//
|
||||
//===========================================================================
|
||||
EXTERN_CVAR(Bool, sv_unlimited_pickup)
|
||||
|
||||
bool AAmmo::HandlePickup (AInventory *item)
|
||||
{
|
||||
if (GetClass() == item->GetClass() ||
|
||||
(item->IsKindOf (RUNTIME_CLASS(AAmmo)) && static_cast<AAmmo*>(item)->GetParentAmmo() == GetClass()))
|
||||
{
|
||||
if (Amount < MaxAmount || sv_unlimited_pickup)
|
||||
{
|
||||
int receiving = item->Amount;
|
||||
|
||||
if (!(item->ItemFlags & IF_IGNORESKILL))
|
||||
{ // extra ammo in baby mode and nightmare mode
|
||||
receiving = int(receiving * G_SkillProperty(SKILLP_AmmoFactor));
|
||||
}
|
||||
int oldamount = Amount;
|
||||
|
||||
if (Amount > 0 && Amount + receiving < 0)
|
||||
{
|
||||
Amount = 0x7fffffff;
|
||||
}
|
||||
else
|
||||
{
|
||||
Amount += receiving;
|
||||
}
|
||||
if (Amount > MaxAmount && !sv_unlimited_pickup)
|
||||
{
|
||||
Amount = MaxAmount;
|
||||
}
|
||||
item->ItemFlags |= IF_PICKUPGOOD;
|
||||
|
||||
// If the player previously had this ammo but ran out, possibly switch
|
||||
// to a weapon that uses it, but only if the player doesn't already
|
||||
// have a weapon pending.
|
||||
|
||||
assert (Owner != NULL);
|
||||
|
||||
if (oldamount == 0 && Owner != NULL && Owner->player != NULL)
|
||||
{
|
||||
barrier_cast<APlayerPawn *>(Owner)->CheckWeaponSwitch(GetClass());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AAmmo :: CreateCopy
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
AInventory *AAmmo::CreateCopy (AActor *other)
|
||||
{
|
||||
AInventory *copy;
|
||||
int amount = Amount;
|
||||
|
||||
// extra ammo in baby mode and nightmare mode
|
||||
if (!(ItemFlags&IF_IGNORESKILL))
|
||||
{
|
||||
amount = int(amount * G_SkillProperty(SKILLP_AmmoFactor));
|
||||
}
|
||||
|
||||
if (GetClass()->ParentClass != RUNTIME_CLASS(AAmmo) && GetClass() != RUNTIME_CLASS(AAmmo))
|
||||
{
|
||||
PClassActor *type = GetParentAmmo();
|
||||
if (!GoAway ())
|
||||
{
|
||||
Destroy ();
|
||||
}
|
||||
|
||||
copy = static_cast<AInventory *>(Spawn (type));
|
||||
copy->Amount = amount;
|
||||
copy->BecomeItem ();
|
||||
}
|
||||
else
|
||||
{
|
||||
copy = Super::CreateCopy (other);
|
||||
copy->Amount = amount;
|
||||
}
|
||||
if (copy->Amount > copy->MaxAmount)
|
||||
{ // Don't pick up more ammo than you're supposed to be able to carry.
|
||||
copy->Amount = copy->MaxAmount;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AAmmo :: CreateTossable
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
AInventory *AAmmo::CreateTossable()
|
||||
{
|
||||
AInventory *copy = Super::CreateTossable();
|
||||
if (copy != NULL)
|
||||
{ // Do not increase ammo by dropping it and picking it back up at
|
||||
// certain skill levels.
|
||||
copy->ItemFlags |= IF_IGNORESKILL;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// FUNC P_GiveBody
|
||||
|
|
@ -2068,174 +1897,6 @@ void AHealthPickup::Serialize(FSerializer &arc)
|
|||
arc("autousemode", autousemode, def->autousemode);
|
||||
}
|
||||
|
||||
// Backpack -----------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLASS(ABackpackItem, false, false)
|
||||
|
||||
DEFINE_FIELD(ABackpackItem, bDepleted)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ABackpackItem :: Serialize
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void ABackpackItem::Serialize(FSerializer &arc)
|
||||
{
|
||||
Super::Serialize (arc);
|
||||
auto def = (ABackpackItem*)GetDefault();
|
||||
arc("bdepleted", bDepleted, def->bDepleted);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ABackpackItem :: CreateCopy
|
||||
//
|
||||
// A backpack is being added to a player who doesn't yet have one. Give them
|
||||
// every kind of ammo, and increase their max amounts.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
AInventory *ABackpackItem::CreateCopy (AActor *other)
|
||||
{
|
||||
// Find every unique type of ammo. Give it to the player if
|
||||
// he doesn't have it already, and double its maximum capacity.
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
PClass *type = PClassActor::AllActorClasses[i];
|
||||
|
||||
if (type->ParentClass == RUNTIME_CLASS(AAmmo))
|
||||
{
|
||||
PClassActor *atype = static_cast<PClassActor *>(type);
|
||||
AAmmo *ammo = static_cast<AAmmo *>(other->FindInventory(atype));
|
||||
int amount = static_cast<AAmmo *>(GetDefaultByType(type))->BackpackAmount;
|
||||
// extra ammo in baby mode and nightmare mode
|
||||
if (!(ItemFlags&IF_IGNORESKILL))
|
||||
{
|
||||
amount = int(amount * G_SkillProperty(SKILLP_AmmoFactor));
|
||||
}
|
||||
if (amount < 0) amount = 0;
|
||||
if (ammo == NULL)
|
||||
{ // The player did not have the ammo. Add it.
|
||||
ammo = static_cast<AAmmo *>(Spawn(atype));
|
||||
ammo->Amount = bDepleted ? 0 : amount;
|
||||
if (ammo->BackpackMaxAmount > ammo->MaxAmount)
|
||||
{
|
||||
ammo->MaxAmount = ammo->BackpackMaxAmount;
|
||||
}
|
||||
if (ammo->Amount > ammo->MaxAmount)
|
||||
{
|
||||
ammo->Amount = ammo->MaxAmount;
|
||||
}
|
||||
ammo->AttachToOwner (other);
|
||||
}
|
||||
else
|
||||
{ // The player had the ammo. Give some more.
|
||||
if (ammo->MaxAmount < ammo->BackpackMaxAmount)
|
||||
{
|
||||
ammo->MaxAmount = ammo->BackpackMaxAmount;
|
||||
}
|
||||
if (!bDepleted && ammo->Amount < ammo->MaxAmount)
|
||||
{
|
||||
ammo->Amount += amount;
|
||||
if (ammo->Amount > ammo->MaxAmount)
|
||||
{
|
||||
ammo->Amount = ammo->MaxAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Super::CreateCopy (other);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ABackpackItem :: HandlePickup
|
||||
//
|
||||
// When the player picks up another backpack, just give them more ammo.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool ABackpackItem::HandlePickup (AInventory *item)
|
||||
{
|
||||
// Since you already have a backpack, that means you already have every
|
||||
// kind of ammo in your inventory, so we don't need to look at the
|
||||
// entire PClass list to discover what kinds of ammo exist, and we don't
|
||||
// have to alter the MaxAmount either.
|
||||
if (item->IsKindOf (RUNTIME_CLASS(ABackpackItem)))
|
||||
{
|
||||
for (AInventory *probe = Owner->Inventory; probe != NULL; probe = probe->Inventory)
|
||||
{
|
||||
if (probe->GetClass()->ParentClass == RUNTIME_CLASS(AAmmo))
|
||||
{
|
||||
if (probe->Amount < probe->MaxAmount || sv_unlimited_pickup)
|
||||
{
|
||||
int amount = static_cast<AAmmo*>(probe->GetDefault())->BackpackAmount;
|
||||
// extra ammo in baby mode and nightmare mode
|
||||
if (!(item->ItemFlags&IF_IGNORESKILL))
|
||||
{
|
||||
amount = int(amount * G_SkillProperty(SKILLP_AmmoFactor));
|
||||
}
|
||||
probe->Amount += amount;
|
||||
if (probe->Amount > probe->MaxAmount && !sv_unlimited_pickup)
|
||||
{
|
||||
probe->Amount = probe->MaxAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// The pickup always succeeds, even if you didn't get anything
|
||||
item->ItemFlags |= IF_PICKUPGOOD;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ABackpackItem :: CreateTossable
|
||||
//
|
||||
// The tossed backpack must not give out any more ammo, otherwise a player
|
||||
// could cheat by dropping their backpack and picking it up for more ammo.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
AInventory *ABackpackItem::CreateTossable ()
|
||||
{
|
||||
ABackpackItem *pack = static_cast<ABackpackItem *>(Super::CreateTossable());
|
||||
if (pack != NULL)
|
||||
{
|
||||
pack->bDepleted = true;
|
||||
}
|
||||
return pack;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ABackpackItem :: DetachFromOwner
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void ABackpackItem::DetachFromOwner ()
|
||||
{
|
||||
// When removing a backpack, drop the player's ammo maximums to normal
|
||||
AInventory *item;
|
||||
|
||||
for (item = Owner->Inventory; item != NULL; item = item->Inventory)
|
||||
{
|
||||
if (item->GetClass()->ParentClass == RUNTIME_CLASS(AAmmo) &&
|
||||
item->MaxAmount == static_cast<AAmmo*>(item)->BackpackMaxAmount)
|
||||
{
|
||||
item->MaxAmount = static_cast<AInventory*>(item->GetDefault())->MaxAmount;
|
||||
if (item->Amount > item->MaxAmount)
|
||||
{
|
||||
item->Amount = item->MaxAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// ABackpack
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue