mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-28 15:02:39 +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();
|
||||
};
|
||||
|
||||
class PPropFlag : public PSymbol
|
||||
{
|
||||
DECLARE_CLASS(PPropFlag, PSymbol);
|
||||
public:
|
||||
PPropFlag(FName name, PField *offset, int bitval);
|
||||
|
||||
PField *Offset;
|
||||
int bitval;
|
||||
|
||||
protected:
|
||||
PPropFlag();
|
||||
};
|
||||
|
||||
// Compound types -----------------------------------------------------------
|
||||
|
||||
class PEnum : public PNamedType
|
||||
|
|
|
@ -123,25 +123,7 @@ DEFINE_FIELD(APowerup, EffectTics)
|
|||
DEFINE_FIELD(APowerup, BlendColor)
|
||||
DEFINE_FIELD(APowerup, Mode)
|
||||
DEFINE_FIELD(APowerup, Strength)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerup :: Tick
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerup::Tick ()
|
||||
{
|
||||
// Powerups cannot exist outside an inventory
|
||||
if (Owner == NULL)
|
||||
{
|
||||
Destroy ();
|
||||
}
|
||||
if (EffectTics > 0 && --EffectTics == 0)
|
||||
{
|
||||
Destroy ();
|
||||
}
|
||||
}
|
||||
DEFINE_FIELD(APowerup, Colormap)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -156,257 +138,8 @@ void APowerup::Serialize(FSerializer &arc)
|
|||
arc("effecttics", EffectTics, def->EffectTics)
|
||||
("blendcolor", BlendColor, def->BlendColor)
|
||||
("mode", Mode, def->Mode)
|
||||
("strength", Strength, def->Strength);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// 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;
|
||||
("strength", Strength, def->Strength)
|
||||
("colormap", Colormap, def->Colormap);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -422,24 +155,6 @@ void APowerup::OwnerDied ()
|
|||
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 ------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLASS(APowerMorph, false, true)
|
||||
|
|
|
@ -11,31 +11,16 @@ class APowerup : public AInventory
|
|||
{
|
||||
DECLARE_CLASS (APowerup, AInventory)
|
||||
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 OwnerDied () override;
|
||||
virtual PalEntry GetBlend () override;
|
||||
virtual bool DrawPowerup (int x, int y) override;
|
||||
|
||||
int EffectTics;
|
||||
PalEntry BlendColor;
|
||||
FNameNoInit Mode;
|
||||
double Strength;
|
||||
int Colormap;
|
||||
|
||||
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 InitAllPowerupEffects(AInventory *item);
|
||||
};
|
||||
|
@ -57,17 +42,6 @@ public:
|
|||
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
|
||||
{
|
||||
DECLARE_CLASS( APowerMorph, APowerup )
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "a_armor.h"
|
||||
#include "r_data/sprites.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "virtual.h"
|
||||
|
||||
static FRandom pr_morphmonst ("MorphMonster");
|
||||
|
||||
|
@ -597,7 +598,12 @@ void EndAllPowerupEffects(AInventory *item)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
@ -617,7 +623,12 @@ void InitAllPowerupEffects(AInventory *item)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
#include "a_ammo.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "stats.h"
|
||||
|
||||
extern FILE *Logfile;
|
||||
|
||||
|
@ -2974,8 +2975,12 @@ void DACSThinker::Serialize(FSerializer &arc)
|
|||
}
|
||||
}
|
||||
|
||||
cycle_t ACSTime;
|
||||
|
||||
void DACSThinker::Tick ()
|
||||
{
|
||||
ACSTime.Reset();
|
||||
ACSTime.Clock();
|
||||
DLevelScript *script = Scripts;
|
||||
|
||||
while (script)
|
||||
|
@ -2993,6 +2998,7 @@ void DACSThinker::Tick ()
|
|||
ACS_StringBuilderStack.Clear();
|
||||
I_Error("Error: %d garbage entries on ACS string builder stack.", size);
|
||||
}
|
||||
ACSTime.Unclock();
|
||||
}
|
||||
|
||||
void DACSThinker::StopScriptsFor (AActor *actor)
|
||||
|
@ -10269,3 +10275,8 @@ CCMD(acsprofile)
|
|||
ShowProfileData(ScriptProfiles, limit, sorter, false);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@ enum
|
|||
DEPF_HEXENBOUNCE,
|
||||
DEPF_DOOMBOUNCE,
|
||||
DEPF_INTERHUBSTRIP,
|
||||
DEPF_NOTRAIL,
|
||||
};
|
||||
|
||||
// Types of old style decorations
|
||||
|
|
|
@ -462,7 +462,7 @@ static FFlagDef PlayerPawnFlagDefs[] =
|
|||
static FFlagDef PowerSpeedFlagDefs[] =
|
||||
{
|
||||
// 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[] =
|
||||
|
@ -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(AWeapon), WeaponFlagDefs, countof(WeaponFlagDefs), 3 },
|
||||
{ &RUNTIME_CLASS_CASTLESS(APlayerPawn), PlayerPawnFlagDefs, countof(PlayerPawnFlagDefs), 3 },
|
||||
{ &RUNTIME_CLASS_CASTLESS(APowerSpeed), PowerSpeedFlagDefs, countof(PowerSpeedFlagDefs), 1 },
|
||||
};
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -354,6 +354,23 @@ void HandleDeprecatedFlags(AActor *defaults, PClassActor *info, bool set, int in
|
|||
break;
|
||||
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;
|
||||
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:
|
||||
break; // silence GCC
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "dobject.h"
|
||||
#include "v_text.h"
|
||||
#include "stats.h"
|
||||
#include "templates.h"
|
||||
|
||||
cycle_t VMCycles[10];
|
||||
int VMCalls[10];
|
||||
|
@ -605,11 +606,16 @@ ADD_STAT(VM)
|
|||
{
|
||||
double added = 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;
|
||||
memmove(&VMCycles[1], &VMCycles[0], 9 * sizeof(cycle_t));
|
||||
memmove(&VMCalls[1], &VMCalls[0], 9 * sizeof(int));
|
||||
VMCycles[0].Reset();
|
||||
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 Name Mode; // Meaning depends on powerup - used for Invulnerability and 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.
|
||||
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,13 +1100,12 @@ class PowerWeaponLevel2 : Powerup
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
class PowerSpeed : Powerup native
|
||||
class PowerSpeed : Powerup
|
||||
{
|
||||
native int SpeedFlags;
|
||||
int NoTrail;
|
||||
|
||||
Property NoTrail: NoTrail;
|
||||
|
||||
const PSF_NOTRAIL = 1;
|
||||
|
||||
|
||||
Default
|
||||
{
|
||||
Powerup.Duration -45;
|
||||
|
@ -917,7 +1135,7 @@ class PowerSpeed : Powerup native
|
|||
if (Owner.player.cheats & CF_PREDICTING)
|
||||
return;
|
||||
|
||||
if (SpeedFlags & PSF_NOTRAIL)
|
||||
if (NoTrail)
|
||||
return;
|
||||
|
||||
if (level.time & 1)
|
||||
|
@ -928,7 +1146,7 @@ class PowerSpeed : Powerup native
|
|||
for (Inventory item = Inv; item != NULL; item = item.Inv)
|
||||
{
|
||||
let sitem = PowerSpeed(item);
|
||||
if (sitem != null && !(sitem.SpeedFlags & PSF_NOTRAIL))
|
||||
if (sitem != null && !NoTrail)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1678,7 +1896,7 @@ class PowerMorph : Powerup native
|
|||
native Class<Actor> MorphFlash, UnMorphFlash;
|
||||
native int MorphStyle;
|
||||
native PlayerInfo MorphedPlayer;
|
||||
|
||||
|
||||
Default
|
||||
{
|
||||
Powerup.Duration -40;
|
||||
|
|
Loading…
Reference in a new issue