mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 23:01:50 +00:00
- scriptified APowerup.
This commit is contained in:
parent
0da1142bdb
commit
75d3f42d4f
11 changed files with 304 additions and 343 deletions
|
@ -639,6 +639,19 @@ protected:
|
||||||
PProperty();
|
PProperty();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PPropFlag : public PSymbol
|
||||||
|
{
|
||||||
|
DECLARE_CLASS(PPropFlag, PSymbol);
|
||||||
|
public:
|
||||||
|
PPropFlag(FName name, PField *offset, int bitval);
|
||||||
|
|
||||||
|
PField *Offset;
|
||||||
|
int bitval;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PPropFlag();
|
||||||
|
};
|
||||||
|
|
||||||
// Compound types -----------------------------------------------------------
|
// Compound types -----------------------------------------------------------
|
||||||
|
|
||||||
class PEnum : public PNamedType
|
class PEnum : public PNamedType
|
||||||
|
|
|
@ -123,25 +123,7 @@ DEFINE_FIELD(APowerup, EffectTics)
|
||||||
DEFINE_FIELD(APowerup, BlendColor)
|
DEFINE_FIELD(APowerup, BlendColor)
|
||||||
DEFINE_FIELD(APowerup, Mode)
|
DEFINE_FIELD(APowerup, Mode)
|
||||||
DEFINE_FIELD(APowerup, Strength)
|
DEFINE_FIELD(APowerup, Strength)
|
||||||
|
DEFINE_FIELD(APowerup, Colormap)
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// APowerup :: Tick
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void APowerup::Tick ()
|
|
||||||
{
|
|
||||||
// Powerups cannot exist outside an inventory
|
|
||||||
if (Owner == NULL)
|
|
||||||
{
|
|
||||||
Destroy ();
|
|
||||||
}
|
|
||||||
if (EffectTics > 0 && --EffectTics == 0)
|
|
||||||
{
|
|
||||||
Destroy ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
@ -156,257 +138,8 @@ void APowerup::Serialize(FSerializer &arc)
|
||||||
arc("effecttics", EffectTics, def->EffectTics)
|
arc("effecttics", EffectTics, def->EffectTics)
|
||||||
("blendcolor", BlendColor, def->BlendColor)
|
("blendcolor", BlendColor, def->BlendColor)
|
||||||
("mode", Mode, def->Mode)
|
("mode", Mode, def->Mode)
|
||||||
("strength", Strength, def->Strength);
|
("strength", Strength, def->Strength)
|
||||||
}
|
("colormap", Colormap, def->Colormap);
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// APowerup :: GetBlend
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
PalEntry APowerup::GetBlend ()
|
|
||||||
{
|
|
||||||
if (isBlinking())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (IsSpecialColormap(BlendColor)) return 0;
|
|
||||||
return BlendColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// APowerup :: InitEffect
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void APowerup::InitEffect ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(APowerup, InitEffect)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(APowerup);
|
|
||||||
self->InitEffect();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void APowerup::CallInitEffect()
|
|
||||||
{
|
|
||||||
IFVIRTUAL(APowerup, InitEffect)
|
|
||||||
{
|
|
||||||
VMValue params[1] = { (DObject*)this };
|
|
||||||
VMFrameStack stack;
|
|
||||||
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
|
|
||||||
}
|
|
||||||
else InitEffect();
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// APowerup :: isBlinking (todo: make this virtual so that child classes can configure their blinking)
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
bool APowerup::isBlinking() const
|
|
||||||
{
|
|
||||||
return (EffectTics <= BLINKTHRESHOLD && (EffectTics & 8) && !(ItemFlags & IF_NOSCREENBLINK));
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(APowerup, isBlinking)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(APowerup);
|
|
||||||
ACTION_RETURN_BOOL(self->isBlinking());
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// APowerup :: DoEffect
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void APowerup::DoEffect ()
|
|
||||||
{
|
|
||||||
if (Owner == NULL || Owner->player == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EffectTics > 0)
|
|
||||||
{
|
|
||||||
int Colormap = GetSpecialColormap(BlendColor);
|
|
||||||
|
|
||||||
if (Colormap != NOFIXEDCOLORMAP)
|
|
||||||
{
|
|
||||||
if (!isBlinking())
|
|
||||||
{
|
|
||||||
Owner->player->fixedcolormap = Colormap;
|
|
||||||
}
|
|
||||||
else if (Owner->player->fixedcolormap == Colormap)
|
|
||||||
{
|
|
||||||
// only unset if the fixed colormap comes from this item
|
|
||||||
Owner->player->fixedcolormap = NOFIXEDCOLORMAP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// APowerup :: EndEffect
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void APowerup::EndEffect ()
|
|
||||||
{
|
|
||||||
int colormap = GetSpecialColormap(BlendColor);
|
|
||||||
|
|
||||||
if (colormap != NOFIXEDCOLORMAP && Owner && Owner->player && Owner->player->fixedcolormap == colormap)
|
|
||||||
{ // only unset if the fixed colormap comes from this item
|
|
||||||
Owner->player->fixedcolormap = NOFIXEDCOLORMAP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(APowerup, EndEffect)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(APowerup);
|
|
||||||
self->EndEffect();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void APowerup::CallEndEffect()
|
|
||||||
{
|
|
||||||
IFVIRTUAL(APowerup, EndEffect)
|
|
||||||
{
|
|
||||||
VMValue params[1] = { (DObject*)this };
|
|
||||||
VMFrameStack stack;
|
|
||||||
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
|
|
||||||
}
|
|
||||||
else EndEffect();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// APowerup :: Destroy
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void APowerup::OnDestroy ()
|
|
||||||
{
|
|
||||||
CallEndEffect ();
|
|
||||||
Super::OnDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// APowerup :: DrawPowerup
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
bool APowerup::DrawPowerup (int x, int y)
|
|
||||||
{
|
|
||||||
if (!Icon.isValid())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isBlinking())
|
|
||||||
{
|
|
||||||
FTexture *pic = TexMan(Icon);
|
|
||||||
screen->DrawTexture (pic, x, y,
|
|
||||||
DTA_HUDRules, HUD_Normal,
|
|
||||||
// DTA_TopOffset, pic->GetHeight()/2,
|
|
||||||
// DTA_LeftOffset, pic->GetWidth()/2,
|
|
||||||
TAG_DONE);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// APowerup :: HandlePickup
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
bool APowerup::HandlePickup (AInventory *item)
|
|
||||||
{
|
|
||||||
if (item->GetClass() == GetClass())
|
|
||||||
{
|
|
||||||
APowerup *power = static_cast<APowerup*>(item);
|
|
||||||
if (power->EffectTics == 0)
|
|
||||||
{
|
|
||||||
power->ItemFlags |= IF_PICKUPGOOD;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Color gets transferred if the new item has an effect.
|
|
||||||
|
|
||||||
// Increase the effect's duration.
|
|
||||||
if (power->ItemFlags & IF_ADDITIVETIME)
|
|
||||||
{
|
|
||||||
EffectTics += power->EffectTics;
|
|
||||||
BlendColor = power->BlendColor;
|
|
||||||
}
|
|
||||||
// If it's not blinking yet, you can't replenish the power unless the
|
|
||||||
// powerup is required to be picked up.
|
|
||||||
else if (EffectTics > BLINKTHRESHOLD && !(power->ItemFlags & IF_ALWAYSPICKUP))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Reset the effect duration.
|
|
||||||
else if (power->EffectTics > EffectTics)
|
|
||||||
{
|
|
||||||
EffectTics = power->EffectTics;
|
|
||||||
BlendColor = power->BlendColor;
|
|
||||||
}
|
|
||||||
power->ItemFlags |= IF_PICKUPGOOD;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// APowerup :: CreateCopy
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
AInventory *APowerup::CreateCopy (AActor *other)
|
|
||||||
{
|
|
||||||
// Get the effective effect time.
|
|
||||||
EffectTics = abs (EffectTics);
|
|
||||||
// Abuse the Owner field to tell the
|
|
||||||
// InitEffect method who started it;
|
|
||||||
// this should be cleared afterwards,
|
|
||||||
// as this powerup instance is not
|
|
||||||
// properly attached to anything yet.
|
|
||||||
Owner = other;
|
|
||||||
// Actually activate the powerup.
|
|
||||||
CallInitEffect ();
|
|
||||||
// Clear the Owner field, unless it was
|
|
||||||
// changed by the activation, for example,
|
|
||||||
// if this instance is a morph powerup;
|
|
||||||
// the flag tells the caller that the
|
|
||||||
// ownership has changed so that they
|
|
||||||
// can properly handle the situation.
|
|
||||||
if (!(ItemFlags & IF_CREATECOPYMOVED))
|
|
||||||
{
|
|
||||||
Owner = NULL;
|
|
||||||
}
|
|
||||||
// All done.
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// APowerup :: CreateTossable
|
|
||||||
//
|
|
||||||
// Powerups are never droppable, even without IF_UNDROPPABLE set.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
AInventory *APowerup::CreateTossable ()
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -422,24 +155,6 @@ void APowerup::OwnerDied ()
|
||||||
Destroy ();
|
Destroy ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Speed Powerup -------------------------------------------------------------
|
|
||||||
|
|
||||||
IMPLEMENT_CLASS(APowerSpeed, false, false)
|
|
||||||
|
|
||||||
DEFINE_FIELD(APowerSpeed, SpeedFlags)
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// APowerSpeed :: Serialize
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void APowerSpeed::Serialize(FSerializer &arc)
|
|
||||||
{
|
|
||||||
Super::Serialize (arc);
|
|
||||||
arc("speedflags", SpeedFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Morph powerup ------------------------------------------------------
|
// Morph powerup ------------------------------------------------------
|
||||||
|
|
||||||
IMPLEMENT_CLASS(APowerMorph, false, true)
|
IMPLEMENT_CLASS(APowerMorph, false, true)
|
||||||
|
|
|
@ -11,31 +11,16 @@ class APowerup : public AInventory
|
||||||
{
|
{
|
||||||
DECLARE_CLASS (APowerup, AInventory)
|
DECLARE_CLASS (APowerup, AInventory)
|
||||||
public:
|
public:
|
||||||
virtual void Tick () override;
|
|
||||||
virtual void OnDestroy() override;
|
|
||||||
virtual bool HandlePickup (AInventory *item) override;
|
|
||||||
virtual AInventory *CreateCopy (AActor *other) override;
|
|
||||||
virtual AInventory *CreateTossable () override;
|
|
||||||
virtual void Serialize(FSerializer &arc) override;
|
virtual void Serialize(FSerializer &arc) override;
|
||||||
virtual void OwnerDied () override;
|
virtual void OwnerDied () override;
|
||||||
virtual PalEntry GetBlend () override;
|
|
||||||
virtual bool DrawPowerup (int x, int y) override;
|
|
||||||
|
|
||||||
int EffectTics;
|
int EffectTics;
|
||||||
PalEntry BlendColor;
|
PalEntry BlendColor;
|
||||||
FNameNoInit Mode;
|
FNameNoInit Mode;
|
||||||
double Strength;
|
double Strength;
|
||||||
|
int Colormap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void InitEffect ();
|
|
||||||
virtual void DoEffect () override;
|
|
||||||
virtual void EndEffect ();
|
|
||||||
bool isBlinking() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void CallInitEffect();
|
|
||||||
void CallEndEffect();
|
|
||||||
|
|
||||||
friend void EndAllPowerupEffects(AInventory *item);
|
friend void EndAllPowerupEffects(AInventory *item);
|
||||||
friend void InitAllPowerupEffects(AInventory *item);
|
friend void InitAllPowerupEffects(AInventory *item);
|
||||||
};
|
};
|
||||||
|
@ -57,17 +42,6 @@ public:
|
||||||
double Strength; // Meaning depends on powerup - currently used only by Invisibility
|
double Strength; // Meaning depends on powerup - currently used only by Invisibility
|
||||||
};
|
};
|
||||||
|
|
||||||
class APowerSpeed : public APowerup
|
|
||||||
{
|
|
||||||
DECLARE_CLASS (APowerSpeed, APowerup)
|
|
||||||
protected:
|
|
||||||
virtual void Serialize(FSerializer &arc) override;
|
|
||||||
public:
|
|
||||||
int SpeedFlags;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PSF_NOTRAIL 1
|
|
||||||
|
|
||||||
class APowerMorph : public APowerup
|
class APowerMorph : public APowerup
|
||||||
{
|
{
|
||||||
DECLARE_CLASS( APowerMorph, APowerup )
|
DECLARE_CLASS( APowerMorph, APowerup )
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "a_armor.h"
|
#include "a_armor.h"
|
||||||
#include "r_data/sprites.h"
|
#include "r_data/sprites.h"
|
||||||
#include "g_levellocals.h"
|
#include "g_levellocals.h"
|
||||||
|
#include "virtual.h"
|
||||||
|
|
||||||
static FRandom pr_morphmonst ("MorphMonster");
|
static FRandom pr_morphmonst ("MorphMonster");
|
||||||
|
|
||||||
|
@ -597,7 +598,12 @@ void EndAllPowerupEffects(AInventory *item)
|
||||||
{
|
{
|
||||||
if (item->IsKindOf(RUNTIME_CLASS(APowerup)))
|
if (item->IsKindOf(RUNTIME_CLASS(APowerup)))
|
||||||
{
|
{
|
||||||
static_cast<APowerup *>(item)->CallEndEffect();
|
IFVIRTUALPTR(item, APowerup, EndEffect)
|
||||||
|
{
|
||||||
|
VMValue params[1] = { item };
|
||||||
|
VMFrameStack stack;
|
||||||
|
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
item = item->Inventory;
|
item = item->Inventory;
|
||||||
}
|
}
|
||||||
|
@ -617,7 +623,12 @@ void InitAllPowerupEffects(AInventory *item)
|
||||||
{
|
{
|
||||||
if (item->IsKindOf(RUNTIME_CLASS(APowerup)))
|
if (item->IsKindOf(RUNTIME_CLASS(APowerup)))
|
||||||
{
|
{
|
||||||
static_cast<APowerup *>(item)->CallInitEffect();
|
IFVIRTUALPTR(item, APowerup, InitEffect)
|
||||||
|
{
|
||||||
|
VMValue params[1] = { item };
|
||||||
|
VMFrameStack stack;
|
||||||
|
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
item = item->Inventory;
|
item = item->Inventory;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,7 @@
|
||||||
#include "a_ammo.h"
|
#include "a_ammo.h"
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
#include "g_levellocals.h"
|
#include "g_levellocals.h"
|
||||||
|
#include "stats.h"
|
||||||
|
|
||||||
extern FILE *Logfile;
|
extern FILE *Logfile;
|
||||||
|
|
||||||
|
@ -2974,8 +2975,12 @@ void DACSThinker::Serialize(FSerializer &arc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cycle_t ACSTime;
|
||||||
|
|
||||||
void DACSThinker::Tick ()
|
void DACSThinker::Tick ()
|
||||||
{
|
{
|
||||||
|
ACSTime.Reset();
|
||||||
|
ACSTime.Clock();
|
||||||
DLevelScript *script = Scripts;
|
DLevelScript *script = Scripts;
|
||||||
|
|
||||||
while (script)
|
while (script)
|
||||||
|
@ -2993,6 +2998,7 @@ void DACSThinker::Tick ()
|
||||||
ACS_StringBuilderStack.Clear();
|
ACS_StringBuilderStack.Clear();
|
||||||
I_Error("Error: %d garbage entries on ACS string builder stack.", size);
|
I_Error("Error: %d garbage entries on ACS string builder stack.", size);
|
||||||
}
|
}
|
||||||
|
ACSTime.Unclock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DACSThinker::StopScriptsFor (AActor *actor)
|
void DACSThinker::StopScriptsFor (AActor *actor)
|
||||||
|
@ -10269,3 +10275,8 @@ CCMD(acsprofile)
|
||||||
ShowProfileData(ScriptProfiles, limit, sorter, false);
|
ShowProfileData(ScriptProfiles, limit, sorter, false);
|
||||||
ShowProfileData(FuncProfiles, limit, sorter, true);
|
ShowProfileData(FuncProfiles, limit, sorter, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ADD_STAT(ACS)
|
||||||
|
{
|
||||||
|
return FStringf("ACS time: %f ms", ACSTime.TimeMS());
|
||||||
|
}
|
||||||
|
|
|
@ -63,16 +63,6 @@ inline uint32 MakeSpecialColormap(int index)
|
||||||
return index | SPECIALCOLORMAP_MASK;
|
return index | SPECIALCOLORMAP_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsSpecialColormap(uint32 map)
|
|
||||||
{
|
|
||||||
return (map & 0xFFFF0000) == SPECIALCOLORMAP_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int GetSpecialColormap(int blend)
|
|
||||||
{
|
|
||||||
return IsSpecialColormap(blend) ? blend & 0xFFFF : NOFIXEDCOLORMAP;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b2);
|
int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b2);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,7 @@ enum
|
||||||
DEPF_HEXENBOUNCE,
|
DEPF_HEXENBOUNCE,
|
||||||
DEPF_DOOMBOUNCE,
|
DEPF_DOOMBOUNCE,
|
||||||
DEPF_INTERHUBSTRIP,
|
DEPF_INTERHUBSTRIP,
|
||||||
|
DEPF_NOTRAIL,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Types of old style decorations
|
// Types of old style decorations
|
||||||
|
|
|
@ -462,7 +462,7 @@ static FFlagDef PlayerPawnFlagDefs[] =
|
||||||
static FFlagDef PowerSpeedFlagDefs[] =
|
static FFlagDef PowerSpeedFlagDefs[] =
|
||||||
{
|
{
|
||||||
// PowerSpeed flags
|
// PowerSpeed flags
|
||||||
DEFINE_FLAG(PSF, NOTRAIL, APowerSpeed, SpeedFlags),
|
DEFINE_DEPRECATED_FLAG(NOTRAIL),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct FFlagList { const PClass * const *Type; FFlagDef *Defs; int NumDefs; int Use; } FlagLists[] =
|
static const struct FFlagList { const PClass * const *Type; FFlagDef *Defs; int NumDefs; int Use; } FlagLists[] =
|
||||||
|
@ -473,7 +473,6 @@ static const struct FFlagList { const PClass * const *Type; FFlagDef *Defs; int
|
||||||
{ &RUNTIME_CLASS_CASTLESS(AInventory), InventoryFlagDefs, countof(InventoryFlagDefs), 3 },
|
{ &RUNTIME_CLASS_CASTLESS(AInventory), InventoryFlagDefs, countof(InventoryFlagDefs), 3 },
|
||||||
{ &RUNTIME_CLASS_CASTLESS(AWeapon), WeaponFlagDefs, countof(WeaponFlagDefs), 3 },
|
{ &RUNTIME_CLASS_CASTLESS(AWeapon), WeaponFlagDefs, countof(WeaponFlagDefs), 3 },
|
||||||
{ &RUNTIME_CLASS_CASTLESS(APlayerPawn), PlayerPawnFlagDefs, countof(PlayerPawnFlagDefs), 3 },
|
{ &RUNTIME_CLASS_CASTLESS(APlayerPawn), PlayerPawnFlagDefs, countof(PlayerPawnFlagDefs), 3 },
|
||||||
{ &RUNTIME_CLASS_CASTLESS(APowerSpeed), PowerSpeedFlagDefs, countof(PowerSpeedFlagDefs), 1 },
|
|
||||||
};
|
};
|
||||||
#define NUM_FLAG_LISTS (countof(FlagLists))
|
#define NUM_FLAG_LISTS (countof(FlagLists))
|
||||||
|
|
||||||
|
@ -548,6 +547,12 @@ FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2, bo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle that lone PowerSpeed flag - this should be more generalized but it's just this one flag and unlikely to become more so an explicit check will do.
|
||||||
|
if ((!stricmp(part1, "NOTRAIL") && !strict) || (!stricmp(part1, "POWERSPEED") && !stricmp(part2, "NOTRAIL")))
|
||||||
|
{
|
||||||
|
return &PowerSpeedFlagDefs[0];
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -354,6 +354,23 @@ void HandleDeprecatedFlags(AActor *defaults, PClassActor *info, bool set, int in
|
||||||
break;
|
break;
|
||||||
case DEPF_INTERHUBSTRIP: // Old system was 0 or 1, so if the flag is cleared, assume 1.
|
case DEPF_INTERHUBSTRIP: // Old system was 0 or 1, so if the flag is cleared, assume 1.
|
||||||
static_cast<AInventory*>(defaults)->InterHubAmount = set ? 0 : 1;
|
static_cast<AInventory*>(defaults)->InterHubAmount = set ? 0 : 1;
|
||||||
|
break;
|
||||||
|
case DEPF_NOTRAIL:
|
||||||
|
{
|
||||||
|
FString propname = "@property@powerspeed.notrail";
|
||||||
|
FName name(propname, true);
|
||||||
|
if (name != NAME_None)
|
||||||
|
{
|
||||||
|
auto propp = dyn_cast<PProperty>(info->Symbols.FindSymbol(name, true));
|
||||||
|
if (propp != nullptr)
|
||||||
|
{
|
||||||
|
*((char*)defaults + propp->Variables[0]->Offset) = set ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break; // silence GCC
|
break; // silence GCC
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "dobject.h"
|
#include "dobject.h"
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
|
#include "templates.h"
|
||||||
|
|
||||||
cycle_t VMCycles[10];
|
cycle_t VMCycles[10];
|
||||||
int VMCalls[10];
|
int VMCalls[10];
|
||||||
|
@ -605,11 +606,16 @@ ADD_STAT(VM)
|
||||||
{
|
{
|
||||||
double added = 0;
|
double added = 0;
|
||||||
int addedc = 0;
|
int addedc = 0;
|
||||||
for (auto d : VMCycles) added += d.TimeMS();
|
double peak = 0;
|
||||||
|
for (auto d : VMCycles)
|
||||||
|
{
|
||||||
|
added += d.TimeMS();
|
||||||
|
peak = MAX<double>(peak, d.TimeMS());
|
||||||
|
}
|
||||||
for (auto d : VMCalls) addedc += d;
|
for (auto d : VMCalls) addedc += d;
|
||||||
memmove(&VMCycles[1], &VMCycles[0], 9 * sizeof(cycle_t));
|
memmove(&VMCycles[1], &VMCycles[0], 9 * sizeof(cycle_t));
|
||||||
memmove(&VMCalls[1], &VMCalls[0], 9 * sizeof(int));
|
memmove(&VMCalls[1], &VMCalls[0], 9 * sizeof(int));
|
||||||
VMCycles[0].Reset();
|
VMCycles[0].Reset();
|
||||||
VMCalls[0] = 0;
|
VMCalls[0] = 0;
|
||||||
return FStringf("VM time in last 10 tics: %f ms, %d calls", added, addedc);
|
return FStringf("VM time in last 10 tics: %f ms, %d calls, peak = %f ms", added, addedc, peak);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,232 @@ class Powerup : Inventory native
|
||||||
native color BlendColor;
|
native color BlendColor;
|
||||||
native Name Mode; // Meaning depends on powerup - used for Invulnerability and Invisibility
|
native Name Mode; // Meaning depends on powerup - used for Invulnerability and Invisibility
|
||||||
native double Strength; // Meaning depends on powerup - currently used only by Invisibility
|
native double Strength; // Meaning depends on powerup - currently used only by Invisibility
|
||||||
|
native int Colormap;
|
||||||
|
const SPECIALCOLORMAP_MASK = 0x00b60000;
|
||||||
|
|
||||||
// Note, that while this is an inventory flag, it only has meaning on an active powerup.
|
// Note, that while this is an inventory flag, it only has meaning on an active powerup.
|
||||||
override bool GetNoTeleportFreeze() { return bNoTeleportFreeze; }
|
override bool GetNoTeleportFreeze()
|
||||||
|
{
|
||||||
|
return bNoTeleportFreeze;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// APowerup :: Tick
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
override void Tick ()
|
||||||
|
{
|
||||||
|
// Powerups cannot exist outside an inventory
|
||||||
|
if (Owner == NULL)
|
||||||
|
{
|
||||||
|
Destroy ();
|
||||||
|
}
|
||||||
|
if (EffectTics > 0 && --EffectTics == 0)
|
||||||
|
{
|
||||||
|
Destroy ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// APowerup :: HandlePickup
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
override bool HandlePickup (Inventory item)
|
||||||
|
{
|
||||||
|
if (item.GetClass() == GetClass())
|
||||||
|
{
|
||||||
|
let power = Powerup(item);
|
||||||
|
if (power.EffectTics == 0)
|
||||||
|
{
|
||||||
|
power.bPickupGood = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Color gets transferred if the new item has an effect.
|
||||||
|
|
||||||
|
// Increase the effect's duration.
|
||||||
|
if (power.bAdditiveTime)
|
||||||
|
{
|
||||||
|
EffectTics += power.EffectTics;
|
||||||
|
BlendColor = power.BlendColor;
|
||||||
|
}
|
||||||
|
// If it's not blinking yet, you can't replenish the power unless the
|
||||||
|
// powerup is required to be picked up.
|
||||||
|
else if (EffectTics > BLINKTHRESHOLD && !power.bAlwaysPickup)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Reset the effect duration.
|
||||||
|
else if (power.EffectTics > EffectTics)
|
||||||
|
{
|
||||||
|
EffectTics = power.EffectTics;
|
||||||
|
BlendColor = power.BlendColor;
|
||||||
|
}
|
||||||
|
power.bPickupGood = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// APowerup :: CreateCopy
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
override Inventory CreateCopy (Actor other)
|
||||||
|
{
|
||||||
|
// Get the effective effect time.
|
||||||
|
EffectTics = abs (EffectTics);
|
||||||
|
// Abuse the Owner field to tell the
|
||||||
|
// InitEffect method who started it;
|
||||||
|
// this should be cleared afterwards,
|
||||||
|
// as this powerup instance is not
|
||||||
|
// properly attached to anything yet.
|
||||||
|
Owner = other;
|
||||||
|
// Actually activate the powerup.
|
||||||
|
InitEffect ();
|
||||||
|
// Clear the Owner field, unless it was
|
||||||
|
// changed by the activation, for example,
|
||||||
|
// if this instance is a morph powerup;
|
||||||
|
// the flag tells the caller that the
|
||||||
|
// ownership has changed so that they
|
||||||
|
// can properly handle the situation.
|
||||||
|
if (!bCreateCopyMoved)
|
||||||
|
{
|
||||||
|
Owner = NULL;
|
||||||
|
}
|
||||||
|
// All done.
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// APowerup :: CreateTossable
|
||||||
|
//
|
||||||
|
// Powerups are never droppable, even without IF_UNDROPPABLE set.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
override Inventory CreateTossable ()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// APowerup :: InitEffect
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
virtual void InitEffect()
|
||||||
|
{
|
||||||
|
// initialize this only once instead of recalculating repeatedly.
|
||||||
|
Colormap = ((BlendColor & 0xFFFF0000) == SPECIALCOLORMAP_MASK)? BlendColor & 0xffff : PlayerInfo.NOFIXEDCOLORMAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// APowerup :: DoEffect
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
override void DoEffect ()
|
||||||
|
{
|
||||||
|
if (Owner == NULL || Owner.player == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EffectTics > 0)
|
||||||
|
{
|
||||||
|
if (Colormap != PlayerInfo.NOFIXEDCOLORMAP)
|
||||||
|
{
|
||||||
|
if (!isBlinking())
|
||||||
|
{
|
||||||
|
Owner.player.fixedcolormap = Colormap;
|
||||||
|
}
|
||||||
|
else if (Owner.player.fixedcolormap == Colormap)
|
||||||
|
{
|
||||||
|
// only unset if the fixed colormap comes from this item
|
||||||
|
Owner.player.fixedcolormap = PlayerInfo.NOFIXEDCOLORMAP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// APowerup :: EndEffect
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
virtual void EndEffect ()
|
||||||
|
{
|
||||||
|
if (colormap != PlayerInfo.NOFIXEDCOLORMAP && Owner && Owner.player && Owner.player.fixedcolormap == colormap)
|
||||||
|
{ // only unset if the fixed colormap comes from this item
|
||||||
|
Owner.player.fixedcolormap = PlayerInfo.NOFIXEDCOLORMAP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// APowerup :: Destroy
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
override void OnDestroy ()
|
||||||
|
{
|
||||||
|
EndEffect ();
|
||||||
|
Super.OnDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// APowerup :: GetBlend
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
override color GetBlend ()
|
||||||
|
{
|
||||||
|
if (Colormap != Player.NOFIXEDCOLORMAP) return 0;
|
||||||
|
if (isBlinking()) return 0;
|
||||||
|
return BlendColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// APowerup :: DrawPowerup
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
override bool DrawPowerup (int x, int y)
|
||||||
|
{
|
||||||
|
if (!Icon.isValid())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!isBlinking())
|
||||||
|
{
|
||||||
|
screen.DrawHUDTexture(Icon, x, y);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// APowerup :: isBlinking
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
virtual bool isBlinking()
|
||||||
|
{
|
||||||
|
return (EffectTics <= BLINKTHRESHOLD && (EffectTics & 8) && !bNoScreenBlink);
|
||||||
|
}
|
||||||
|
|
||||||
native virtual void InitEffect();
|
|
||||||
native virtual void EndEffect();
|
|
||||||
native bool isBlinking();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -881,12 +1100,11 @@ class PowerWeaponLevel2 : Powerup
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
class PowerSpeed : Powerup native
|
class PowerSpeed : Powerup
|
||||||
{
|
{
|
||||||
native int SpeedFlags;
|
int NoTrail;
|
||||||
|
|
||||||
const PSF_NOTRAIL = 1;
|
|
||||||
|
|
||||||
|
Property NoTrail: NoTrail;
|
||||||
|
|
||||||
Default
|
Default
|
||||||
{
|
{
|
||||||
|
@ -917,7 +1135,7 @@ class PowerSpeed : Powerup native
|
||||||
if (Owner.player.cheats & CF_PREDICTING)
|
if (Owner.player.cheats & CF_PREDICTING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (SpeedFlags & PSF_NOTRAIL)
|
if (NoTrail)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (level.time & 1)
|
if (level.time & 1)
|
||||||
|
@ -928,7 +1146,7 @@ class PowerSpeed : Powerup native
|
||||||
for (Inventory item = Inv; item != NULL; item = item.Inv)
|
for (Inventory item = Inv; item != NULL; item = item.Inv)
|
||||||
{
|
{
|
||||||
let sitem = PowerSpeed(item);
|
let sitem = PowerSpeed(item);
|
||||||
if (sitem != null && !(sitem.SpeedFlags & PSF_NOTRAIL))
|
if (sitem != null && !NoTrail)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue