mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- did some cleanup and consolidation on damage factor code while converting it all to floating point.
- made armor properties floating point.
This commit is contained in:
parent
1eb106e2c5
commit
af427b80bd
19 changed files with 104 additions and 112 deletions
|
@ -1940,13 +1940,13 @@ static int PatchMisc (int dummy)
|
||||||
if (armor!=NULL)
|
if (armor!=NULL)
|
||||||
{
|
{
|
||||||
armor->SaveAmount = 100 * deh.GreenAC;
|
armor->SaveAmount = 100 * deh.GreenAC;
|
||||||
armor->SavePercent = deh.GreenAC == 1 ? FRACUNIT/3 : FRACUNIT/2;
|
armor->SavePercent = deh.GreenAC == 1 ? 0.33335 : 0.5;
|
||||||
}
|
}
|
||||||
armor = static_cast<ABasicArmorPickup *> (GetDefaultByName ("BlueArmor"));
|
armor = static_cast<ABasicArmorPickup *> (GetDefaultByName ("BlueArmor"));
|
||||||
if (armor!=NULL)
|
if (armor!=NULL)
|
||||||
{
|
{
|
||||||
armor->SaveAmount = 100 * deh.BlueAC;
|
armor->SaveAmount = 100 * deh.BlueAC;
|
||||||
armor->SavePercent = deh.BlueAC == 1 ? FRACUNIT/3 : FRACUNIT/2;
|
armor->SavePercent = deh.BlueAC == 1 ? 0.33335 : 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
ABasicArmorBonus *barmor;
|
ABasicArmorBonus *barmor;
|
||||||
|
|
|
@ -89,7 +89,7 @@ public:
|
||||||
FString Slot[10];
|
FString Slot[10];
|
||||||
FName InvulMode;
|
FName InvulMode;
|
||||||
FName HealingRadiusType;
|
FName HealingRadiusType;
|
||||||
fixed_t HexenArmor[5];
|
double HexenArmor[5];
|
||||||
BYTE ColorRangeStart; // Skin color range
|
BYTE ColorRangeStart; // Skin color range
|
||||||
BYTE ColorRangeEnd;
|
BYTE ColorRangeEnd;
|
||||||
FPlayerColorSetMap ColorSets;
|
FPlayerColorSetMap ColorSets;
|
||||||
|
|
|
@ -287,13 +287,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
|
||||||
// base the number of shards on the size of the dead thing, so bigger
|
// base the number of shards on the size of the dead thing, so bigger
|
||||||
// things break up into more shards than smaller things.
|
// things break up into more shards than smaller things.
|
||||||
// An actor with _f_radius() 20 and height 64 creates ~40 chunks.
|
// An actor with _f_radius() 20 and height 64 creates ~40 chunks.
|
||||||
numChunks = MAX<int> (4, (self->_f_radius()>>FRACBITS)*(self->_f_height()>>FRACBITS)/32);
|
numChunks = MAX<int>(4, int(self->radius * self->Height)/32);
|
||||||
i = (pr_freeze.Random2()) % (numChunks/4);
|
i = (pr_freeze.Random2()) % (numChunks/4);
|
||||||
for (i = MAX (24, numChunks + i); i >= 0; i--)
|
for (i = MAX (24, numChunks + i); i >= 0; i--)
|
||||||
{
|
{
|
||||||
fixed_t xo = (((pr_freeze() - 128)*self->_f_radius()) >> 7);
|
double xo = (pr_freeze() - 128)*self->radius / 128;
|
||||||
fixed_t yo = (((pr_freeze() - 128)*self->_f_radius()) >> 7);
|
double yo = (pr_freeze() - 128)*self->radius / 128;
|
||||||
fixed_t zo = (pr_freeze()*self->_f_height() / 255);
|
double zo = (pr_freeze()*self->Height / 255);
|
||||||
|
|
||||||
mo = Spawn("IceChunk", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
|
mo = Spawn("IceChunk", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
|
||||||
if (mo)
|
if (mo)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,8 +67,8 @@ AInventory *ABasicArmor::CreateCopy (AActor *other)
|
||||||
{
|
{
|
||||||
// BasicArmor that is in use is stored in the inventory as BasicArmor.
|
// BasicArmor that is in use is stored in the inventory as BasicArmor.
|
||||||
// BasicArmor that is in reserve is not.
|
// BasicArmor that is in reserve is not.
|
||||||
ABasicArmor *copy = Spawn<ABasicArmor> (0, 0, 0, NO_REPLACE);
|
ABasicArmor *copy = Spawn<ABasicArmor> ();
|
||||||
copy->SavePercent = SavePercent != 0 ? SavePercent : FRACUNIT/3;
|
copy->SavePercent = SavePercent != 0 ? SavePercent : 0.33335; // slightly more than 1/3 to avoid roundoff errors.
|
||||||
copy->Amount = Amount;
|
copy->Amount = Amount;
|
||||||
copy->MaxAmount = MaxAmount;
|
copy->MaxAmount = MaxAmount;
|
||||||
copy->Icon = Icon;
|
copy->Icon = Icon;
|
||||||
|
@ -130,7 +130,7 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
saved = full + FixedMul (damage - full, SavePercent);
|
saved = full + int((damage - full) * SavePercent);
|
||||||
if (MaxAbsorb > 0 && saved + AbsorbCount > MaxAbsorb)
|
if (MaxAbsorb > 0 && saved + AbsorbCount > MaxAbsorb)
|
||||||
{
|
{
|
||||||
saved = MAX(0, MaxAbsorb - AbsorbCount);
|
saved = MAX(0, MaxAbsorb - AbsorbCount);
|
||||||
|
@ -179,15 +179,10 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
||||||
// This code is taken and adapted from APowerProtection::ModifyDamage().
|
// This code is taken and adapted from APowerProtection::ModifyDamage().
|
||||||
// The differences include not using a default value, and of course the way
|
// The differences include not using a default value, and of course the way
|
||||||
// the damage factor info is obtained.
|
// the damage factor info is obtained.
|
||||||
const fixed_t *pdf = NULL;
|
|
||||||
DmgFactors *df = PClass::FindActor(ArmorType)->DamageFactors;
|
DmgFactors *df = PClass::FindActor(ArmorType)->DamageFactors;
|
||||||
if (df != NULL && df->CountUsed() != 0)
|
if (df != NULL)
|
||||||
{
|
{
|
||||||
pdf = df->CheckFactor(damageType);
|
damage = newdamage = df->Apply(damageType, damage);
|
||||||
if (pdf != NULL)
|
|
||||||
{
|
|
||||||
damage = newdamage = FixedMul(damage, *pdf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Inventory != NULL)
|
if (Inventory != NULL)
|
||||||
|
@ -401,7 +396,7 @@ AInventory *AHexenArmor::CreateCopy (AActor *other)
|
||||||
// Like BasicArmor, HexenArmor is used in the inventory but not the map.
|
// Like BasicArmor, HexenArmor is used in the inventory but not the map.
|
||||||
// health is the slot this armor occupies.
|
// health is the slot this armor occupies.
|
||||||
// Amount is the quantity to give (0 = normal max).
|
// Amount is the quantity to give (0 = normal max).
|
||||||
AHexenArmor *copy = Spawn<AHexenArmor> (0, 0, 0, NO_REPLACE);
|
AHexenArmor *copy = Spawn<AHexenArmor> ();
|
||||||
copy->AddArmorToSlot (other, health, Amount);
|
copy->AddArmorToSlot (other, health, Amount);
|
||||||
GoAwayAndDie ();
|
GoAwayAndDie ();
|
||||||
return copy;
|
return copy;
|
||||||
|
@ -452,7 +447,7 @@ bool AHexenArmor::HandlePickup (AInventory *item)
|
||||||
bool AHexenArmor::AddArmorToSlot (AActor *actor, int slot, int amount)
|
bool AHexenArmor::AddArmorToSlot (AActor *actor, int slot, int amount)
|
||||||
{
|
{
|
||||||
APlayerPawn *ppawn;
|
APlayerPawn *ppawn;
|
||||||
int hits;
|
double hits;
|
||||||
|
|
||||||
if (actor->player != NULL)
|
if (actor->player != NULL)
|
||||||
{
|
{
|
||||||
|
@ -478,9 +473,9 @@ bool AHexenArmor::AddArmorToSlot (AActor *actor, int slot, int amount)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hits = amount * 5 * FRACUNIT;
|
hits = amount * 5;
|
||||||
fixed_t total = Slots[0]+Slots[1]+Slots[2]+Slots[3]+Slots[4];
|
auto 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;
|
auto max = SlotsIncrement[0] + SlotsIncrement[1] + SlotsIncrement[2] + SlotsIncrement[3] + Slots[4] + 4 * 5;
|
||||||
if (total < max)
|
if (total < max)
|
||||||
{
|
{
|
||||||
Slots[slot] += hits;
|
Slots[slot] += hits;
|
||||||
|
@ -500,13 +495,13 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
||||||
{
|
{
|
||||||
if (!DamageTypeDefinition::IgnoreArmor(damageType))
|
if (!DamageTypeDefinition::IgnoreArmor(damageType))
|
||||||
{
|
{
|
||||||
fixed_t savedPercent = Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4];
|
double savedPercent = Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4];
|
||||||
|
|
||||||
if (savedPercent)
|
if (savedPercent)
|
||||||
{ // armor absorbed some damage
|
{ // armor absorbed some damage
|
||||||
if (savedPercent > 100*FRACUNIT)
|
if (savedPercent > 100)
|
||||||
{
|
{
|
||||||
savedPercent = 100*FRACUNIT;
|
savedPercent = 100;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
|
@ -516,15 +511,8 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
||||||
// with the dragon skin bracers.
|
// with the dragon skin bracers.
|
||||||
if (damage < 10000)
|
if (damage < 10000)
|
||||||
{
|
{
|
||||||
#if __APPLE__ && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ == 1
|
Slots[i] -= damage * SlotsIncrement[i] / 300.;
|
||||||
// -O1 optimizer bug work around. Only needed for
|
if (Slots[i] < 2)
|
||||||
// GCC 4.2.1 on OS X for 10.4/10.5 tools compatibility.
|
|
||||||
volatile fixed_t tmp = 300;
|
|
||||||
Slots[i] -= ::Scale (damage, SlotsIncrement[i], tmp);
|
|
||||||
#else
|
|
||||||
Slots[i] -= ::Scale (damage, SlotsIncrement[i], 300);
|
|
||||||
#endif
|
|
||||||
if (Slots[i] < 2*FRACUNIT)
|
|
||||||
{
|
{
|
||||||
Slots[i] = 0;
|
Slots[i] = 0;
|
||||||
}
|
}
|
||||||
|
@ -535,10 +523,10 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int saved = ::Scale (damage, savedPercent, 100*FRACUNIT);
|
int saved = int(damage * savedPercent / 100.);
|
||||||
if (saved > savedPercent >> (FRACBITS-1))
|
if (saved > savedPercent*2)
|
||||||
{
|
{
|
||||||
saved = savedPercent >> (FRACBITS-1);
|
saved = int(savedPercent*2);
|
||||||
}
|
}
|
||||||
newdamage -= saved;
|
newdamage -= saved;
|
||||||
damage = newdamage;
|
damage = newdamage;
|
||||||
|
|
|
@ -1630,25 +1630,20 @@ void APowerDamage::EndEffect( )
|
||||||
|
|
||||||
void APowerDamage::ModifyDamage(int damage, FName damageType, int &newdamage, bool passive)
|
void APowerDamage::ModifyDamage(int damage, FName damageType, int &newdamage, bool passive)
|
||||||
{
|
{
|
||||||
static const fixed_t def = 4*FRACUNIT;
|
|
||||||
if (!passive && damage > 0)
|
if (!passive && damage > 0)
|
||||||
{
|
{
|
||||||
const fixed_t *pdf = NULL;
|
int newdam;
|
||||||
DmgFactors *df = GetClass()->DamageFactors;
|
DmgFactors *df = GetClass()->DamageFactors;
|
||||||
if (df != NULL && df->CountUsed() != 0)
|
if (df != NULL && df->CountUsed() != 0)
|
||||||
{
|
{
|
||||||
pdf = df->CheckFactor(damageType);
|
newdam = MIN(1, df->Apply(damageType, damage));// don't allow zero damage as result of an underflow
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pdf = &def;
|
newdam = damage * 4;
|
||||||
}
|
|
||||||
if (pdf != NULL)
|
|
||||||
{
|
|
||||||
damage = newdamage = FixedMul(damage, *pdf);
|
|
||||||
if (*pdf > 0 && damage == 0) damage = newdamage = 1; // don't allow zero damage as result of an underflow
|
|
||||||
if (Owner != NULL && *pdf > FRACUNIT) S_Sound(Owner, 5, ActiveSound, 1.0f, ATTN_NONE);
|
|
||||||
}
|
}
|
||||||
|
if (Owner != NULL && newdam > damage) S_Sound(Owner, 5, ActiveSound, 1.0f, ATTN_NONE);
|
||||||
|
newdamage = newdam;
|
||||||
}
|
}
|
||||||
if (Inventory != NULL) Inventory->ModifyDamage(damage, damageType, newdamage, passive);
|
if (Inventory != NULL) Inventory->ModifyDamage(damage, damageType, newdamage, passive);
|
||||||
}
|
}
|
||||||
|
@ -1710,22 +1705,20 @@ void APowerProtection::EndEffect( )
|
||||||
|
|
||||||
void APowerProtection::ModifyDamage(int damage, FName damageType, int &newdamage, bool passive)
|
void APowerProtection::ModifyDamage(int damage, FName damageType, int &newdamage, bool passive)
|
||||||
{
|
{
|
||||||
static const fixed_t def = FRACUNIT/4;
|
|
||||||
if (passive && damage > 0)
|
if (passive && damage > 0)
|
||||||
{
|
{
|
||||||
const fixed_t *pdf = NULL;
|
int newdam;
|
||||||
DmgFactors *df = GetClass()->DamageFactors;
|
DmgFactors *df = GetClass()->DamageFactors;
|
||||||
if (df != NULL && df->CountUsed() != 0)
|
if (df != NULL && df->CountUsed() != 0)
|
||||||
{
|
{
|
||||||
pdf = df->CheckFactor(damageType);
|
newdam = MIN(0, df->Apply(damageType, damage));
|
||||||
}
|
}
|
||||||
else pdf = &def;
|
else
|
||||||
|
|
||||||
if (pdf != NULL)
|
|
||||||
{
|
{
|
||||||
damage = newdamage = FixedMul(damage, *pdf);
|
newdam = damage / 4;
|
||||||
if (Owner != NULL && *pdf < FRACUNIT) S_Sound(Owner, CHAN_AUTO, ActiveSound, 1.0f, ATTN_NONE);
|
|
||||||
}
|
}
|
||||||
|
if (Owner != NULL && newdam < damage) S_Sound(Owner, CHAN_AUTO, ActiveSound, 1.0f, ATTN_NONE);
|
||||||
|
newdamage = newdam;
|
||||||
}
|
}
|
||||||
if (Inventory != NULL)
|
if (Inventory != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -456,7 +456,7 @@ public:
|
||||||
virtual void AbsorbDamage (int damage, FName damageType, int &newdamage);
|
virtual void AbsorbDamage (int damage, FName damageType, int &newdamage);
|
||||||
|
|
||||||
int AbsorbCount;
|
int AbsorbCount;
|
||||||
fixed_t SavePercent;
|
double SavePercent;
|
||||||
int MaxAbsorb;
|
int MaxAbsorb;
|
||||||
int MaxFullAbsorb;
|
int MaxFullAbsorb;
|
||||||
int BonusCount;
|
int BonusCount;
|
||||||
|
@ -473,7 +473,7 @@ public:
|
||||||
virtual AInventory *CreateCopy (AActor *other);
|
virtual AInventory *CreateCopy (AActor *other);
|
||||||
virtual bool Use (bool pickup);
|
virtual bool Use (bool pickup);
|
||||||
|
|
||||||
fixed_t SavePercent;
|
double SavePercent;
|
||||||
int MaxAbsorb;
|
int MaxAbsorb;
|
||||||
int MaxFullAbsorb;
|
int MaxFullAbsorb;
|
||||||
int SaveAmount;
|
int SaveAmount;
|
||||||
|
@ -488,7 +488,7 @@ public:
|
||||||
virtual AInventory *CreateCopy (AActor *other);
|
virtual AInventory *CreateCopy (AActor *other);
|
||||||
virtual bool Use (bool pickup);
|
virtual bool Use (bool pickup);
|
||||||
|
|
||||||
fixed_t SavePercent; // The default, for when you don't already have armor
|
double SavePercent; // The default, for when you don't already have armor
|
||||||
int MaxSaveAmount;
|
int MaxSaveAmount;
|
||||||
int MaxAbsorb;
|
int MaxAbsorb;
|
||||||
int MaxFullAbsorb;
|
int MaxFullAbsorb;
|
||||||
|
@ -510,8 +510,8 @@ public:
|
||||||
virtual void AbsorbDamage (int damage, FName damageType, int &newdamage);
|
virtual void AbsorbDamage (int damage, FName damageType, int &newdamage);
|
||||||
void DepleteOrDestroy();
|
void DepleteOrDestroy();
|
||||||
|
|
||||||
fixed_t Slots[5];
|
double Slots[5];
|
||||||
fixed_t SlotsIncrement[4];
|
double SlotsIncrement[4];
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool AddArmorToSlot (AActor *actor, int slot, int amount);
|
bool AddArmorToSlot (AActor *actor, int slot, int amount);
|
||||||
|
|
|
@ -146,7 +146,7 @@ void ASoundSequence::PostBeginPlay ()
|
||||||
}
|
}
|
||||||
if (master == NULL)
|
if (master == NULL)
|
||||||
{
|
{
|
||||||
master = Spawn<ASoundSequenceSlot> (0, 0, 0, NO_REPLACE);
|
master = Spawn<ASoundSequenceSlot> ();
|
||||||
master->Sequence = SN_StartSequence (master, slot, 0);
|
master->Sequence = SN_StartSequence (master, slot, 0);
|
||||||
GC::WriteBarrier(master, master->Sequence);
|
GC::WriteBarrier(master, master->Sequence);
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,7 +282,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl
|
||||||
if (harmor->Slots[armorType] > 0 && harmor->SlotsIncrement[armorType] > 0)
|
if (harmor->Slots[armorType] > 0 && harmor->SlotsIncrement[armorType] > 0)
|
||||||
{
|
{
|
||||||
//combine the alpha values
|
//combine the alpha values
|
||||||
alpha = FixedMul(alpha, MIN<fixed_t> (OPAQUE, Scale(harmor->Slots[armorType], OPAQUE, harmor->SlotsIncrement[armorType])));
|
alpha = int(alpha * MIN(1., harmor->Slots[armorType] / harmor->SlotsIncrement[armorType]));
|
||||||
texture = statusBar->Images[image];
|
texture = statusBar->Images[image];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1377,21 +1377,21 @@ class CommandDrawNumber : public CommandDrawString
|
||||||
case ARMORCLASS:
|
case ARMORCLASS:
|
||||||
case SAVEPERCENT:
|
case SAVEPERCENT:
|
||||||
{
|
{
|
||||||
|
double add = 0;
|
||||||
AHexenArmor *harmor = statusBar->CPlayer->mo->FindInventory<AHexenArmor>();
|
AHexenArmor *harmor = statusBar->CPlayer->mo->FindInventory<AHexenArmor>();
|
||||||
if(harmor != NULL)
|
if(harmor != NULL)
|
||||||
{
|
{
|
||||||
num = harmor->Slots[0] + harmor->Slots[1] +
|
add = harmor->Slots[0] + harmor->Slots[1] +
|
||||||
harmor->Slots[2] + harmor->Slots[3] + harmor->Slots[4];
|
harmor->Slots[2] + harmor->Slots[3] + harmor->Slots[4];
|
||||||
}
|
}
|
||||||
//Hexen counts basic armor also so we should too.
|
//Hexen counts basic armor also so we should too.
|
||||||
if(statusBar->armor != NULL)
|
if(statusBar->armor != NULL)
|
||||||
{
|
{
|
||||||
num += FixedMul(statusBar->armor->SavePercent, 100*FRACUNIT);
|
add += statusBar->armor->SavePercent * 100;
|
||||||
}
|
}
|
||||||
if(value == ARMORCLASS)
|
if(value == ARMORCLASS)
|
||||||
num /= (5*FRACUNIT);
|
add /= 5;
|
||||||
else
|
num = int(add);
|
||||||
num >>= FRACBITS;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GLOBALVAR:
|
case GLOBALVAR:
|
||||||
|
@ -2770,18 +2770,19 @@ class CommandDrawBar : public SBarInfoCommand
|
||||||
}
|
}
|
||||||
case SAVEPERCENT:
|
case SAVEPERCENT:
|
||||||
{
|
{
|
||||||
|
double add = 0;
|
||||||
AHexenArmor *harmor = statusBar->CPlayer->mo->FindInventory<AHexenArmor>();
|
AHexenArmor *harmor = statusBar->CPlayer->mo->FindInventory<AHexenArmor>();
|
||||||
if(harmor != NULL)
|
if(harmor != NULL)
|
||||||
{
|
{
|
||||||
value = harmor->Slots[0] + harmor->Slots[1] +
|
add = harmor->Slots[0] + harmor->Slots[1] +
|
||||||
harmor->Slots[2] + harmor->Slots[3] + harmor->Slots[4];
|
harmor->Slots[2] + harmor->Slots[3] + harmor->Slots[4];
|
||||||
}
|
}
|
||||||
//Hexen counts basic armor also so we should too.
|
//Hexen counts basic armor also so we should too.
|
||||||
if(statusBar->armor != NULL)
|
if(statusBar->armor != NULL)
|
||||||
{
|
{
|
||||||
value += FixedMul(statusBar->armor->SavePercent, 100*FRACUNIT);
|
add += statusBar->armor->SavePercent * 100;
|
||||||
}
|
}
|
||||||
value >>= FRACBITS;
|
value = int(add);
|
||||||
max = 100;
|
max = 100;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -313,9 +313,8 @@ static void DrawArmor(ABasicArmor * barmor, AHexenArmor * harmor, int x, int y)
|
||||||
|
|
||||||
if (harmor)
|
if (harmor)
|
||||||
{
|
{
|
||||||
int ac = (harmor->Slots[0] + harmor->Slots[1] + harmor->Slots[2] + harmor->Slots[3] + harmor->Slots[4]);
|
auto ac = (harmor->Slots[0] + harmor->Slots[1] + harmor->Slots[2] + harmor->Slots[3] + harmor->Slots[4]);
|
||||||
ac >>= FRACBITS;
|
ap += int(ac);
|
||||||
ap += ac;
|
|
||||||
|
|
||||||
if (ac)
|
if (ac)
|
||||||
{
|
{
|
||||||
|
|
|
@ -279,7 +279,7 @@ void FMapInfoParser::ParseGameInfo()
|
||||||
if (sc.CheckToken(','))
|
if (sc.CheckToken(','))
|
||||||
{
|
{
|
||||||
sc.MustGetToken(TK_FloatConst);
|
sc.MustGetToken(TK_FloatConst);
|
||||||
gameinfo.Armor2Percent = FLOAT2FIXED(sc.Float);
|
gameinfo.Armor2Percent = sc.Float;
|
||||||
sc.MustGetToken(',');
|
sc.MustGetToken(',');
|
||||||
sc.MustGetToken(TK_StringConst);
|
sc.MustGetToken(TK_StringConst);
|
||||||
gameinfo.ArmorIcon2 = sc.String;
|
gameinfo.ArmorIcon2 = sc.String;
|
||||||
|
|
2
src/gi.h
2
src/gi.h
|
@ -135,7 +135,7 @@ struct gameinfo_t
|
||||||
FString ArmorIcon2;
|
FString ArmorIcon2;
|
||||||
FString PauseSign;
|
FString PauseSign;
|
||||||
FString Endoom;
|
FString Endoom;
|
||||||
fixed_t Armor2Percent;
|
double Armor2Percent;
|
||||||
FString quitSound;
|
FString quitSound;
|
||||||
gameborder_t Border;
|
gameborder_t Border;
|
||||||
double telefogheight;
|
double telefogheight;
|
||||||
|
|
41
src/info.cpp
41
src/info.cpp
|
@ -532,7 +532,7 @@ PClassActor *PClassActor::GetReplacee(bool lookskill)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void PClassActor::SetDamageFactor(FName type, fixed_t factor)
|
void PClassActor::SetDamageFactor(FName type, double factor)
|
||||||
{
|
{
|
||||||
if (DamageFactors == NULL)
|
if (DamageFactors == NULL)
|
||||||
{
|
{
|
||||||
|
@ -593,16 +593,18 @@ void PClassActor::ReplaceClassRef(PClass *oldclass, PClass *newclass)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
fixed_t *DmgFactors::CheckFactor(FName type)
|
int DmgFactors::Apply(FName type, int damage)
|
||||||
{
|
{
|
||||||
fixed_t *pdf = CheckKey(type);
|
auto pdf = CheckKey(type);
|
||||||
if (pdf == NULL && type != NAME_None)
|
if (pdf == NULL && type != NAME_None)
|
||||||
{
|
{
|
||||||
pdf = CheckKey(NAME_None);
|
pdf = CheckKey(NAME_None);
|
||||||
}
|
}
|
||||||
return pdf;
|
if (!pdf) return damage;
|
||||||
|
return int(damage * *pdf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void SummonActor (int command, int command2, FCommandLine argv)
|
static void SummonActor (int command, int command2, FCommandLine argv)
|
||||||
{
|
{
|
||||||
if (CheckCheatmode ())
|
if (CheckCheatmode ())
|
||||||
|
@ -689,32 +691,33 @@ bool DamageTypeDefinition::IgnoreArmor(FName type)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int DamageTypeDefinition::ApplyMobjDamageFactor(int damage, FName type, DmgFactors const * const factors)
|
double DamageTypeDefinition::GetMobjDamageFactor(FName type, DmgFactors const * const factors)
|
||||||
{
|
{
|
||||||
if (factors)
|
if (factors)
|
||||||
{
|
{
|
||||||
// If the actor has named damage factors, look for a specific factor
|
// If the actor has named damage factors, look for a specific factor
|
||||||
fixed_t const *pdf = factors->CheckKey(type);
|
|
||||||
if (pdf) return FixedMul(damage, *pdf); // type specific damage type
|
auto pdf = factors->CheckKey(type);
|
||||||
|
if (pdf) return *pdf; // type specific damage type
|
||||||
|
|
||||||
// If this was nonspecific damage, don't fall back to nonspecific search
|
// If this was nonspecific damage, don't fall back to nonspecific search
|
||||||
if (type == NAME_None) return damage;
|
if (type == NAME_None) return 1.;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this was nonspecific damage, don't fall back to nonspecific search
|
// If this was nonspecific damage, don't fall back to nonspecific search
|
||||||
else if (type == NAME_None)
|
else if (type == NAME_None)
|
||||||
{
|
{
|
||||||
return damage;
|
return 1.;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Normal is unsupplied / 1.0, so there's no difference between modifying and overriding
|
// Normal is unsupplied / 1.0, so there's no difference between modifying and overriding
|
||||||
DamageTypeDefinition *dtd = Get(type);
|
DamageTypeDefinition *dtd = Get(type);
|
||||||
return dtd ? FixedMul(damage, dtd->DefaultFactor) : damage;
|
return dtd ? dtd->DefaultFactor : 1.;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
fixed_t const *pdf = factors->CheckKey(NAME_None);
|
auto pdf = factors->CheckKey(NAME_None);
|
||||||
DamageTypeDefinition *dtd = Get(type);
|
DamageTypeDefinition *dtd = Get(type);
|
||||||
// Here we are looking for modifications to untyped damage
|
// Here we are looking for modifications to untyped damage
|
||||||
// If the calling actor defines untyped damage factor, that is contained in "pdf".
|
// If the calling actor defines untyped damage factor, that is contained in "pdf".
|
||||||
|
@ -722,15 +725,21 @@ int DamageTypeDefinition::ApplyMobjDamageFactor(int damage, FName type, DmgFacto
|
||||||
{
|
{
|
||||||
if (dtd)
|
if (dtd)
|
||||||
{
|
{
|
||||||
if (dtd->ReplaceFactor) return FixedMul(damage, dtd->DefaultFactor); // use default instead of untyped factor
|
if (dtd->ReplaceFactor) return dtd->DefaultFactor; // use default instead of untyped factor
|
||||||
return FixedMul(damage, FixedMul(*pdf, dtd->DefaultFactor)); // use default as modification of untyped factor
|
return *pdf * dtd->DefaultFactor; // use default as modification of untyped factor
|
||||||
}
|
}
|
||||||
return FixedMul(damage, *pdf); // there was no default, so actor default is used
|
return *pdf; // there was no default, so actor default is used
|
||||||
}
|
}
|
||||||
else if (dtd)
|
else if (dtd)
|
||||||
{
|
{
|
||||||
return FixedMul(damage, dtd->DefaultFactor); // implicit untyped factor 1.0 does not need to be applied/replaced explicitly
|
return dtd->DefaultFactor; // implicit untyped factor 1.0 does not need to be applied/replaced explicitly
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return damage;
|
return 1.;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DamageTypeDefinition::ApplyMobjDamageFactor(int damage, FName type, DmgFactors const * const factors)
|
||||||
|
{
|
||||||
|
double factor = GetMobjDamageFactor(type, factors);
|
||||||
|
return int(damage * factor);
|
||||||
}
|
}
|
||||||
|
|
11
src/info.h
11
src/info.h
|
@ -158,9 +158,9 @@ FArchive &operator<< (FArchive &arc, FState *&state);
|
||||||
|
|
||||||
#include "gametype.h"
|
#include "gametype.h"
|
||||||
|
|
||||||
struct DmgFactors : public TMap<FName, fixed_t>
|
struct DmgFactors : public TMap<FName, double>
|
||||||
{
|
{
|
||||||
fixed_t *CheckFactor(FName type);
|
int Apply(FName type, int damage);
|
||||||
};
|
};
|
||||||
typedef TMap<FName, int> PainChanceList;
|
typedef TMap<FName, int> PainChanceList;
|
||||||
|
|
||||||
|
@ -169,20 +169,21 @@ struct DamageTypeDefinition
|
||||||
public:
|
public:
|
||||||
DamageTypeDefinition() { Clear(); }
|
DamageTypeDefinition() { Clear(); }
|
||||||
|
|
||||||
fixed_t DefaultFactor;
|
double DefaultFactor;
|
||||||
bool ReplaceFactor;
|
bool ReplaceFactor;
|
||||||
bool NoArmor;
|
bool NoArmor;
|
||||||
|
|
||||||
void Apply(FName type);
|
void Apply(FName type);
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
DefaultFactor = FRACUNIT;
|
DefaultFactor = 1.;
|
||||||
ReplaceFactor = false;
|
ReplaceFactor = false;
|
||||||
NoArmor = false;
|
NoArmor = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DamageTypeDefinition *Get(FName type);
|
static DamageTypeDefinition *Get(FName type);
|
||||||
static bool IgnoreArmor(FName type);
|
static bool IgnoreArmor(FName type);
|
||||||
|
static double GetMobjDamageFactor(FName type, DmgFactors const * const factors);
|
||||||
static int ApplyMobjDamageFactor(int damage, FName type, DmgFactors const * const factors);
|
static int ApplyMobjDamageFactor(int damage, FName type, DmgFactors const * const factors);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -206,7 +207,7 @@ public:
|
||||||
void BuildDefaults();
|
void BuildDefaults();
|
||||||
void ApplyDefaults(BYTE *defaults);
|
void ApplyDefaults(BYTE *defaults);
|
||||||
void RegisterIDs();
|
void RegisterIDs();
|
||||||
void SetDamageFactor(FName type, fixed_t factor);
|
void SetDamageFactor(FName type, double factor);
|
||||||
void SetPainChance(FName type, int chance);
|
void SetPainChance(FName type, int chance);
|
||||||
size_t PropagateMark();
|
size_t PropagateMark();
|
||||||
void InitializeNativeDefaults();
|
void InitializeNativeDefaults();
|
||||||
|
|
|
@ -715,7 +715,7 @@ void cht_Give (player_t *player, const char *name, int amount)
|
||||||
{
|
{
|
||||||
ABasicArmorPickup *armor = Spawn<ABasicArmorPickup> ();
|
ABasicArmorPickup *armor = Spawn<ABasicArmorPickup> ();
|
||||||
armor->SaveAmount = 100*deh.BlueAC;
|
armor->SaveAmount = 100*deh.BlueAC;
|
||||||
armor->SavePercent = gameinfo.Armor2Percent > 0? gameinfo.Armor2Percent : FRACUNIT/2;
|
armor->SavePercent = gameinfo.Armor2Percent > 0? gameinfo.Armor2Percent : 0.5;
|
||||||
if (!armor->CallTryPickup (player->mo))
|
if (!armor->CallTryPickup (player->mo))
|
||||||
{
|
{
|
||||||
armor->Destroy ();
|
armor->Destroy ();
|
||||||
|
|
|
@ -5080,7 +5080,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
|
||||||
return equippedarmor->MaxAmount;
|
return equippedarmor->MaxAmount;
|
||||||
|
|
||||||
case ARMORINFO_SAVEPERCENT:
|
case ARMORINFO_SAVEPERCENT:
|
||||||
return equippedarmor->SavePercent;
|
return DoubleToACS(equippedarmor->SavePercent);
|
||||||
|
|
||||||
case ARMORINFO_MAXABSORB:
|
case ARMORINFO_MAXABSORB:
|
||||||
return equippedarmor->MaxAbsorb;
|
return equippedarmor->MaxAbsorb;
|
||||||
|
|
|
@ -3317,13 +3317,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Burst)
|
||||||
// base the number of shards on the size of the dead thing, so bigger
|
// base the number of shards on the size of the dead thing, so bigger
|
||||||
// things break up into more shards than smaller things.
|
// things break up into more shards than smaller things.
|
||||||
// An self with _f_radius() 20 and height 64 creates ~40 chunks.
|
// An self with _f_radius() 20 and height 64 creates ~40 chunks.
|
||||||
numChunks = MAX<int> (4, int(self->radius * self->Height));
|
numChunks = MAX<int> (4, int(self->radius * self->Height)/32);
|
||||||
i = (pr_burst.Random2()) % (numChunks/4);
|
i = (pr_burst.Random2()) % (numChunks/4);
|
||||||
for (i = MAX (24, numChunks + i); i >= 0; i--)
|
for (i = MAX (24, numChunks + i); i >= 0; i--)
|
||||||
{
|
{
|
||||||
fixed_t xo = (((pr_burst() - 128)*self->_f_radius()) >> 7);
|
double xo = (pr_burst() - 128) * self->radius / 128;
|
||||||
fixed_t yo = (((pr_burst() - 128)*self->_f_radius()) >> 7);
|
double yo = (pr_burst() - 128) * self->radius / 128;
|
||||||
fixed_t zo = (pr_burst()*self->_f_height() / 255 + self->GetBobOffset());
|
double zo = (pr_burst() * self->Height / 255);
|
||||||
mo = Spawn(chunk, self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
|
mo = Spawn(chunk, self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
|
||||||
|
|
||||||
if (mo)
|
if (mo)
|
||||||
|
|
|
@ -1283,8 +1283,8 @@ static void ParseDamageDefinition(FScanner &sc)
|
||||||
if (sc.Compare("FACTOR"))
|
if (sc.Compare("FACTOR"))
|
||||||
{
|
{
|
||||||
sc.MustGetFloat();
|
sc.MustGetFloat();
|
||||||
dtd.DefaultFactor = FLOAT2FIXED(sc.Float);
|
dtd.DefaultFactor = sc.Float;
|
||||||
if (!dtd.DefaultFactor) dtd.ReplaceFactor = true; // Multiply by 0 yields 0: FixedMul(damage, FixedMul(factor, 0)) is more wasteful than FixedMul(factor, 0)
|
if (dtd.DefaultFactor == 0) dtd.ReplaceFactor = true; // Multiply by 0 yields 0: FixedMul(damage, FixedMul(factor, 0)) is more wasteful than FixedMul(factor, 0)
|
||||||
}
|
}
|
||||||
else if (sc.Compare("REPLACEFACTOR"))
|
else if (sc.Compare("REPLACEFACTOR"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -254,7 +254,7 @@ void HandleDeprecatedFlags(AActor *defaults, PClassActor *info, bool set, int in
|
||||||
defaults->Gravity = set ? 1. / 4 : 1.;
|
defaults->Gravity = set ? 1. / 4 : 1.;
|
||||||
break;
|
break;
|
||||||
case DEPF_FIRERESIST:
|
case DEPF_FIRERESIST:
|
||||||
info->SetDamageFactor(NAME_Fire, set? FRACUNIT/2 : FRACUNIT);
|
info->SetDamageFactor(NAME_Fire, set ? 0.5 : 1.);
|
||||||
break;
|
break;
|
||||||
// the bounce flags will set the compatibility bounce modes to remain compatible
|
// the bounce flags will set the compatibility bounce modes to remain compatible
|
||||||
case DEPF_HERETICBOUNCE:
|
case DEPF_HERETICBOUNCE:
|
||||||
|
@ -322,8 +322,8 @@ bool CheckDeprecatedFlags(const AActor *actor, PClassActor *info, int index)
|
||||||
case DEPF_FIRERESIST:
|
case DEPF_FIRERESIST:
|
||||||
if (info->DamageFactors)
|
if (info->DamageFactors)
|
||||||
{
|
{
|
||||||
fixed_t *df = info->DamageFactors->CheckKey(NAME_Fire);
|
double *df = info->DamageFactors->CheckKey(NAME_Fire);
|
||||||
return df && (*df) == FRACUNIT / 2;
|
return df && (*df) == 0.5;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1229,7 +1229,7 @@ DEFINE_PROPERTY(damagefactor, ZF, Actor)
|
||||||
if (!stricmp(str, "Normal")) dmgType = NAME_None;
|
if (!stricmp(str, "Normal")) dmgType = NAME_None;
|
||||||
else dmgType=str;
|
else dmgType=str;
|
||||||
|
|
||||||
info->SetDamageFactor(dmgType, FLOAT2FIXED(id));
|
info->SetDamageFactor(dmgType, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1639,9 +1639,9 @@ DEFINE_CLASS_PROPERTY(saveamount, I, Armor)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
DEFINE_CLASS_PROPERTY(savepercent, F, Armor)
|
DEFINE_CLASS_PROPERTY(savepercent, F, Armor)
|
||||||
{
|
{
|
||||||
PROP_FIXED_PARM(i, 0);
|
PROP_DOUBLE_PARM(i, 0);
|
||||||
|
|
||||||
i = clamp(i, 0, 100*FRACUNIT)/100;
|
i = clamp(i, 0., 100.)/100.;
|
||||||
// Special case here because this property has to work for 2 unrelated classes
|
// Special case here because this property has to work for 2 unrelated classes
|
||||||
if (info->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup)))
|
if (info->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup)))
|
||||||
{
|
{
|
||||||
|
@ -2793,7 +2793,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, hexenarmor, FFFFF, PlayerPawn)
|
||||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn)));
|
assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn)));
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
PROP_FIXED_PARM(val, i);
|
PROP_DOUBLE_PARM(val, i);
|
||||||
static_cast<PClassPlayerPawn *>(info)->HexenArmor[i] = val;
|
static_cast<PClassPlayerPawn *>(info)->HexenArmor[i] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ ACTOR BasicArmorBonus : Armor native
|
||||||
+Inventory.AUTOACTIVATE
|
+Inventory.AUTOACTIVATE
|
||||||
+Inventory.ALWAYSPICKUP
|
+Inventory.ALWAYSPICKUP
|
||||||
Inventory.MaxAmount 0
|
Inventory.MaxAmount 0
|
||||||
Armor.SavePercent 0.333333
|
Armor.SavePercent 33.335
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue