mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-28 15:02:39 +00:00
- Converted the Communicator to DECORATE.
- Renamed the new armor properties to use the same names as Skulltag to avoid confusion. They still don't need a separate base class as in Skulltag though. - Added Skulltag-type armor bonus that increases the max amount that can be given by other armor items. - Separated all armor related code from a_pickups.cpp into a_armor.cpp. SVN r427 (trunk)
This commit is contained in:
parent
c89dd1de57
commit
3eeef7af77
15 changed files with 1193 additions and 1179 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
December 25, 2006 (Changes by Graf Zahl)
|
||||||
|
- Converted the Communicator to DECORATE.
|
||||||
|
- Renamed the new armor properties to use the same names as Skulltag to avoid
|
||||||
|
confusion. They still don't need a separate base class as in Skulltag though.
|
||||||
|
- Added Skulltag-type armor bonus that increases the max amount that can be given
|
||||||
|
by other armor items.
|
||||||
|
- Separated all armor related code from a_pickups.cpp into a_armor.cpp.
|
||||||
|
|
||||||
December 24, 2006 (Changes by Graf Zahl)
|
December 24, 2006 (Changes by Graf Zahl)
|
||||||
- Replaced several calls to S_GetSoundPlayingInfo with S_IsActorPlayingSomething
|
- Replaced several calls to S_GetSoundPlayingInfo with S_IsActorPlayingSomething
|
||||||
because S_GetSoundPlayingInfo cannot properly resolve player and random sounds.
|
because S_GetSoundPlayingInfo cannot properly resolve player and random sounds.
|
||||||
|
|
|
@ -550,6 +550,7 @@ public:
|
||||||
|
|
||||||
// Finds the first item of a particular type.
|
// Finds the first item of a particular type.
|
||||||
AInventory *FindInventory (const PClass *type) const;
|
AInventory *FindInventory (const PClass *type) const;
|
||||||
|
AInventory *FindInventory (FName type) const;
|
||||||
template<class T> T *FindInventory () const
|
template<class T> T *FindInventory () const
|
||||||
{
|
{
|
||||||
return static_cast<T *> (FindInventory (RUNTIME_CLASS(T)));
|
return static_cast<T *> (FindInventory (RUNTIME_CLASS(T)));
|
||||||
|
|
|
@ -417,9 +417,8 @@ CCMD (useflechette)
|
||||||
|
|
||||||
for (j = 0; j < 3; ++j)
|
for (j = 0; j < 3; ++j)
|
||||||
{
|
{
|
||||||
const PClass *type = PClass::FindClass (bagnames[(i+j)%3]);
|
|
||||||
AInventory *item;
|
AInventory *item;
|
||||||
if (type != NULL && (item = who->FindInventory (type)))
|
if (item = who->FindInventory (bagnames[(i+j)%3]))
|
||||||
{
|
{
|
||||||
SendItemUse = item;
|
SendItemUse = item;
|
||||||
break;
|
break;
|
||||||
|
|
486
src/g_shared/a_armor.cpp
Normal file
486
src/g_shared/a_armor.cpp
Normal file
|
@ -0,0 +1,486 @@
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "info.h"
|
||||||
|
#include "gi.h"
|
||||||
|
#include "r_data.h"
|
||||||
|
#include "a_pickups.h"
|
||||||
|
#include "templates.h"
|
||||||
|
|
||||||
|
|
||||||
|
IMPLEMENT_STATELESS_ACTOR (AArmor, Any, -1, 0)
|
||||||
|
PROP_Inventory_PickupSound ("misc/armor_pkup")
|
||||||
|
END_DEFAULTS
|
||||||
|
|
||||||
|
IMPLEMENT_STATELESS_ACTOR (ABasicArmor, Any, -1, 0)
|
||||||
|
END_DEFAULTS
|
||||||
|
|
||||||
|
IMPLEMENT_STATELESS_ACTOR (ABasicArmorPickup, Any, -1, 0)
|
||||||
|
PROP_Inventory_MaxAmount (0)
|
||||||
|
PROP_Inventory_FlagsSet (IF_AUTOACTIVATE)
|
||||||
|
END_DEFAULTS
|
||||||
|
|
||||||
|
IMPLEMENT_STATELESS_ACTOR (ABasicArmorBonus, Any, -1, 0)
|
||||||
|
PROP_Inventory_MaxAmount (0)
|
||||||
|
PROP_Inventory_FlagsSet (IF_AUTOACTIVATE|IF_ALWAYSPICKUP)
|
||||||
|
PROP_BasicArmorBonus_SavePercent (FRACUNIT/3)
|
||||||
|
END_DEFAULTS
|
||||||
|
|
||||||
|
IMPLEMENT_STATELESS_ACTOR (AHexenArmor, Any, -1, 0)
|
||||||
|
PROP_Inventory_FlagsSet (IF_UNDROPPABLE)
|
||||||
|
END_DEFAULTS
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// ABasicArmor :: Serialize
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void ABasicArmor::Serialize (FArchive &arc)
|
||||||
|
{
|
||||||
|
Super::Serialize (arc);
|
||||||
|
arc << SavePercent << BonusCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// ABasicArmor :: Tick
|
||||||
|
//
|
||||||
|
// If BasicArmor is given to the player by means other than a
|
||||||
|
// BasicArmorPickup, then it may not have an icon set. Fix that here.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void ABasicArmor::Tick ()
|
||||||
|
{
|
||||||
|
Super::Tick ();
|
||||||
|
if (Icon == 0)
|
||||||
|
{
|
||||||
|
switch (gameinfo.gametype)
|
||||||
|
{
|
||||||
|
case GAME_Doom:
|
||||||
|
Icon = TexMan.CheckForTexture (SavePercent == FRACUNIT/3 ? "ARM1A0" : "ARM2A0", FTexture::TEX_Any);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GAME_Heretic:
|
||||||
|
Icon = TexMan.CheckForTexture (SavePercent == FRACUNIT/2 ? "SHLDA0" : "SHD2A0", FTexture::TEX_Any);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GAME_Strife:
|
||||||
|
Icon = TexMan.CheckForTexture (SavePercent == FRACUNIT/3 ? "I_ARM2" : "I_ARM1", FTexture::TEX_Any);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// ABasicArmor :: CreateCopy
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
AInventory *ABasicArmor::CreateCopy (AActor *other)
|
||||||
|
{
|
||||||
|
// BasicArmor that is in use is stored in the inventory as BasicArmor.
|
||||||
|
// BasicArmor that is in reserve is not.
|
||||||
|
ABasicArmor *copy = Spawn<ABasicArmor> (0, 0, 0, NO_REPLACE);
|
||||||
|
copy->SavePercent = SavePercent != 0 ? SavePercent : FRACUNIT/3;
|
||||||
|
copy->Amount = Amount;
|
||||||
|
copy->MaxAmount = MaxAmount;
|
||||||
|
copy->Icon = Icon;
|
||||||
|
copy->BonusCount = BonusCount;
|
||||||
|
GoAwayAndDie ();
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// ABasicArmor :: HandlePickup
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
bool ABasicArmor::HandlePickup (AInventory *item)
|
||||||
|
{
|
||||||
|
if (item->GetClass() == RUNTIME_CLASS(ABasicArmor))
|
||||||
|
{
|
||||||
|
// You shouldn't be picking up BasicArmor anyway.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (Inventory != NULL)
|
||||||
|
{
|
||||||
|
return Inventory->HandlePickup (item);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// ABasicArmor :: AbsorbDamage
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
||||||
|
{
|
||||||
|
if (damageType != NAME_Water)
|
||||||
|
{
|
||||||
|
int saved = FixedMul (damage, SavePercent);
|
||||||
|
if (Amount < saved)
|
||||||
|
{
|
||||||
|
saved = Amount;
|
||||||
|
}
|
||||||
|
newdamage -= saved;
|
||||||
|
Amount -= saved;
|
||||||
|
if (Amount == 0)
|
||||||
|
{
|
||||||
|
// The armor has become useless
|
||||||
|
SavePercent = 0;
|
||||||
|
// Now see if the player has some more armor in their inventory
|
||||||
|
// and use it if so. As in Strife, the best armor is used up first.
|
||||||
|
ABasicArmorPickup *best = NULL;
|
||||||
|
AInventory *probe = Owner->Inventory;
|
||||||
|
while (probe != NULL)
|
||||||
|
{
|
||||||
|
if (probe->IsKindOf (RUNTIME_CLASS(ABasicArmorPickup)))
|
||||||
|
{
|
||||||
|
ABasicArmorPickup *inInv = static_cast<ABasicArmorPickup*>(probe);
|
||||||
|
if (best == NULL || best->SavePercent < inInv->SavePercent)
|
||||||
|
{
|
||||||
|
best = inInv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
probe = probe->Inventory;
|
||||||
|
}
|
||||||
|
if (best != NULL)
|
||||||
|
{
|
||||||
|
Owner->UseInventory (best);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Inventory != NULL)
|
||||||
|
{
|
||||||
|
Inventory->AbsorbDamage (damage, damageType, newdamage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// ABasicArmorPickup :: Serialize
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void ABasicArmorPickup::Serialize (FArchive &arc)
|
||||||
|
{
|
||||||
|
Super::Serialize (arc);
|
||||||
|
arc << SavePercent << SaveAmount;
|
||||||
|
arc << DropTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// ABasicArmorPickup :: CreateCopy
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
AInventory *ABasicArmorPickup::CreateCopy (AActor *other)
|
||||||
|
{
|
||||||
|
ABasicArmorPickup *copy = static_cast<ABasicArmorPickup *> (Super::CreateCopy (other));
|
||||||
|
copy->SavePercent = SavePercent;
|
||||||
|
copy->SaveAmount = SaveAmount;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// ABasicArmorPickup :: Use
|
||||||
|
//
|
||||||
|
// Either gives you new armor or replaces the armor you already have (if
|
||||||
|
// the SaveAmount is greater than the amount of armor you own). When the
|
||||||
|
// item is auto-activated, it will only be activated if its max amount is 0
|
||||||
|
// or if you have no armor active already.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
bool ABasicArmorPickup::Use (bool pickup)
|
||||||
|
{
|
||||||
|
ABasicArmor *armor = Owner->FindInventory<ABasicArmor> ();
|
||||||
|
|
||||||
|
if (armor == NULL)
|
||||||
|
{
|
||||||
|
armor = Spawn<ABasicArmor> (0,0,0, NO_REPLACE);
|
||||||
|
armor->BecomeItem ();
|
||||||
|
Owner->AddInventory (armor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If you already have more armor than this item gives you, you can't
|
||||||
|
// use it.
|
||||||
|
if (armor->Amount >= SaveAmount + armor->BonusCount)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Don't use it if you're picking it up and already have some.
|
||||||
|
if (pickup && armor->Amount > 0 && MaxAmount > 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
armor->SavePercent = SavePercent;
|
||||||
|
armor->Amount = SaveAmount + armor->BonusCount;
|
||||||
|
armor->MaxAmount = SaveAmount;
|
||||||
|
armor->Icon = Icon;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// ABasicArmorBonus :: Serialize
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void ABasicArmorBonus::Serialize (FArchive &arc)
|
||||||
|
{
|
||||||
|
Super::Serialize (arc);
|
||||||
|
arc << SavePercent << SaveAmount << MaxSaveAmount << BonusCount << BonusMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// ABasicArmorBonus :: CreateCopy
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
AInventory *ABasicArmorBonus::CreateCopy (AActor *other)
|
||||||
|
{
|
||||||
|
ABasicArmorBonus *copy = static_cast<ABasicArmorBonus *> (Super::CreateCopy (other));
|
||||||
|
copy->SavePercent = SavePercent;
|
||||||
|
copy->SaveAmount = SaveAmount;
|
||||||
|
copy->MaxSaveAmount = MaxSaveAmount;
|
||||||
|
copy->BonusCount = BonusCount;
|
||||||
|
copy->BonusMax = BonusMax;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// ABasicArmorBonus :: Use
|
||||||
|
//
|
||||||
|
// Tries to add to the amount of BasicArmor a player has.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
bool ABasicArmorBonus::Use (bool pickup)
|
||||||
|
{
|
||||||
|
ABasicArmor *armor = Owner->FindInventory<ABasicArmor> ();
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (armor == NULL)
|
||||||
|
{
|
||||||
|
armor = Spawn<ABasicArmor> (0,0,0, NO_REPLACE);
|
||||||
|
armor->BecomeItem ();
|
||||||
|
armor->Amount = 0;
|
||||||
|
armor->MaxAmount = MaxSaveAmount;
|
||||||
|
Owner->AddInventory (armor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BonusCount > 0 && armor->BonusCount < BonusMax)
|
||||||
|
{
|
||||||
|
armor->BonusCount = MIN (armor->BonusCount + BonusCount, BonusMax);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int saveAmount = MIN (SaveAmount, MaxSaveAmount);
|
||||||
|
|
||||||
|
if (saveAmount <= 0)
|
||||||
|
{ // If it can't give you anything, it's as good as used.
|
||||||
|
return BonusCount > 0 ? result : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If you already have more armor than this item can give you, you can't
|
||||||
|
// use it.
|
||||||
|
if (armor->Amount >= MaxSaveAmount + armor->BonusCount)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (armor->Amount <= 0)
|
||||||
|
{ // Should never be less than 0, but might as well check anyway
|
||||||
|
armor->Amount = 0;
|
||||||
|
armor->Icon = Icon;
|
||||||
|
armor->SavePercent = SavePercent;
|
||||||
|
}
|
||||||
|
|
||||||
|
armor->Amount = MIN(armor->Amount + saveAmount, MaxSaveAmount + armor->BonusCount);
|
||||||
|
armor->MaxAmount = MAX (armor->MaxAmount, MaxSaveAmount);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// AHexenArmor :: Serialize
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void AHexenArmor::Serialize (FArchive &arc)
|
||||||
|
{
|
||||||
|
Super::Serialize (arc);
|
||||||
|
arc << Slots[0] << Slots[1] << Slots[2] << Slots[3]
|
||||||
|
<< Slots[4]
|
||||||
|
<< SlotsIncrement[0] << SlotsIncrement[1] << SlotsIncrement[2]
|
||||||
|
<< SlotsIncrement[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// AHexenArmor :: CreateCopy
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
AInventory *AHexenArmor::CreateCopy (AActor *other)
|
||||||
|
{
|
||||||
|
// Like BasicArmor, HexenArmor is used in the inventory but not the map.
|
||||||
|
// health is the slot this armor occupies.
|
||||||
|
// Amount is the quantity to give (0 = normal max).
|
||||||
|
AHexenArmor *copy = Spawn<AHexenArmor> (0, 0, 0, NO_REPLACE);
|
||||||
|
copy->AddArmorToSlot (other, health, Amount);
|
||||||
|
GoAwayAndDie ();
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// AHexenArmor :: CreateTossable
|
||||||
|
//
|
||||||
|
// Since this isn't really a single item, you can't drop it. Ever.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
AInventory *AHexenArmor::CreateTossable ()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// AHexenArmor :: HandlePickup
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
bool AHexenArmor::HandlePickup (AInventory *item)
|
||||||
|
{
|
||||||
|
if (item->IsKindOf (RUNTIME_CLASS(AHexenArmor)))
|
||||||
|
{
|
||||||
|
if (AddArmorToSlot (Owner, item->health, item->Amount))
|
||||||
|
{
|
||||||
|
item->ItemFlags |= IF_PICKUPGOOD;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (Inventory != NULL)
|
||||||
|
{
|
||||||
|
return Inventory->HandlePickup (item);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// AHexenArmor :: AddArmorToSlot
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
bool AHexenArmor::AddArmorToSlot (AActor *actor, int slot, int amount)
|
||||||
|
{
|
||||||
|
APlayerPawn *ppawn;
|
||||||
|
int hits;
|
||||||
|
|
||||||
|
if (actor->player != NULL)
|
||||||
|
{
|
||||||
|
ppawn = static_cast<APlayerPawn *>(actor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ppawn = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slot < 0 || slot > 3)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (amount <= 0)
|
||||||
|
{
|
||||||
|
hits = SlotsIncrement[slot];
|
||||||
|
if (Slots[slot] < hits)
|
||||||
|
{
|
||||||
|
Slots[slot] = hits;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hits = amount * 5 * FRACUNIT;
|
||||||
|
fixed_t total = Slots[0]+Slots[1]+Slots[2]+Slots[3]+Slots[4];
|
||||||
|
fixed_t max = SlotsIncrement[0]+SlotsIncrement[1]+SlotsIncrement[2]+SlotsIncrement[3]+Slots[4]+4*5*FRACUNIT;
|
||||||
|
if (total < max)
|
||||||
|
{
|
||||||
|
Slots[slot] += hits;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// AHexenArmor :: AbsorbDamage
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
||||||
|
{
|
||||||
|
if (damageType != NAME_Water)
|
||||||
|
{
|
||||||
|
fixed_t savedPercent = Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4];
|
||||||
|
|
||||||
|
if (savedPercent)
|
||||||
|
{ // armor absorbed some damage
|
||||||
|
if (savedPercent > 100*FRACUNIT)
|
||||||
|
{
|
||||||
|
savedPercent = 100*FRACUNIT;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (Slots[i])
|
||||||
|
{
|
||||||
|
// 300 damage always wipes out the armor unless some was added
|
||||||
|
// with the dragon skin bracers.
|
||||||
|
if (damage < 10000)
|
||||||
|
{
|
||||||
|
Slots[i] -= Scale (damage, SlotsIncrement[i], 300);
|
||||||
|
if (Slots[i] < 2*FRACUNIT)
|
||||||
|
{
|
||||||
|
Slots[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Slots[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int saved = Scale (damage, savedPercent, 100*FRACUNIT);
|
||||||
|
if (saved > savedPercent >> (FRACBITS-1))
|
||||||
|
{
|
||||||
|
saved = savedPercent >> (FRACBITS-1);
|
||||||
|
}
|
||||||
|
newdamage -= saved;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Inventory != NULL)
|
||||||
|
{
|
||||||
|
Inventory->AbsorbDamage (damage, damageType, newdamage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -165,8 +165,6 @@ AInventory *AAmmo::CreateCopy (AActor *other)
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keys *******************************************************************/
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// FUNC P_GiveBody
|
// FUNC P_GiveBody
|
||||||
|
@ -1270,472 +1268,6 @@ bool ACustomInventory::TryPickup (AActor *toucher)
|
||||||
return useok;
|
return useok;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_STATELESS_ACTOR (AArmor, Any, -1, 0)
|
|
||||||
PROP_Inventory_PickupSound ("misc/armor_pkup")
|
|
||||||
END_DEFAULTS
|
|
||||||
|
|
||||||
IMPLEMENT_STATELESS_ACTOR (ABasicArmor, Any, -1, 0)
|
|
||||||
PROP_SpawnState (S_HELD)
|
|
||||||
END_DEFAULTS
|
|
||||||
|
|
||||||
IMPLEMENT_STATELESS_ACTOR (ABasicArmorPickup, Any, -1, 0)
|
|
||||||
PROP_Inventory_MaxAmount (0)
|
|
||||||
PROP_Inventory_FlagsSet (IF_AUTOACTIVATE)
|
|
||||||
END_DEFAULTS
|
|
||||||
|
|
||||||
IMPLEMENT_STATELESS_ACTOR (ABasicArmorBonus, Any, -1, 0)
|
|
||||||
PROP_Inventory_MaxAmount (0)
|
|
||||||
PROP_Inventory_FlagsSet (IF_AUTOACTIVATE|IF_ALWAYSPICKUP)
|
|
||||||
PROP_BasicArmorBonus_SavePercent (FRACUNIT/3)
|
|
||||||
END_DEFAULTS
|
|
||||||
|
|
||||||
IMPLEMENT_STATELESS_ACTOR (AHexenArmor, Any, -1, 0)
|
|
||||||
PROP_Inventory_FlagsSet (IF_UNDROPPABLE)
|
|
||||||
END_DEFAULTS
|
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// ABasicArmorPickup :: Serialize
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void ABasicArmorPickup::Serialize (FArchive &arc)
|
|
||||||
{
|
|
||||||
Super::Serialize (arc);
|
|
||||||
arc << SavePercent << SaveAmount;
|
|
||||||
arc << DropTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// ABasicArmorPickup :: CreateCopy
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
AInventory *ABasicArmorPickup::CreateCopy (AActor *other)
|
|
||||||
{
|
|
||||||
ABasicArmorPickup *copy = static_cast<ABasicArmorPickup *> (Super::CreateCopy (other));
|
|
||||||
copy->SavePercent = SavePercent;
|
|
||||||
copy->SaveAmount = SaveAmount;
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// ABasicArmorPickup :: Use
|
|
||||||
//
|
|
||||||
// Either gives you new armor or replaces the armor you already have (if
|
|
||||||
// the SaveAmount is greater than the amount of armor you own). When the
|
|
||||||
// item is auto-activated, it will only be activated if its max amount is 0
|
|
||||||
// or if you have no armor active already.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
bool ABasicArmorPickup::Use (bool pickup)
|
|
||||||
{
|
|
||||||
ABasicArmor *armor = Owner->FindInventory<ABasicArmor> ();
|
|
||||||
|
|
||||||
if (armor == NULL)
|
|
||||||
{
|
|
||||||
armor = Spawn<ABasicArmor> (0,0,0, NO_REPLACE);
|
|
||||||
armor->BecomeItem ();
|
|
||||||
armor->SavePercent = SavePercent;
|
|
||||||
armor->Amount = armor->MaxAmount = SaveAmount;
|
|
||||||
armor->Icon = Icon;
|
|
||||||
Owner->AddInventory (armor);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// If you already have more armor than this item gives you, you can't
|
|
||||||
// use it.
|
|
||||||
if (armor->Amount >= SaveAmount)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Don't use it if you're picking it up and already have some.
|
|
||||||
if (pickup && armor->Amount > 0 && MaxAmount > 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
armor->SavePercent = SavePercent;
|
|
||||||
armor->Amount = armor->MaxAmount = SaveAmount;
|
|
||||||
armor->Icon = Icon;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// ABasicArmorBonus :: Serialize
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void ABasicArmorBonus::Serialize (FArchive &arc)
|
|
||||||
{
|
|
||||||
Super::Serialize (arc);
|
|
||||||
arc << SavePercent << SaveAmount << MaxSaveAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// ABasicArmorBonus :: CreateCopy
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
AInventory *ABasicArmorBonus::CreateCopy (AActor *other)
|
|
||||||
{
|
|
||||||
ABasicArmorBonus *copy = static_cast<ABasicArmorBonus *> (Super::CreateCopy (other));
|
|
||||||
copy->SavePercent = SavePercent;
|
|
||||||
copy->SaveAmount = SaveAmount;
|
|
||||||
copy->MaxSaveAmount = MaxSaveAmount;
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// ABasicArmorBonus :: Use
|
|
||||||
//
|
|
||||||
// Tries to add to the amount of BasicArmor a player has.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
bool ABasicArmorBonus::Use (bool pickup)
|
|
||||||
{
|
|
||||||
ABasicArmor *armor = Owner->FindInventory<ABasicArmor> ();
|
|
||||||
int saveAmount = MIN (SaveAmount, MaxSaveAmount);
|
|
||||||
|
|
||||||
if (saveAmount <= 0)
|
|
||||||
{ // If it can't give you anything, it's as good as used.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (armor == NULL)
|
|
||||||
{
|
|
||||||
armor = Spawn<ABasicArmor> (0,0,0, NO_REPLACE);
|
|
||||||
armor->BecomeItem ();
|
|
||||||
armor->SavePercent = SavePercent;
|
|
||||||
armor->Amount = saveAmount;
|
|
||||||
armor->MaxAmount = MaxSaveAmount;
|
|
||||||
armor->Icon = Icon;
|
|
||||||
Owner->AddInventory (armor);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// If you already have more armor than this item can give you, you can't
|
|
||||||
// use it.
|
|
||||||
if (armor->Amount >= MaxSaveAmount)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (armor->Amount <= 0)
|
|
||||||
{ // Should never be less than 0, but might as well check anyway
|
|
||||||
armor->Amount = 0;
|
|
||||||
armor->Icon = Icon;
|
|
||||||
armor->SavePercent = SavePercent;
|
|
||||||
}
|
|
||||||
armor->Amount += saveAmount;
|
|
||||||
armor->MaxAmount = MAX (armor->MaxAmount, MaxSaveAmount);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// ABasicArmor :: Serialize
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void ABasicArmor::Serialize (FArchive &arc)
|
|
||||||
{
|
|
||||||
Super::Serialize (arc);
|
|
||||||
arc << SavePercent;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// ABasicArmor :: Tick
|
|
||||||
//
|
|
||||||
// If BasicArmor is given to the player by means other than a
|
|
||||||
// BasicArmorPickup, then it may not have an icon set. Fix that here.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void ABasicArmor::Tick ()
|
|
||||||
{
|
|
||||||
Super::Tick ();
|
|
||||||
if (Icon == 0)
|
|
||||||
{
|
|
||||||
switch (gameinfo.gametype)
|
|
||||||
{
|
|
||||||
case GAME_Doom:
|
|
||||||
Icon = TexMan.CheckForTexture (SavePercent == FRACUNIT/3 ? "ARM1A0" : "ARM2A0", FTexture::TEX_Any);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GAME_Heretic:
|
|
||||||
Icon = TexMan.CheckForTexture (SavePercent == FRACUNIT/2 ? "SHLDA0" : "SHD2A0", FTexture::TEX_Any);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GAME_Strife:
|
|
||||||
Icon = TexMan.CheckForTexture (SavePercent == FRACUNIT/3 ? "I_ARM2" : "I_ARM1", FTexture::TEX_Any);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// ABasicArmor :: CreateCopy
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
AInventory *ABasicArmor::CreateCopy (AActor *other)
|
|
||||||
{
|
|
||||||
// BasicArmor that is in use is stored in the inventory as BasicArmor.
|
|
||||||
// BasicArmor that is in reserve is not.
|
|
||||||
ABasicArmor *copy = Spawn<ABasicArmor> (0, 0, 0, NO_REPLACE);
|
|
||||||
copy->SavePercent = SavePercent != 0 ? SavePercent : FRACUNIT/3;
|
|
||||||
copy->Amount = Amount;
|
|
||||||
copy->MaxAmount = MaxAmount;
|
|
||||||
copy->Icon = Icon;
|
|
||||||
GoAwayAndDie ();
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// ABasicArmor :: HandlePickup
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
bool ABasicArmor::HandlePickup (AInventory *item)
|
|
||||||
{
|
|
||||||
if (item->GetClass() == RUNTIME_CLASS(ABasicArmor))
|
|
||||||
{
|
|
||||||
// You shouldn't be picking up BasicArmor anyway.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (Inventory != NULL)
|
|
||||||
{
|
|
||||||
return Inventory->HandlePickup (item);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// ABasicArmor :: AbsorbDamage
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
|
||||||
{
|
|
||||||
if (damageType != NAME_Water)
|
|
||||||
{
|
|
||||||
int saved = FixedMul (damage, SavePercent);
|
|
||||||
if (Amount < saved)
|
|
||||||
{
|
|
||||||
saved = Amount;
|
|
||||||
}
|
|
||||||
newdamage -= saved;
|
|
||||||
Amount -= saved;
|
|
||||||
if (Amount == 0)
|
|
||||||
{
|
|
||||||
// The armor has become useless
|
|
||||||
SavePercent = 0;
|
|
||||||
// Now see if the player has some more armor in their inventory
|
|
||||||
// and use it if so. As in Strife, the best armor is used up first.
|
|
||||||
ABasicArmorPickup *best = NULL;
|
|
||||||
AInventory *probe = Owner->Inventory;
|
|
||||||
while (probe != NULL)
|
|
||||||
{
|
|
||||||
if (probe->IsKindOf (RUNTIME_CLASS(ABasicArmorPickup)))
|
|
||||||
{
|
|
||||||
ABasicArmorPickup *inInv = static_cast<ABasicArmorPickup*>(probe);
|
|
||||||
if (best == NULL || best->SavePercent < inInv->SavePercent)
|
|
||||||
{
|
|
||||||
best = inInv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
probe = probe->Inventory;
|
|
||||||
}
|
|
||||||
if (best != NULL)
|
|
||||||
{
|
|
||||||
Owner->UseInventory (best);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Inventory != NULL)
|
|
||||||
{
|
|
||||||
Inventory->AbsorbDamage (damage, damageType, newdamage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// AHexenArmor :: Serialize
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void AHexenArmor::Serialize (FArchive &arc)
|
|
||||||
{
|
|
||||||
Super::Serialize (arc);
|
|
||||||
arc << Slots[0] << Slots[1] << Slots[2] << Slots[3]
|
|
||||||
<< Slots[4]
|
|
||||||
<< SlotsIncrement[0] << SlotsIncrement[1] << SlotsIncrement[2]
|
|
||||||
<< SlotsIncrement[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// AHexenArmor :: CreateCopy
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
AInventory *AHexenArmor::CreateCopy (AActor *other)
|
|
||||||
{
|
|
||||||
// Like BasicArmor, HexenArmor is used in the inventory but not the map.
|
|
||||||
// health is the slot this armor occupies.
|
|
||||||
// Amount is the quantity to give (0 = normal max).
|
|
||||||
AHexenArmor *copy = Spawn<AHexenArmor> (0, 0, 0, NO_REPLACE);
|
|
||||||
copy->AddArmorToSlot (other, health, Amount);
|
|
||||||
GoAwayAndDie ();
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// AHexenArmor :: CreateTossable
|
|
||||||
//
|
|
||||||
// Since this isn't really a single item, you can't drop it. Ever.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
AInventory *AHexenArmor::CreateTossable ()
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// AHexenArmor :: HandlePickup
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
bool AHexenArmor::HandlePickup (AInventory *item)
|
|
||||||
{
|
|
||||||
if (item->IsKindOf (RUNTIME_CLASS(AHexenArmor)))
|
|
||||||
{
|
|
||||||
if (AddArmorToSlot (Owner, item->health, item->Amount))
|
|
||||||
{
|
|
||||||
item->ItemFlags |= IF_PICKUPGOOD;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (Inventory != NULL)
|
|
||||||
{
|
|
||||||
return Inventory->HandlePickup (item);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// AHexenArmor :: AddArmorToSlot
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
bool AHexenArmor::AddArmorToSlot (AActor *actor, int slot, int amount)
|
|
||||||
{
|
|
||||||
APlayerPawn *ppawn;
|
|
||||||
int hits;
|
|
||||||
|
|
||||||
if (actor->player != NULL)
|
|
||||||
{
|
|
||||||
ppawn = static_cast<APlayerPawn *>(actor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ppawn = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slot < 0 || slot > 3)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (amount <= 0)
|
|
||||||
{
|
|
||||||
hits = SlotsIncrement[slot];
|
|
||||||
if (Slots[slot] < hits)
|
|
||||||
{
|
|
||||||
Slots[slot] = hits;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hits = amount * 5 * FRACUNIT;
|
|
||||||
fixed_t total = Slots[0]+Slots[1]+Slots[2]+Slots[3]+Slots[4];
|
|
||||||
fixed_t max = SlotsIncrement[0]+SlotsIncrement[1]+SlotsIncrement[2]+SlotsIncrement[3]+Slots[4]+4*5*FRACUNIT;
|
|
||||||
if (total < max)
|
|
||||||
{
|
|
||||||
Slots[slot] += hits;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// AHexenArmor :: AbsorbDamage
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
|
||||||
{
|
|
||||||
if (damageType != NAME_Water)
|
|
||||||
{
|
|
||||||
fixed_t savedPercent = Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4];
|
|
||||||
|
|
||||||
if (savedPercent)
|
|
||||||
{ // armor absorbed some damage
|
|
||||||
if (savedPercent > 100*FRACUNIT)
|
|
||||||
{
|
|
||||||
savedPercent = 100*FRACUNIT;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (Slots[i])
|
|
||||||
{
|
|
||||||
// 300 damage always wipes out the armor unless some was added
|
|
||||||
// with the dragon skin bracers.
|
|
||||||
if (damage < 10000)
|
|
||||||
{
|
|
||||||
Slots[i] -= Scale (damage, SlotsIncrement[i], 300);
|
|
||||||
if (Slots[i] < 2*FRACUNIT)
|
|
||||||
{
|
|
||||||
Slots[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Slots[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int saved = Scale (damage, savedPercent, 100*FRACUNIT);
|
|
||||||
if (saved > savedPercent >> (FRACBITS-1))
|
|
||||||
{
|
|
||||||
saved = savedPercent >> (FRACBITS-1);
|
|
||||||
}
|
|
||||||
newdamage -= saved;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Inventory != NULL)
|
|
||||||
{
|
|
||||||
Inventory->AbsorbDamage (damage, damageType, newdamage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IMPLEMENT_STATELESS_ACTOR (AHealth, Any, -1, 0)
|
IMPLEMENT_STATELESS_ACTOR (AHealth, Any, -1, 0)
|
||||||
PROP_Inventory_Amount (1)
|
PROP_Inventory_Amount (1)
|
||||||
PROP_Inventory_MaxAmount (0)
|
PROP_Inventory_MaxAmount (0)
|
||||||
|
@ -2086,20 +1618,3 @@ bool AMapRevealer::TryPickup (AActor *toucher)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FState ACommunicator::States[] =
|
|
||||||
{
|
|
||||||
S_NORMAL (COMM, 'A', -1, NULL, NULL)
|
|
||||||
};
|
|
||||||
|
|
||||||
IMPLEMENT_ACTOR (ACommunicator, Strife, 206, 0)
|
|
||||||
PROP_Flags (MF_SPECIAL|MF_NOTDMATCH)
|
|
||||||
PROP_SpawnState (0)
|
|
||||||
PROP_StrifeType (176)
|
|
||||||
PROP_StrifeTeaserType (168)
|
|
||||||
PROP_StrifeTeaserType2 (172)
|
|
||||||
PROP_Inventory_Icon ("I_COMM")
|
|
||||||
PROP_Tag ("Communicator")
|
|
||||||
PROP_Inventory_PickupSound ("misc/p_pkup")
|
|
||||||
PROP_Inventory_PickupMessage("$TXT_COMMUNICATOR")
|
|
||||||
END_DEFAULTS
|
|
||||||
|
|
||||||
|
|
|
@ -320,6 +320,7 @@ public:
|
||||||
virtual void AbsorbDamage (int damage, FName damageType, int &newdamage);
|
virtual void AbsorbDamage (int damage, FName damageType, int &newdamage);
|
||||||
|
|
||||||
fixed_t SavePercent;
|
fixed_t SavePercent;
|
||||||
|
int BonusCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
// BasicArmorPickup replaces the armor you have.
|
// BasicArmorPickup replaces the armor you have.
|
||||||
|
@ -347,6 +348,8 @@ public:
|
||||||
fixed_t SavePercent; // The default, for when you don't already have armor
|
fixed_t SavePercent; // The default, for when you don't already have armor
|
||||||
int MaxSaveAmount;
|
int MaxSaveAmount;
|
||||||
int SaveAmount;
|
int SaveAmount;
|
||||||
|
int BonusCount;
|
||||||
|
int BonusMax;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hexen armor consists of four separate armor types plus a conceptual armor
|
// Hexen armor consists of four separate armor types plus a conceptual armor
|
||||||
|
@ -404,11 +407,4 @@ public:
|
||||||
bool bDepleted;
|
bool bDepleted;
|
||||||
};
|
};
|
||||||
|
|
||||||
// When the communicator is in a player's inventory, the
|
|
||||||
// SendToCommunicator special can work.
|
|
||||||
class ACommunicator : public AInventory
|
|
||||||
{
|
|
||||||
DECLARE_ACTOR (ACommunicator, AInventory)
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //__A_PICKUPS_H__
|
#endif //__A_PICKUPS_H__
|
||||||
|
|
|
@ -672,7 +672,7 @@ private:
|
||||||
DrINumber2 (i, left+268*xscale, top+76*yscale, 7*xscale, imgFONY0);
|
DrINumber2 (i, left+268*xscale, top+76*yscale, 7*xscale, imgFONY0);
|
||||||
|
|
||||||
// Does the player have a communicator?
|
// Does the player have a communicator?
|
||||||
item = CPlayer->mo->FindInventory (RUNTIME_CLASS(ACommunicator));
|
item = CPlayer->mo->FindInventory (NAME_Communicator);
|
||||||
if (item != NULL)
|
if (item != NULL)
|
||||||
{
|
{
|
||||||
screen->DrawTexture (TexMan(item->Icon),
|
screen->DrawTexture (TexMan(item->Icon),
|
||||||
|
@ -730,7 +730,7 @@ private:
|
||||||
};
|
};
|
||||||
for (i = 0; i < 6; ++i)
|
for (i = 0; i < 6; ++i)
|
||||||
{
|
{
|
||||||
item = CPlayer->mo->FindInventory (PClass::FindClass (WeaponList[i].TypeName));
|
item = CPlayer->mo->FindInventory (WeaponList[i].TypeName);
|
||||||
|
|
||||||
if (item != NULL)
|
if (item != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -217,3 +217,4 @@ xx(MomZ)
|
||||||
xx(MapSpot)
|
xx(MapSpot)
|
||||||
xx(PatrolPoint)
|
xx(PatrolPoint)
|
||||||
xx(PatrolSpecial)
|
xx(PatrolSpecial)
|
||||||
|
xx(Communicator)
|
||||||
|
|
|
@ -2557,7 +2557,7 @@ FUNC(LS_SendToCommunicator)
|
||||||
if (arg1 && backSide)
|
if (arg1 && backSide)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (it != NULL && it->player != NULL && it->FindInventory<ACommunicator>())
|
if (it != NULL && it->player != NULL && it->FindInventory(NAME_Communicator))
|
||||||
{
|
{
|
||||||
char name[32];
|
char name[32];
|
||||||
sprintf (name, "svox/voc%d", arg0);
|
sprintf (name, "svox/voc%d", arg0);
|
||||||
|
|
|
@ -795,6 +795,11 @@ AInventory *AActor::FindInventory (const PClass *type) const
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AInventory *AActor::FindInventory (FName type) const
|
||||||
|
{
|
||||||
|
return FindInventory(PClass::FindClass(type));
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// AActor :: GiveInventoryType
|
// AActor :: GiveInventoryType
|
||||||
|
|
|
@ -2035,7 +2035,7 @@ void P_PlayerThink (player_t *player)
|
||||||
}
|
}
|
||||||
else if (cmd->ucmd.upmove > 0 && !(player->cheats & CF_PREDICTING))
|
else if (cmd->ucmd.upmove > 0 && !(player->cheats & CF_PREDICTING))
|
||||||
{
|
{
|
||||||
AInventory *fly = player->mo->FindInventory (PClass::FindClass (NAME_ArtiFly));
|
AInventory *fly = player->mo->FindInventory (NAME_ArtiFly);
|
||||||
if (fly != NULL)
|
if (fly != NULL)
|
||||||
{
|
{
|
||||||
player->mo->UseInventory (fly);
|
player->mo->UseInventory (fly);
|
||||||
|
|
|
@ -3347,7 +3347,25 @@ static void AmmoDropAmount (AAmmo *defaults, Baggage &bag)
|
||||||
static void ArmorMaxSaveAmount (ABasicArmorBonus *defaults, Baggage &bag)
|
static void ArmorMaxSaveAmount (ABasicArmorBonus *defaults, Baggage &bag)
|
||||||
{
|
{
|
||||||
SC_MustGetNumber();
|
SC_MustGetNumber();
|
||||||
defaults->MaxSaveAmount=sc_Number;
|
defaults->MaxSaveAmount = sc_Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
static void ArmorMaxBonus (ABasicArmorBonus *defaults, Baggage &bag)
|
||||||
|
{
|
||||||
|
SC_MustGetNumber();
|
||||||
|
defaults->BonusCount = sc_Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
static void ArmorMaxBonusMax (ABasicArmorBonus *defaults, Baggage &bag)
|
||||||
|
{
|
||||||
|
SC_MustGetNumber();
|
||||||
|
defaults->BonusMax = sc_Number;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -4025,6 +4043,8 @@ static const ActorProps props[] =
|
||||||
{ "ammo.backpackmaxamount", (apf)AmmoBackpackMaxAmount, RUNTIME_CLASS(AAmmo) },
|
{ "ammo.backpackmaxamount", (apf)AmmoBackpackMaxAmount, RUNTIME_CLASS(AAmmo) },
|
||||||
{ "ammo.dropamount", (apf)AmmoDropAmount, RUNTIME_CLASS(AAmmo) },
|
{ "ammo.dropamount", (apf)AmmoDropAmount, RUNTIME_CLASS(AAmmo) },
|
||||||
{ "args", ActorArgs, RUNTIME_CLASS(AActor) },
|
{ "args", ActorArgs, RUNTIME_CLASS(AActor) },
|
||||||
|
{ "armor.maxbonus", (apf)ArmorMaxBonus, RUNTIME_CLASS(ABasicArmorBonus) },
|
||||||
|
{ "armor.maxbonusmax", (apf)ArmorMaxBonusMax, RUNTIME_CLASS(ABasicArmorBonus) },
|
||||||
{ "armor.maxsaveamount", (apf)ArmorMaxSaveAmount, RUNTIME_CLASS(ABasicArmorBonus) },
|
{ "armor.maxsaveamount", (apf)ArmorMaxSaveAmount, RUNTIME_CLASS(ABasicArmorBonus) },
|
||||||
{ "armor.saveamount", (apf)ArmorSaveAmount, RUNTIME_CLASS(AActor) },
|
{ "armor.saveamount", (apf)ArmorSaveAmount, RUNTIME_CLASS(AActor) },
|
||||||
{ "armor.savepercent", (apf)ArmorSavePercent, RUNTIME_CLASS(AActor) },
|
{ "armor.savepercent", (apf)ArmorSavePercent, RUNTIME_CLASS(AActor) },
|
||||||
|
|
|
@ -1260,23 +1260,19 @@ void DoTakeInventory(AActor * self, AActor * receiver)
|
||||||
ENamedName item =(ENamedName)StateParameters[index];
|
ENamedName item =(ENamedName)StateParameters[index];
|
||||||
int amount=EvalExpressionI (StateParameters[index+1], self);
|
int amount=EvalExpressionI (StateParameters[index+1], self);
|
||||||
|
|
||||||
const PClass * mi=PClass::FindClass(item);
|
|
||||||
|
|
||||||
if (pStateCall != NULL) pStateCall->Result=false;
|
if (pStateCall != NULL) pStateCall->Result=false;
|
||||||
if (mi)
|
|
||||||
{
|
|
||||||
AInventory * inv = receiver->FindInventory(mi);
|
|
||||||
|
|
||||||
if (inv && !inv->IsKindOf(RUNTIME_CLASS(AHexenArmor)))
|
AInventory * inv = receiver->FindInventory(item);
|
||||||
|
|
||||||
|
if (inv && !inv->IsKindOf(RUNTIME_CLASS(AHexenArmor)))
|
||||||
|
{
|
||||||
|
if (inv->Amount > 0 && pStateCall != NULL) pStateCall->Result=true;
|
||||||
|
if (!amount || amount>=inv->Amount)
|
||||||
{
|
{
|
||||||
if (inv->Amount > 0 && pStateCall != NULL) pStateCall->Result=true;
|
if (inv->IsKindOf(RUNTIME_CLASS(AAmmo))) inv->Amount=0;
|
||||||
if (!amount || amount>=inv->Amount)
|
else inv->Destroy();
|
||||||
{
|
|
||||||
if (inv->IsKindOf(RUNTIME_CLASS(AAmmo))) inv->Amount=0;
|
|
||||||
else inv->Destroy();
|
|
||||||
}
|
|
||||||
else inv->Amount-=amount;
|
|
||||||
}
|
}
|
||||||
|
else inv->Amount-=amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1579,8 +1575,7 @@ void A_SelectWeapon(AActor * actor)
|
||||||
int index=CheckIndex(1, NULL);
|
int index=CheckIndex(1, NULL);
|
||||||
if (index<0 || actor->player == NULL) return;
|
if (index<0 || actor->player == NULL) return;
|
||||||
|
|
||||||
const PClass * weapon= PClass::FindClass((ENamedName)StateParameters[index]);
|
AWeapon * weaponitem = static_cast<AWeapon*>(actor->FindInventory((ENamedName)StateParameters[index]));
|
||||||
AWeapon * weaponitem = static_cast<AWeapon*>(actor->FindInventory(weapon));
|
|
||||||
|
|
||||||
if (weaponitem != NULL && weaponitem->IsKindOf(RUNTIME_CLASS(AWeapon)))
|
if (weaponitem != NULL && weaponitem->IsKindOf(RUNTIME_CLASS(AWeapon)))
|
||||||
{
|
{
|
||||||
|
@ -1802,14 +1797,11 @@ void A_DropInventory(AActor * self)
|
||||||
{
|
{
|
||||||
int index=CheckIndex(1, &CallingState);
|
int index=CheckIndex(1, &CallingState);
|
||||||
if (index<0) return;
|
if (index<0) return;
|
||||||
const PClass * ti = PClass::FindClass((ENamedName)StateParameters[index]);
|
|
||||||
if (ti)
|
AInventory * inv = self->FindInventory((ENamedName)StateParameters[index]);
|
||||||
|
if (inv)
|
||||||
{
|
{
|
||||||
AInventory * inv = self->FindInventory(ti);
|
self->DropInventory(inv);
|
||||||
if (inv)
|
|
||||||
{
|
|
||||||
self->DropInventory(inv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -352,3 +352,22 @@ ACTOR Targeter : PowerupGiver 207
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Communicator -----------------------------------------------------------------
|
||||||
|
|
||||||
|
ACTOR Communicator : Inventory 206
|
||||||
|
{
|
||||||
|
Game Strife
|
||||||
|
ConversationID 176, 168, 172
|
||||||
|
+NOTDMATCH
|
||||||
|
Tag "Communicator"
|
||||||
|
Inventory.Icon "I_COMM"
|
||||||
|
Inventory.PickupSound "misc/p_pkup"
|
||||||
|
Inventory.PickupMessage "$TXT_COMMUNICATOR"
|
||||||
|
States
|
||||||
|
{
|
||||||
|
Spawn:
|
||||||
|
COMM A -1
|
||||||
|
Stop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
1286
zdoom.vcproj
1286
zdoom.vcproj
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue