mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-13 07:57:58 +00:00
- 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
|
@ -1107,6 +1107,7 @@ set (PCH_SOURCES
|
||||||
w_wad.cpp
|
w_wad.cpp
|
||||||
wi_stuff.cpp
|
wi_stuff.cpp
|
||||||
zstrformat.cpp
|
zstrformat.cpp
|
||||||
|
g_inventory/a_ammo.cpp
|
||||||
g_inventory/a_armor.cpp
|
g_inventory/a_armor.cpp
|
||||||
g_inventory/a_artifacts.cpp
|
g_inventory/a_artifacts.cpp
|
||||||
g_inventory/a_keys.cpp
|
g_inventory/a_keys.cpp
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "d_event.h"
|
#include "d_event.h"
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
|
|
||||||
static FRandom pr_botmove ("BotMove");
|
static FRandom pr_botmove ("BotMove");
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "vmbuilder.h"
|
#include "vmbuilder.h"
|
||||||
#include "a_armor.h"
|
#include "a_armor.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
|
|
||||||
// [SO] Just the way Randy said to do it :)
|
// [SO] Just the way Randy said to do it :)
|
||||||
// [RH] Made this CVAR_SERVERINFO
|
// [RH] Made this CVAR_SERVERINFO
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
|
|
||||||
#include "a_artifacts.h"
|
#include "a_artifacts.h"
|
||||||
|
#include "a_weapons.h"
|
||||||
|
|
||||||
// The player data structure depends on a number
|
// The player data structure depends on a number
|
||||||
// of other structs: items (internal inventory),
|
// of other structs: items (internal inventory),
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "p_spec.h"
|
#include "p_spec.h"
|
||||||
#include "r_utility.h"
|
#include "r_utility.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
#include "math/cmath.h"
|
#include "math/cmath.h"
|
||||||
|
|
||||||
static FRandom pr_script("FScript");
|
static FRandom pr_script("FScript");
|
||||||
|
|
381
src/g_inventory/a_ammo.cpp
Normal file
381
src/g_inventory/a_ammo.cpp
Normal file
|
@ -0,0 +1,381 @@
|
||||||
|
/*
|
||||||
|
** a_ammo.cpp
|
||||||
|
** Implements ammo and backpack items.
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2000-2016 Randy Heit
|
||||||
|
** Copyright 2006-2016 Cheistoph Oelckers
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "c_dispatch.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "serializer.h"
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
47
src/g_inventory/a_ammo.h
Normal file
47
src/g_inventory/a_ammo.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#pragma once
|
||||||
|
#include "a_pickups.h"
|
||||||
|
|
||||||
|
// Ammo: Something a weapon needs to operate
|
||||||
|
class PClassAmmo : public PClassInventory
|
||||||
|
{
|
||||||
|
DECLARE_CLASS(PClassAmmo, PClassInventory)
|
||||||
|
protected:
|
||||||
|
virtual void DeriveData(PClass *newclass);
|
||||||
|
public:
|
||||||
|
PClassAmmo();
|
||||||
|
|
||||||
|
int DropAmount; // Specifies the amount for a dropped ammo item.
|
||||||
|
};
|
||||||
|
|
||||||
|
class AAmmo : public AInventory
|
||||||
|
{
|
||||||
|
DECLARE_CLASS_WITH_META(AAmmo, AInventory, PClassAmmo)
|
||||||
|
public:
|
||||||
|
|
||||||
|
void Serialize(FSerializer &arc);
|
||||||
|
AInventory *CreateCopy (AActor *other);
|
||||||
|
bool HandlePickup (AInventory *item);
|
||||||
|
PClassActor *GetParentAmmo () const;
|
||||||
|
AInventory *CreateTossable ();
|
||||||
|
|
||||||
|
int BackpackAmount, BackpackMaxAmount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// A backpack gives you one clip of each ammo and doubles your
|
||||||
|
// normal maximum ammo amounts.
|
||||||
|
class ABackpackItem : public AInventory
|
||||||
|
{
|
||||||
|
DECLARE_CLASS (ABackpackItem, AInventory)
|
||||||
|
public:
|
||||||
|
|
||||||
|
void Serialize(FSerializer &arc);
|
||||||
|
bool HandlePickup (AInventory *item);
|
||||||
|
AInventory *CreateCopy (AActor *other);
|
||||||
|
AInventory *CreateTossable ();
|
||||||
|
void DetachFromOwner ();
|
||||||
|
|
||||||
|
bool bDepleted;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,10 @@
|
||||||
#include "p_spec.h"
|
#include "p_spec.h"
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
#include "virtual.h"
|
#include "virtual.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
|
|
||||||
static FRandom pr_restore ("RestorePos");
|
static FRandom pr_restore ("RestorePos");
|
||||||
|
EXTERN_CVAR(Bool, sv_unlimited_pickup)
|
||||||
|
|
||||||
IMPLEMENT_CLASS(PClassInventory, false, false)
|
IMPLEMENT_CLASS(PClassInventory, false, false)
|
||||||
|
|
||||||
|
@ -70,179 +72,6 @@ void PClassInventory::Finalize(FStateDefinitions &statedef)
|
||||||
((AActor*)Defaults)->flags |= MF_SPECIAL;
|
((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
|
// FUNC P_GiveBody
|
||||||
|
@ -2068,174 +1897,6 @@ void AHealthPickup::Serialize(FSerializer &arc)
|
||||||
arc("autousemode", autousemode, def->autousemode);
|
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
|
// ABackpack
|
||||||
|
|
|
@ -9,92 +9,9 @@
|
||||||
|
|
||||||
class player_t;
|
class player_t;
|
||||||
class FConfigFile;
|
class FConfigFile;
|
||||||
class AWeapon;
|
|
||||||
class PClassWeapon;
|
|
||||||
class PClassPlayerPawn;
|
class PClassPlayerPawn;
|
||||||
struct visstyle_t;
|
struct visstyle_t;
|
||||||
|
|
||||||
class FWeaponSlot
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FWeaponSlot() { Clear(); }
|
|
||||||
FWeaponSlot(const FWeaponSlot &other) { Weapons = other.Weapons; }
|
|
||||||
FWeaponSlot &operator= (const FWeaponSlot &other) { Weapons = other.Weapons; return *this; }
|
|
||||||
void Clear() { Weapons.Clear(); }
|
|
||||||
bool AddWeapon (const char *type);
|
|
||||||
bool AddWeapon (PClassWeapon *type);
|
|
||||||
void AddWeaponList (const char *list, bool clear);
|
|
||||||
AWeapon *PickWeapon (player_t *player, bool checkammo = false);
|
|
||||||
int Size () const { return (int)Weapons.Size(); }
|
|
||||||
int LocateWeapon (PClassWeapon *type);
|
|
||||||
|
|
||||||
inline PClassWeapon *GetWeapon (int index) const
|
|
||||||
{
|
|
||||||
if ((unsigned)index < Weapons.Size())
|
|
||||||
{
|
|
||||||
return Weapons[index].Type;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
friend struct FWeaponSlots;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct WeaponInfo
|
|
||||||
{
|
|
||||||
PClassWeapon *Type;
|
|
||||||
int Position;
|
|
||||||
};
|
|
||||||
void SetInitialPositions();
|
|
||||||
void Sort();
|
|
||||||
TArray<WeaponInfo> Weapons;
|
|
||||||
};
|
|
||||||
// FWeaponSlots::AddDefaultWeapon return codes
|
|
||||||
enum ESlotDef
|
|
||||||
{
|
|
||||||
SLOTDEF_Exists, // Weapon was already assigned a slot
|
|
||||||
SLOTDEF_Added, // Weapon was successfully added
|
|
||||||
SLOTDEF_Full // The specifed slot was full
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FWeaponSlots
|
|
||||||
{
|
|
||||||
FWeaponSlots() { Clear(); }
|
|
||||||
FWeaponSlots(const FWeaponSlots &other);
|
|
||||||
|
|
||||||
FWeaponSlot Slots[NUM_WEAPON_SLOTS];
|
|
||||||
|
|
||||||
AWeapon *PickNextWeapon (player_t *player);
|
|
||||||
AWeapon *PickPrevWeapon (player_t *player);
|
|
||||||
|
|
||||||
void Clear ();
|
|
||||||
bool LocateWeapon (PClassWeapon *type, int *const slot, int *const index);
|
|
||||||
ESlotDef AddDefaultWeapon (int slot, PClassWeapon *type);
|
|
||||||
void AddExtraWeapons();
|
|
||||||
void SetFromGameInfo();
|
|
||||||
void SetFromPlayer(PClassPlayerPawn *type);
|
|
||||||
void StandardSetup(PClassPlayerPawn *type);
|
|
||||||
void LocalSetup(PClassActor *type);
|
|
||||||
void SendDifferences(int playernum, const FWeaponSlots &other);
|
|
||||||
int RestoreSlots (FConfigFile *config, const char *section);
|
|
||||||
void PrintSettings();
|
|
||||||
|
|
||||||
void AddSlot(int slot, PClassWeapon *type, bool feedback);
|
|
||||||
void AddSlotDefault(int slot, PClassWeapon *type, bool feedback);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
void P_PlaybackKeyConfWeapons(FWeaponSlots *slots);
|
|
||||||
void Net_WriteWeapon(PClassWeapon *type);
|
|
||||||
PClassWeapon *Net_ReadWeapon(BYTE **stream);
|
|
||||||
|
|
||||||
void P_SetupWeapons_ntohton();
|
|
||||||
void P_WriteDemoWeaponsChunk(BYTE **demo);
|
|
||||||
void P_ReadDemoWeaponsChunk(BYTE **demo);
|
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Class definitions */
|
/* Class definitions */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
@ -252,174 +169,6 @@ public:
|
||||||
bool SpecialDropAction (AActor *dropper);
|
bool SpecialDropAction (AActor *dropper);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ammo: Something a weapon needs to operate
|
|
||||||
class PClassAmmo : public PClassInventory
|
|
||||||
{
|
|
||||||
DECLARE_CLASS(PClassAmmo, PClassInventory)
|
|
||||||
protected:
|
|
||||||
virtual void DeriveData(PClass *newclass);
|
|
||||||
public:
|
|
||||||
PClassAmmo();
|
|
||||||
|
|
||||||
int DropAmount; // Specifies the amount for a dropped ammo item.
|
|
||||||
};
|
|
||||||
|
|
||||||
class AAmmo : public AInventory
|
|
||||||
{
|
|
||||||
DECLARE_CLASS_WITH_META(AAmmo, AInventory, PClassAmmo)
|
|
||||||
public:
|
|
||||||
|
|
||||||
void Serialize(FSerializer &arc);
|
|
||||||
AInventory *CreateCopy (AActor *other);
|
|
||||||
bool HandlePickup (AInventory *item);
|
|
||||||
PClassActor *GetParentAmmo () const;
|
|
||||||
AInventory *CreateTossable ();
|
|
||||||
|
|
||||||
int BackpackAmount, BackpackMaxAmount;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A weapon is just that.
|
|
||||||
class PClassWeapon : public PClassInventory
|
|
||||||
{
|
|
||||||
DECLARE_CLASS(PClassWeapon, PClassInventory);
|
|
||||||
protected:
|
|
||||||
virtual void DeriveData(PClass *newclass);
|
|
||||||
public:
|
|
||||||
PClassWeapon();
|
|
||||||
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
|
|
||||||
void Finalize(FStateDefinitions &statedef);
|
|
||||||
|
|
||||||
int SlotNumber;
|
|
||||||
int SlotPriority;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AWeapon : public AStateProvider
|
|
||||||
{
|
|
||||||
DECLARE_CLASS_WITH_META(AWeapon, AStateProvider, PClassWeapon)
|
|
||||||
HAS_OBJECT_POINTERS
|
|
||||||
public:
|
|
||||||
DWORD WeaponFlags;
|
|
||||||
PClassAmmo *AmmoType1, *AmmoType2; // Types of ammo used by this weapon
|
|
||||||
int AmmoGive1, AmmoGive2; // Amount of each ammo to get when picking up weapon
|
|
||||||
int MinAmmo1, MinAmmo2; // Minimum ammo needed to switch to this weapon
|
|
||||||
int AmmoUse1, AmmoUse2; // How much ammo to use with each shot
|
|
||||||
int Kickback;
|
|
||||||
float YAdjust; // For viewing the weapon fullscreen (visual only so no need to be a double)
|
|
||||||
FSoundIDNoInit UpSound, ReadySound; // Sounds when coming up and idle
|
|
||||||
PClassWeapon *SisterWeaponType; // Another weapon to pick up with this one
|
|
||||||
PClassActor *ProjectileType; // Projectile used by primary attack
|
|
||||||
PClassActor *AltProjectileType; // Projectile used by alternate attack
|
|
||||||
int SelectionOrder; // Lower-numbered weapons get picked first
|
|
||||||
int MinSelAmmo1, MinSelAmmo2; // Ignore in BestWeapon() if inadequate ammo
|
|
||||||
double MoveCombatDist; // Used by bots, but do they *really* need it?
|
|
||||||
int ReloadCounter; // For A_CheckForReload
|
|
||||||
int BobStyle; // [XA] Bobbing style. Defines type of bobbing (e.g. Normal, Alpha) (visual only so no need to be a double)
|
|
||||||
float BobSpeed; // [XA] Bobbing speed. Defines how quickly a weapon bobs.
|
|
||||||
float BobRangeX, BobRangeY; // [XA] Bobbing range. Defines how far a weapon bobs in either direction.
|
|
||||||
|
|
||||||
// In-inventory instance variables
|
|
||||||
TObjPtr<AAmmo> Ammo1, Ammo2;
|
|
||||||
TObjPtr<AWeapon> SisterWeapon;
|
|
||||||
float FOVScale;
|
|
||||||
int Crosshair; // 0 to use player's crosshair
|
|
||||||
bool GivenAsMorphWeapon;
|
|
||||||
|
|
||||||
bool bAltFire; // Set when this weapon's alternate fire is used.
|
|
||||||
|
|
||||||
virtual void MarkPrecacheSounds() const;
|
|
||||||
|
|
||||||
virtual void Serialize(FSerializer &arc);
|
|
||||||
virtual bool ShouldStay ();
|
|
||||||
virtual void AttachToOwner (AActor *other);
|
|
||||||
virtual bool HandlePickup (AInventory *item);
|
|
||||||
virtual AInventory *CreateCopy (AActor *other);
|
|
||||||
virtual AInventory *CreateTossable ();
|
|
||||||
virtual bool TryPickup (AActor *&toucher);
|
|
||||||
virtual bool TryPickupRestricted (AActor *&toucher);
|
|
||||||
virtual bool PickupForAmmo (AWeapon *ownedWeapon);
|
|
||||||
virtual bool Use (bool pickup);
|
|
||||||
virtual void Destroy() override;
|
|
||||||
|
|
||||||
FState *GetUpState ();
|
|
||||||
FState *GetDownState ();
|
|
||||||
FState *GetReadyState ();
|
|
||||||
FState *GetAtkState (bool hold);
|
|
||||||
FState *GetAltAtkState (bool hold);
|
|
||||||
FState *GetStateForButtonName (FName button);
|
|
||||||
|
|
||||||
virtual void PostMorphWeapon ();
|
|
||||||
virtual void EndPowerup ();
|
|
||||||
void CallEndPowerup();
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
PrimaryFire,
|
|
||||||
AltFire,
|
|
||||||
EitherFire
|
|
||||||
};
|
|
||||||
bool CheckAmmo (int fireMode, bool autoSwitch, bool requireAmmo=false, int ammocount = -1);
|
|
||||||
bool DepleteAmmo (bool altFire, bool checkEnough=true, int ammouse = -1);
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
BobNormal,
|
|
||||||
BobInverse,
|
|
||||||
BobAlpha,
|
|
||||||
BobInverseAlpha,
|
|
||||||
BobSmooth,
|
|
||||||
BobInverseSmooth
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
AAmmo *AddAmmo (AActor *other, PClassActor *ammotype, int amount);
|
|
||||||
bool AddExistingAmmo (AAmmo *ammo, int amount);
|
|
||||||
AWeapon *AddWeapon (PClassWeapon *weapon);
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
WIF_NOAUTOFIRE = 0x00000001, // weapon does not autofire
|
|
||||||
WIF_READYSNDHALF = 0x00000002, // ready sound is played ~1/2 the time
|
|
||||||
WIF_DONTBOB = 0x00000004, // don't bob the weapon
|
|
||||||
WIF_AXEBLOOD = 0x00000008, // weapon makes axe blood on impact (Hexen only)
|
|
||||||
WIF_NOALERT = 0x00000010, // weapon does not alert monsters
|
|
||||||
WIF_AMMO_OPTIONAL = 0x00000020, // weapon can use ammo but does not require it
|
|
||||||
WIF_ALT_AMMO_OPTIONAL = 0x00000040, // alternate fire can use ammo but does not require it
|
|
||||||
WIF_PRIMARY_USES_BOTH = 0x00000080, // primary fire uses both ammo
|
|
||||||
WIF_ALT_USES_BOTH = 0x00000100, // alternate fire uses both ammo
|
|
||||||
WIF_WIMPY_WEAPON = 0x00000200, // change away when ammo for another weapon is replenished
|
|
||||||
WIF_POWERED_UP = 0x00000400, // this is a tome-of-power'ed version of its sister
|
|
||||||
WIF_AMMO_CHECKBOTH = 0x00000800, // check for both primary and secondary fire before switching it off
|
|
||||||
WIF_NO_AUTO_SWITCH = 0x00001000, // never switch to this weapon when it's picked up
|
|
||||||
WIF_STAFF2_KICKBACK = 0x00002000, // the powered-up Heretic staff has special kickback
|
|
||||||
WIF_NOAUTOAIM = 0x00004000, // this weapon never uses autoaim (useful for ballistic projectiles)
|
|
||||||
WIF_MELEEWEAPON = 0x00008000, // melee weapon. Used by bots and monster AI.
|
|
||||||
WIF_DEHAMMO = 0x00010000, // Uses Doom's original amount of ammo for the respective attack functions so that old DEHACKED patches work as intended.
|
|
||||||
// AmmoUse1 will be set to the first attack's ammo use so that checking for empty weapons still works
|
|
||||||
WIF_NODEATHDESELECT = 0x00020000, // Don't jump to the Deselect state when the player dies
|
|
||||||
WIF_NODEATHINPUT = 0x00040000, // The weapon cannot be fired/reloaded/whatever when the player is dead
|
|
||||||
WIF_CHEATNOTWEAPON = 0x08000000, // Give cheat considers this not a weapon (used by Sigil)
|
|
||||||
|
|
||||||
// Flags used only by bot AI:
|
|
||||||
|
|
||||||
WIF_BOT_REACTION_SKILL_THING = 1<<31, // I don't understand this
|
|
||||||
WIF_BOT_EXPLOSIVE = 1<<30, // weapon fires an explosive
|
|
||||||
WIF_BOT_BFG = 1<<28, // this is a BFG
|
|
||||||
};
|
|
||||||
|
|
||||||
class AWeaponGiver : public AWeapon
|
|
||||||
{
|
|
||||||
DECLARE_CLASS(AWeaponGiver, AWeapon)
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool TryPickup(AActor *&toucher);
|
|
||||||
|
|
||||||
void Serialize(FSerializer &arc);
|
|
||||||
|
|
||||||
double DropAmmoFactor;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Health is some item that gives the player health when picked up.
|
// Health is some item that gives the player health when picked up.
|
||||||
class PClassHealth : public PClassInventory
|
class PClassHealth : public PClassInventory
|
||||||
{
|
{
|
||||||
|
@ -488,23 +237,6 @@ public:
|
||||||
bool TryPickup (AActor *&toucher);
|
bool TryPickup (AActor *&toucher);
|
||||||
};
|
};
|
||||||
|
|
||||||
// A backpack gives you one clip of each ammo and doubles your
|
|
||||||
// normal maximum ammo amounts.
|
|
||||||
class ABackpackItem : public AInventory
|
|
||||||
{
|
|
||||||
DECLARE_CLASS (ABackpackItem, AInventory)
|
|
||||||
public:
|
|
||||||
|
|
||||||
void Serialize(FSerializer &arc);
|
|
||||||
bool HandlePickup (AInventory *item);
|
|
||||||
AInventory *CreateCopy (AActor *other);
|
|
||||||
AInventory *CreateTossable ();
|
|
||||||
void DetachFromOwner ();
|
|
||||||
|
|
||||||
bool bDepleted;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// A score item is picked up without being added to the inventory.
|
// A score item is picked up without being added to the inventory.
|
||||||
// It differs from FakeInventory by doing nothing more than increasing the player's score.
|
// It differs from FakeInventory by doing nothing more than increasing the player's score.
|
||||||
class AScoreItem : public AInventory
|
class AScoreItem : public AInventory
|
||||||
|
|
|
@ -1,3 +1,38 @@
|
||||||
|
/*
|
||||||
|
** a_puzzleitems.cpp
|
||||||
|
** Implements Hexen's puzzle items.
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2002-2016 Randy Heit
|
||||||
|
** Copyright 2006-2016 Cheistoph Oelckers
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "a_pickups.h"
|
#include "a_pickups.h"
|
||||||
#include "a_artifacts.h"
|
#include "a_artifacts.h"
|
||||||
|
@ -8,7 +43,17 @@
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "v_font.h"
|
#include "v_font.h"
|
||||||
|
|
||||||
|
|
||||||
IMPLEMENT_CLASS(PClassPuzzleItem, false, false)
|
IMPLEMENT_CLASS(PClassPuzzleItem, false, false)
|
||||||
|
IMPLEMENT_CLASS(APuzzleItem, false, false)
|
||||||
|
|
||||||
|
DEFINE_FIELD(APuzzleItem, PuzzleItemNumber)
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
void PClassPuzzleItem::DeriveData(PClass *newclass)
|
void PClassPuzzleItem::DeriveData(PClass *newclass)
|
||||||
{
|
{
|
||||||
|
@ -17,9 +62,12 @@ void PClassPuzzleItem::DeriveData(PClass *newclass)
|
||||||
static_cast<PClassPuzzleItem *>(newclass)->PuzzFailMessage = PuzzFailMessage;
|
static_cast<PClassPuzzleItem *>(newclass)->PuzzFailMessage = PuzzFailMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_CLASS(APuzzleItem, false, false)
|
|
||||||
|
|
||||||
DEFINE_FIELD(APuzzleItem, PuzzleItemNumber)
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
bool APuzzleItem::HandlePickup (AInventory *item)
|
bool APuzzleItem::HandlePickup (AInventory *item)
|
||||||
{
|
{
|
||||||
|
@ -31,6 +79,12 @@ bool APuzzleItem::HandlePickup (AInventory *item)
|
||||||
return Super::HandlePickup (item);
|
return Super::HandlePickup (item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
bool APuzzleItem::Use (bool pickup)
|
bool APuzzleItem::Use (bool pickup)
|
||||||
{
|
{
|
||||||
if (P_UsePuzzleItem (Owner, PuzzleItemNumber))
|
if (P_UsePuzzleItem (Owner, PuzzleItemNumber))
|
||||||
|
@ -49,6 +103,12 @@ bool APuzzleItem::Use (bool pickup)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
bool APuzzleItem::ShouldStay ()
|
bool APuzzleItem::ShouldStay ()
|
||||||
{
|
{
|
||||||
return !!multiplayer;
|
return !!multiplayer;
|
||||||
|
|
|
@ -1,3 +1,38 @@
|
||||||
|
/*
|
||||||
|
** a_weaponpieces.cpp
|
||||||
|
** Implements generic weapon pieces
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2006-2016 Cheistoph Oelckers
|
||||||
|
** Copyright 2006-2016 Randy Heit
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
#include "a_pickups.h"
|
#include "a_pickups.h"
|
||||||
#include "a_weaponpiece.h"
|
#include "a_weaponpiece.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
|
@ -9,6 +44,12 @@ IMPLEMENT_CLASS(AWeaponHolder, false, false)
|
||||||
DEFINE_FIELD(AWeaponHolder, PieceMask);
|
DEFINE_FIELD(AWeaponHolder, PieceMask);
|
||||||
DEFINE_FIELD(AWeaponHolder, PieceWeapon);
|
DEFINE_FIELD(AWeaponHolder, PieceWeapon);
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
void PClassWeaponPiece::ReplaceClassRef(PClass *oldclass, PClass *newclass)
|
void PClassWeaponPiece::ReplaceClassRef(PClass *oldclass, PClass *newclass)
|
||||||
{
|
{
|
||||||
Super::ReplaceClassRef(oldclass, newclass);
|
Super::ReplaceClassRef(oldclass, newclass);
|
||||||
|
@ -19,6 +60,11 @@ void PClassWeaponPiece::ReplaceClassRef(PClass *oldclass, PClass *newclass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
void AWeaponHolder::Serialize(FSerializer &arc)
|
void AWeaponHolder::Serialize(FSerializer &arc)
|
||||||
{
|
{
|
||||||
|
@ -33,6 +79,11 @@ IMPLEMENT_POINTERS_START(AWeaponPiece)
|
||||||
IMPLEMENT_POINTER(FullWeapon)
|
IMPLEMENT_POINTER(FullWeapon)
|
||||||
IMPLEMENT_POINTERS_END
|
IMPLEMENT_POINTERS_END
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
void AWeaponPiece::Serialize(FSerializer &arc)
|
void AWeaponPiece::Serialize(FSerializer &arc)
|
||||||
{
|
{
|
||||||
|
@ -151,11 +202,23 @@ bool AWeaponPiece::TryPickup (AActor *&toucher)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
bool AWeaponPiece::ShouldStay ()
|
bool AWeaponPiece::ShouldStay ()
|
||||||
{
|
{
|
||||||
return PrivateShouldStay ();
|
return PrivateShouldStay ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
bool AWeaponPiece::PrivateShouldStay ()
|
bool AWeaponPiece::PrivateShouldStay ()
|
||||||
{
|
{
|
||||||
// We want a weapon piece to behave like a weapon, so follow the exact
|
// We want a weapon piece to behave like a weapon, so follow the exact
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "a_pickups.h"
|
#include "a_pickups.h"
|
||||||
|
#include "a_weapons.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
class PClassWeaponPiece : public PClassInventory
|
class PClassWeaponPiece : public PClassInventory
|
||||||
|
|
|
@ -1,3 +1,38 @@
|
||||||
|
/*
|
||||||
|
** a_weapons.cpp
|
||||||
|
** Implements weapon handling
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2000-2016 Randy Heit
|
||||||
|
** Copyright 2006-2016 Cheistoph Oelckers
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "a_pickups.h"
|
#include "a_pickups.h"
|
||||||
|
@ -19,6 +54,7 @@
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
#include "thingdef.h"
|
#include "thingdef.h"
|
||||||
#include "virtual.h"
|
#include "virtual.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
|
|
||||||
#define BONUSADD 6
|
#define BONUSADD 6
|
||||||
|
|
||||||
|
|
230
src/g_inventory/a_weapons.h
Normal file
230
src/g_inventory/a_weapons.h
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "a_ammo.h"
|
||||||
|
|
||||||
|
class PClassWeapon;
|
||||||
|
class AWeapon;
|
||||||
|
|
||||||
|
class FWeaponSlot
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FWeaponSlot() { Clear(); }
|
||||||
|
FWeaponSlot(const FWeaponSlot &other) { Weapons = other.Weapons; }
|
||||||
|
FWeaponSlot &operator= (const FWeaponSlot &other) { Weapons = other.Weapons; return *this; }
|
||||||
|
void Clear() { Weapons.Clear(); }
|
||||||
|
bool AddWeapon (const char *type);
|
||||||
|
bool AddWeapon (PClassWeapon *type);
|
||||||
|
void AddWeaponList (const char *list, bool clear);
|
||||||
|
AWeapon *PickWeapon (player_t *player, bool checkammo = false);
|
||||||
|
int Size () const { return (int)Weapons.Size(); }
|
||||||
|
int LocateWeapon (PClassWeapon *type);
|
||||||
|
|
||||||
|
inline PClassWeapon *GetWeapon (int index) const
|
||||||
|
{
|
||||||
|
if ((unsigned)index < Weapons.Size())
|
||||||
|
{
|
||||||
|
return Weapons[index].Type;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
friend struct FWeaponSlots;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct WeaponInfo
|
||||||
|
{
|
||||||
|
PClassWeapon *Type;
|
||||||
|
int Position;
|
||||||
|
};
|
||||||
|
void SetInitialPositions();
|
||||||
|
void Sort();
|
||||||
|
TArray<WeaponInfo> Weapons;
|
||||||
|
};
|
||||||
|
// FWeaponSlots::AddDefaultWeapon return codes
|
||||||
|
enum ESlotDef
|
||||||
|
{
|
||||||
|
SLOTDEF_Exists, // Weapon was already assigned a slot
|
||||||
|
SLOTDEF_Added, // Weapon was successfully added
|
||||||
|
SLOTDEF_Full // The specifed slot was full
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FWeaponSlots
|
||||||
|
{
|
||||||
|
FWeaponSlots() { Clear(); }
|
||||||
|
FWeaponSlots(const FWeaponSlots &other);
|
||||||
|
|
||||||
|
FWeaponSlot Slots[NUM_WEAPON_SLOTS];
|
||||||
|
|
||||||
|
AWeapon *PickNextWeapon (player_t *player);
|
||||||
|
AWeapon *PickPrevWeapon (player_t *player);
|
||||||
|
|
||||||
|
void Clear ();
|
||||||
|
bool LocateWeapon (PClassWeapon *type, int *const slot, int *const index);
|
||||||
|
ESlotDef AddDefaultWeapon (int slot, PClassWeapon *type);
|
||||||
|
void AddExtraWeapons();
|
||||||
|
void SetFromGameInfo();
|
||||||
|
void SetFromPlayer(PClassPlayerPawn *type);
|
||||||
|
void StandardSetup(PClassPlayerPawn *type);
|
||||||
|
void LocalSetup(PClassActor *type);
|
||||||
|
void SendDifferences(int playernum, const FWeaponSlots &other);
|
||||||
|
int RestoreSlots (FConfigFile *config, const char *section);
|
||||||
|
void PrintSettings();
|
||||||
|
|
||||||
|
void AddSlot(int slot, PClassWeapon *type, bool feedback);
|
||||||
|
void AddSlotDefault(int slot, PClassWeapon *type, bool feedback);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void P_PlaybackKeyConfWeapons(FWeaponSlots *slots);
|
||||||
|
void Net_WriteWeapon(PClassWeapon *type);
|
||||||
|
PClassWeapon *Net_ReadWeapon(BYTE **stream);
|
||||||
|
|
||||||
|
void P_SetupWeapons_ntohton();
|
||||||
|
void P_WriteDemoWeaponsChunk(BYTE **demo);
|
||||||
|
void P_ReadDemoWeaponsChunk(BYTE **demo);
|
||||||
|
|
||||||
|
|
||||||
|
// A weapon is just that.
|
||||||
|
class PClassWeapon : public PClassInventory
|
||||||
|
{
|
||||||
|
DECLARE_CLASS(PClassWeapon, PClassInventory);
|
||||||
|
protected:
|
||||||
|
virtual void DeriveData(PClass *newclass);
|
||||||
|
public:
|
||||||
|
PClassWeapon();
|
||||||
|
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
|
||||||
|
void Finalize(FStateDefinitions &statedef);
|
||||||
|
|
||||||
|
int SlotNumber;
|
||||||
|
int SlotPriority;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AWeapon : public AStateProvider
|
||||||
|
{
|
||||||
|
DECLARE_CLASS_WITH_META(AWeapon, AStateProvider, PClassWeapon)
|
||||||
|
HAS_OBJECT_POINTERS
|
||||||
|
public:
|
||||||
|
DWORD WeaponFlags;
|
||||||
|
PClassAmmo *AmmoType1, *AmmoType2; // Types of ammo used by this weapon
|
||||||
|
int AmmoGive1, AmmoGive2; // Amount of each ammo to get when picking up weapon
|
||||||
|
int MinAmmo1, MinAmmo2; // Minimum ammo needed to switch to this weapon
|
||||||
|
int AmmoUse1, AmmoUse2; // How much ammo to use with each shot
|
||||||
|
int Kickback;
|
||||||
|
float YAdjust; // For viewing the weapon fullscreen (visual only so no need to be a double)
|
||||||
|
FSoundIDNoInit UpSound, ReadySound; // Sounds when coming up and idle
|
||||||
|
PClassWeapon *SisterWeaponType; // Another weapon to pick up with this one
|
||||||
|
PClassActor *ProjectileType; // Projectile used by primary attack
|
||||||
|
PClassActor *AltProjectileType; // Projectile used by alternate attack
|
||||||
|
int SelectionOrder; // Lower-numbered weapons get picked first
|
||||||
|
int MinSelAmmo1, MinSelAmmo2; // Ignore in BestWeapon() if inadequate ammo
|
||||||
|
double MoveCombatDist; // Used by bots, but do they *really* need it?
|
||||||
|
int ReloadCounter; // For A_CheckForReload
|
||||||
|
int BobStyle; // [XA] Bobbing style. Defines type of bobbing (e.g. Normal, Alpha) (visual only so no need to be a double)
|
||||||
|
float BobSpeed; // [XA] Bobbing speed. Defines how quickly a weapon bobs.
|
||||||
|
float BobRangeX, BobRangeY; // [XA] Bobbing range. Defines how far a weapon bobs in either direction.
|
||||||
|
|
||||||
|
// In-inventory instance variables
|
||||||
|
TObjPtr<AAmmo> Ammo1, Ammo2;
|
||||||
|
TObjPtr<AWeapon> SisterWeapon;
|
||||||
|
float FOVScale;
|
||||||
|
int Crosshair; // 0 to use player's crosshair
|
||||||
|
bool GivenAsMorphWeapon;
|
||||||
|
|
||||||
|
bool bAltFire; // Set when this weapon's alternate fire is used.
|
||||||
|
|
||||||
|
virtual void MarkPrecacheSounds() const;
|
||||||
|
|
||||||
|
virtual void Serialize(FSerializer &arc);
|
||||||
|
virtual bool ShouldStay ();
|
||||||
|
virtual void AttachToOwner (AActor *other);
|
||||||
|
virtual bool HandlePickup (AInventory *item);
|
||||||
|
virtual AInventory *CreateCopy (AActor *other);
|
||||||
|
virtual AInventory *CreateTossable ();
|
||||||
|
virtual bool TryPickup (AActor *&toucher);
|
||||||
|
virtual bool TryPickupRestricted (AActor *&toucher);
|
||||||
|
virtual bool PickupForAmmo (AWeapon *ownedWeapon);
|
||||||
|
virtual bool Use (bool pickup);
|
||||||
|
virtual void Destroy() override;
|
||||||
|
|
||||||
|
FState *GetUpState ();
|
||||||
|
FState *GetDownState ();
|
||||||
|
FState *GetReadyState ();
|
||||||
|
FState *GetAtkState (bool hold);
|
||||||
|
FState *GetAltAtkState (bool hold);
|
||||||
|
FState *GetStateForButtonName (FName button);
|
||||||
|
|
||||||
|
virtual void PostMorphWeapon ();
|
||||||
|
virtual void EndPowerup ();
|
||||||
|
void CallEndPowerup();
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PrimaryFire,
|
||||||
|
AltFire,
|
||||||
|
EitherFire
|
||||||
|
};
|
||||||
|
bool CheckAmmo (int fireMode, bool autoSwitch, bool requireAmmo=false, int ammocount = -1);
|
||||||
|
bool DepleteAmmo (bool altFire, bool checkEnough=true, int ammouse = -1);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BobNormal,
|
||||||
|
BobInverse,
|
||||||
|
BobAlpha,
|
||||||
|
BobInverseAlpha,
|
||||||
|
BobSmooth,
|
||||||
|
BobInverseSmooth
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AAmmo *AddAmmo (AActor *other, PClassActor *ammotype, int amount);
|
||||||
|
bool AddExistingAmmo (AAmmo *ammo, int amount);
|
||||||
|
AWeapon *AddWeapon (PClassWeapon *weapon);
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
WIF_NOAUTOFIRE = 0x00000001, // weapon does not autofire
|
||||||
|
WIF_READYSNDHALF = 0x00000002, // ready sound is played ~1/2 the time
|
||||||
|
WIF_DONTBOB = 0x00000004, // don't bob the weapon
|
||||||
|
WIF_AXEBLOOD = 0x00000008, // weapon makes axe blood on impact (Hexen only)
|
||||||
|
WIF_NOALERT = 0x00000010, // weapon does not alert monsters
|
||||||
|
WIF_AMMO_OPTIONAL = 0x00000020, // weapon can use ammo but does not require it
|
||||||
|
WIF_ALT_AMMO_OPTIONAL = 0x00000040, // alternate fire can use ammo but does not require it
|
||||||
|
WIF_PRIMARY_USES_BOTH = 0x00000080, // primary fire uses both ammo
|
||||||
|
WIF_ALT_USES_BOTH = 0x00000100, // alternate fire uses both ammo
|
||||||
|
WIF_WIMPY_WEAPON = 0x00000200, // change away when ammo for another weapon is replenished
|
||||||
|
WIF_POWERED_UP = 0x00000400, // this is a tome-of-power'ed version of its sister
|
||||||
|
WIF_AMMO_CHECKBOTH = 0x00000800, // check for both primary and secondary fire before switching it off
|
||||||
|
WIF_NO_AUTO_SWITCH = 0x00001000, // never switch to this weapon when it's picked up
|
||||||
|
WIF_STAFF2_KICKBACK = 0x00002000, // the powered-up Heretic staff has special kickback
|
||||||
|
WIF_NOAUTOAIM = 0x00004000, // this weapon never uses autoaim (useful for ballistic projectiles)
|
||||||
|
WIF_MELEEWEAPON = 0x00008000, // melee weapon. Used by bots and monster AI.
|
||||||
|
WIF_DEHAMMO = 0x00010000, // Uses Doom's original amount of ammo for the respective attack functions so that old DEHACKED patches work as intended.
|
||||||
|
// AmmoUse1 will be set to the first attack's ammo use so that checking for empty weapons still works
|
||||||
|
WIF_NODEATHDESELECT = 0x00020000, // Don't jump to the Deselect state when the player dies
|
||||||
|
WIF_NODEATHINPUT = 0x00040000, // The weapon cannot be fired/reloaded/whatever when the player is dead
|
||||||
|
WIF_CHEATNOTWEAPON = 0x08000000, // Give cheat considers this not a weapon (used by Sigil)
|
||||||
|
|
||||||
|
// Flags used only by bot AI:
|
||||||
|
|
||||||
|
WIF_BOT_REACTION_SKILL_THING = 1<<31, // I don't understand this
|
||||||
|
WIF_BOT_EXPLOSIVE = 1<<30, // weapon fires an explosive
|
||||||
|
WIF_BOT_BFG = 1<<28, // this is a BFG
|
||||||
|
};
|
||||||
|
|
||||||
|
class AWeaponGiver : public AWeapon
|
||||||
|
{
|
||||||
|
DECLARE_CLASS(AWeaponGiver, AWeapon)
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool TryPickup(AActor *&toucher);
|
||||||
|
|
||||||
|
void Serialize(FSerializer &arc);
|
||||||
|
|
||||||
|
double DropAmmoFactor;
|
||||||
|
};
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
|
|
||||||
#define ARTIFLASH_OFFSET (statusBar->invBarOffset+6)
|
#define ARTIFLASH_OFFSET (statusBar->invBarOffset+6)
|
||||||
enum
|
enum
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
#include "a_keys.h"
|
#include "a_keys.h"
|
||||||
#include "a_armor.h"
|
#include "a_armor.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
#include "sbar.h"
|
#include "sbar.h"
|
||||||
#include "sc_man.h"
|
#include "sc_man.h"
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "a_keys.h"
|
#include "a_keys.h"
|
||||||
#include "a_armor.h"
|
#include "a_armor.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "colormatcher.h"
|
#include "colormatcher.h"
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "r_utility.h"
|
#include "r_utility.h"
|
||||||
#include "a_morph.h"
|
#include "a_morph.h"
|
||||||
#include "a_armor.h"
|
#include "a_armor.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
|
|
||||||
// [RH] Actually handle the cheat. The cheat code in st_stuff.c now just
|
// [RH] Actually handle the cheat. The cheat code in st_stuff.c now just
|
||||||
// writes some bytes to the network data stream, and the network code
|
// writes some bytes to the network data stream, and the network code
|
||||||
|
|
|
@ -84,6 +84,7 @@
|
||||||
#include "thingdef.h"
|
#include "thingdef.h"
|
||||||
#include "a_pickups.h"
|
#include "a_pickups.h"
|
||||||
#include "a_armor.h"
|
#include "a_armor.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
|
|
||||||
extern FILE *Logfile;
|
extern FILE *Logfile;
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "p_spec.h"
|
#include "p_spec.h"
|
||||||
#include "p_checkposition.h"
|
#include "p_checkposition.h"
|
||||||
#include "math/cmath.h"
|
#include "math/cmath.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
|
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
#include "virtual.h"
|
#include "virtual.h"
|
||||||
#include "a_armor.h"
|
#include "a_armor.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
#include "p_spec.h"
|
#include "p_spec.h"
|
||||||
#include "virtual.h"
|
#include "virtual.h"
|
||||||
#include "a_armor.h"
|
#include "a_armor.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
|
|
||||||
static FRandom pr_skullpop ("SkullPop");
|
static FRandom pr_skullpop ("SkullPop");
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
#include "a_weaponpiece.h"
|
#include "a_weaponpiece.h"
|
||||||
#include "vmbuilder.h"
|
#include "vmbuilder.h"
|
||||||
|
#include "a_ammo.h"
|
||||||
|
|
||||||
extern TArray<PClassActor **> OptionalClassPtrs;
|
extern TArray<PClassActor **> OptionalClassPtrs;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue