mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-28 23:11:58 +00:00
- eliminated the native PowerupGiver class.
- scriptified the respawn invulnerability code into a virtual OnRespawn function for PlayerPawn so that custom effects can be implemented.
This commit is contained in:
parent
98f9219334
commit
232b64d332
17 changed files with 138 additions and 130 deletions
|
@ -456,9 +456,7 @@ size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld, bool s
|
|||
auto def = GetDefaultByType(p);
|
||||
if (def != nullptr)
|
||||
{
|
||||
def->Class = p;
|
||||
def->DObject::PointerSubstitution(old, notOld);
|
||||
def->Class = nullptr; // reset pointer. Defaults should not have a valid class pointer.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,7 +208,6 @@ enum EObjectFlags
|
|||
OF_SerialSuccess = 1 << 9, // For debugging Serialize() calls
|
||||
OF_Sentinel = 1 << 10, // Object is serving as the sentinel in a ring list
|
||||
OF_Transient = 1 << 11, // Object should not be archived (references to it will be nulled on disk)
|
||||
OF_SuperCall = 1 << 12, // A super call from the VM is about to be performed
|
||||
};
|
||||
|
||||
template<class T> class TObjPtr;
|
||||
|
@ -453,6 +452,8 @@ public:
|
|||
|
||||
void *ScriptVar(FName field, PType *type);
|
||||
|
||||
protected:
|
||||
|
||||
public:
|
||||
DObject ();
|
||||
DObject (PClass *inClass);
|
||||
|
|
|
@ -1782,6 +1782,18 @@ PClassPointer::PClassPointer(PClass *restrict)
|
|||
else mDescriptiveName = "ClassPointer";
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClassPointer - isCompatible
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool PClassPointer::isCompatible(PType *type)
|
||||
{
|
||||
auto other = dyn_cast<PClassPointer>(type);
|
||||
return (other != nullptr && other->ClassRestriction->IsDescendantOf(ClassRestriction));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClassPointer :: IsMatch
|
||||
|
@ -3333,6 +3345,20 @@ void PClass::InitializeDefaults()
|
|||
{
|
||||
assert(Defaults == NULL);
|
||||
Defaults = (BYTE *)M_Malloc(Size);
|
||||
|
||||
// run the constructor on the defaults to set the vtbl pointer which is needed to run class-aware functions on them.
|
||||
// bSerialOverride prevents linking into the thinker chains.
|
||||
auto s = DThinker::bSerialOverride;
|
||||
DThinker::bSerialOverride = true;
|
||||
ConstructNative(Defaults);
|
||||
DThinker::bSerialOverride = s;
|
||||
// We must unlink the defaults from the class list because it's just a static block of data to the engine.
|
||||
DObject *optr = (DObject*)Defaults;
|
||||
GC::Root = optr->ObjNext;
|
||||
optr->ObjNext = nullptr;
|
||||
optr->SetClass(this);
|
||||
|
||||
|
||||
if (ParentClass->Defaults != NULL)
|
||||
{
|
||||
memcpy(Defaults, ParentClass->Defaults, ParentClass->Size);
|
||||
|
|
|
@ -599,6 +599,7 @@ public:
|
|||
|
||||
// this is only here to block PPointer's implementation
|
||||
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override {}
|
||||
bool isCompatible(PType *type);
|
||||
|
||||
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
||||
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
||||
|
|
|
@ -1263,10 +1263,11 @@ void G_PlayerFinishLevel (int player, EFinishLevelType mode, int flags)
|
|||
|
||||
// Strip all current powers, unless moving in a hub and the power is okay to keep.
|
||||
item = p->mo->Inventory;
|
||||
auto ptype = PClass::FindActor(NAME_Powerup);
|
||||
while (item != NULL)
|
||||
{
|
||||
next = item->Inventory;
|
||||
if (item->IsKindOf (RUNTIME_CLASS(APowerup)))
|
||||
if (item->IsKindOf (ptype))
|
||||
{
|
||||
if (deathmatch || ((mode != FINISH_SameHub || !(item->ItemFlags & IF_HUBPOWER))
|
||||
&& !(item->ItemFlags & IF_PERSISTENTPOWER))) // Keep persistent powers in non-deathmatch games
|
||||
|
|
|
@ -48,35 +48,6 @@ IMPLEMENT_CLASS(APowerup, false, false)
|
|||
// Powerup-Giver -------------------------------------------------------------
|
||||
|
||||
|
||||
IMPLEMENT_CLASS(APowerupGiver, false, true)
|
||||
|
||||
IMPLEMENT_POINTERS_START(APowerupGiver)
|
||||
IMPLEMENT_POINTER(PowerupType)
|
||||
IMPLEMENT_POINTERS_END
|
||||
|
||||
DEFINE_FIELD(APowerupGiver, PowerupType)
|
||||
DEFINE_FIELD(APowerupGiver, EffectTics)
|
||||
DEFINE_FIELD(APowerupGiver, BlendColor)
|
||||
DEFINE_FIELD(APowerupGiver, Mode)
|
||||
DEFINE_FIELD(APowerupGiver, Strength)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerupGiver :: Serialize
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerupGiver::Serialize(FSerializer &arc)
|
||||
{
|
||||
Super::Serialize (arc);
|
||||
auto def = (APowerupGiver*)GetDefault();
|
||||
arc("poweruptype", PowerupType, def->PowerupType)
|
||||
("effecttics", EffectTics, def->EffectTics)
|
||||
("blendcolor", BlendColor, def->BlendColor)
|
||||
("mode", Mode, def->Mode)
|
||||
("strength", Strength, def->Strength);
|
||||
}
|
||||
|
||||
// Powerup -------------------------------------------------------------------
|
||||
|
||||
DEFINE_FIELD(APowerup, EffectTics)
|
||||
|
@ -101,4 +72,3 @@ void APowerup::Serialize(FSerializer &arc)
|
|||
("strength", Strength, def->Strength)
|
||||
("colormap", Colormap, def->Colormap);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,22 +23,4 @@ public:
|
|||
friend void EndAllPowerupEffects(AInventory *item);
|
||||
friend void InitAllPowerupEffects(AInventory *item);
|
||||
};
|
||||
|
||||
// An artifact is an item that gives the player a powerup when activated.
|
||||
class APowerupGiver : public AInventory
|
||||
{
|
||||
DECLARE_CLASS (APowerupGiver, AInventory)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
virtual void Serialize(FSerializer &arc) override;
|
||||
|
||||
|
||||
PClassActor *PowerupType;
|
||||
int EffectTics; // Non-0 to override the powerup's default tics
|
||||
PalEntry BlendColor; // Non-0 to override the powerup's default blend
|
||||
FNameNoInit Mode; // Meaning depends on powerup - used for Invulnerability and Invisibility
|
||||
double Strength; // Meaning depends on powerup - currently used only by Invisibility
|
||||
};
|
||||
|
||||
|
||||
#endif //__A_ARTIFACTS_H__
|
||||
|
|
|
@ -594,11 +594,12 @@ bool P_MorphedDeath(AActor *actor, AActor **morphed, int *morphedstyle, int *mor
|
|||
|
||||
void EndAllPowerupEffects(AInventory *item)
|
||||
{
|
||||
auto ptype = PClass::FindActor(NAME_Powerup);
|
||||
while (item != NULL)
|
||||
{
|
||||
if (item->IsKindOf(RUNTIME_CLASS(APowerup)))
|
||||
if (item->IsKindOf(ptype))
|
||||
{
|
||||
IFVIRTUALPTR(item, APowerup, EndEffect)
|
||||
IFVIRTUALPTRNAME(item, NAME_Powerup, EndEffect)
|
||||
{
|
||||
VMValue params[1] = { item };
|
||||
VMFrameStack stack;
|
||||
|
@ -619,11 +620,12 @@ void EndAllPowerupEffects(AInventory *item)
|
|||
|
||||
void InitAllPowerupEffects(AInventory *item)
|
||||
{
|
||||
auto ptype = PClass::FindActor(NAME_Powerup);
|
||||
while (item != NULL)
|
||||
{
|
||||
if (item->IsKindOf(RUNTIME_CLASS(APowerup)))
|
||||
if (item->IsKindOf(ptype))
|
||||
{
|
||||
IFVIRTUALPTR(item, APowerup, InitEffect)
|
||||
IFVIRTUALPTRNAME(item, NAME_Powerup, EndEffect)
|
||||
{
|
||||
VMValue params[1] = { item };
|
||||
VMFrameStack stack;
|
||||
|
|
|
@ -1158,10 +1158,10 @@ class CommandDrawNumber : public CommandDrawString
|
|||
if(!parenthesized || !sc.CheckToken(TK_StringConst))
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
inventoryItem = PClass::FindActor(sc.String);
|
||||
if(inventoryItem == NULL || !RUNTIME_CLASS(APowerupGiver)->IsAncestorOf(inventoryItem))
|
||||
if(inventoryItem == NULL || !PClass::FindActor(NAME_PowerupGiver)->IsAncestorOf(inventoryItem))
|
||||
{
|
||||
sc.ScriptMessage("'%s' is not a type of PowerupGiver.", sc.String);
|
||||
inventoryItem = RUNTIME_CLASS(APowerupGiver);
|
||||
inventoryItem = PClass::FindActor(NAME_PowerupGiver);
|
||||
}
|
||||
|
||||
if(parenthesized) sc.MustGetToken(')');
|
||||
|
@ -1433,11 +1433,14 @@ class CommandDrawNumber : public CommandDrawString
|
|||
break;
|
||||
case POWERUPTIME:
|
||||
{
|
||||
//Get the PowerupType and check to see if the player has any in inventory.
|
||||
PClassActor* powerupType = ((APowerupGiver*) GetDefaultByType(inventoryItem))->PowerupType;
|
||||
APowerup* powerup = (APowerup*) statusBar->CPlayer->mo->FindInventory(powerupType);
|
||||
if(powerup != NULL)
|
||||
num = powerup->EffectTics / TICRATE + 1;
|
||||
// num = statusBar.CPlayer.mo.GetEffectTicsForItem(inventoryItem) / TICRATE + 1;
|
||||
static VMFunction *func = nullptr;
|
||||
if (func == nullptr) func = static_cast<PFunction*>(RUNTIME_CLASS(APlayerPawn)->Symbols.FindSymbol("GetEffectTicsForItem", false))->Variants[0].Implementation;
|
||||
VMValue params[] = { statusBar->CPlayer->mo, inventoryItem };
|
||||
int retv;
|
||||
VMReturn ret(&retv);
|
||||
GlobalVMStack.Call(func, params, 2, &ret, 1);
|
||||
num = retv / TICRATE + 1;
|
||||
break;
|
||||
}
|
||||
case INVENTORY:
|
||||
|
@ -2655,10 +2658,10 @@ class CommandDrawBar : public SBarInfoCommand
|
|||
if(!parenthesized || !sc.CheckToken(TK_StringConst))
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
data.inventoryItem = PClass::FindActor(sc.String);
|
||||
if(data.inventoryItem == NULL || !RUNTIME_CLASS(APowerupGiver)->IsAncestorOf(data.inventoryItem))
|
||||
if(data.inventoryItem == NULL || !PClass::FindActor(NAME_PowerupGiver)->IsAncestorOf(data.inventoryItem))
|
||||
{
|
||||
sc.ScriptMessage("'%s' is not a type of PowerupGiver.", sc.String);
|
||||
data.inventoryItem = RUNTIME_CLASS(APowerupGiver);
|
||||
data.inventoryItem = PClass::FindActor(NAME_PowerupGiver);
|
||||
}
|
||||
|
||||
if(parenthesized) sc.MustGetToken(')');
|
||||
|
@ -2822,18 +2825,16 @@ class CommandDrawBar : public SBarInfoCommand
|
|||
break;
|
||||
case POWERUPTIME:
|
||||
{
|
||||
//Get the PowerupType and check to see if the player has any in inventory.
|
||||
APowerupGiver *powerupGiver = (APowerupGiver*) GetDefaultByType(data.inventoryItem);
|
||||
PClassActor *powerupType = powerupGiver->PowerupType;
|
||||
APowerup *powerup = (APowerup*) statusBar->CPlayer->mo->FindInventory(powerupType);
|
||||
if(powerup != NULL && powerupType != NULL && powerupGiver != NULL)
|
||||
{
|
||||
value = powerup->EffectTics + 1;
|
||||
if(powerupGiver->EffectTics == 0) //if 0 we need to get the default from the powerup
|
||||
max = ((APowerup*) GetDefaultByType(powerupType))->EffectTics + 1;
|
||||
else
|
||||
max = powerupGiver->EffectTics + 1;
|
||||
}
|
||||
static VMFunction *func = nullptr;
|
||||
if (func == nullptr) func = static_cast<PFunction*>(RUNTIME_CLASS(APlayerPawn)->Symbols.FindSymbol("GetEffectTicsForItem", false))->Variants[0].Implementation;
|
||||
VMValue params[] = { statusBar->CPlayer->mo, data.inventoryItem };
|
||||
VMReturn ret[2];
|
||||
int ival;
|
||||
ret[0].IntAt(&ival);
|
||||
ret[1].IntAt(&max);
|
||||
GlobalVMStack.Call(func, params, 2, ret, 2);
|
||||
value = ival + 1;
|
||||
max++;
|
||||
break;
|
||||
}
|
||||
case SAVEPERCENT:
|
||||
|
|
|
@ -709,6 +709,13 @@ xx(Wi_NoAutostartMap)
|
|||
xx(MorphStyle)
|
||||
xx(MorphFlash)
|
||||
xx(UnMorphFlash)
|
||||
xx(Powerup)
|
||||
xx(EffectTics)
|
||||
xx(PowerupGiver)
|
||||
xx(BlendColor)
|
||||
xx(Strength)
|
||||
xx(Mode)
|
||||
xx(PowerupType)
|
||||
|
||||
// Decorate compatibility functions
|
||||
xx(BuiltinTypeCheck)
|
||||
|
|
|
@ -5719,7 +5719,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
if (argCount >= 2)
|
||||
{
|
||||
PClassActor *powerupclass = PClass::FindActor(FBehavior::StaticLookupString(args[1]));
|
||||
if (powerupclass == NULL || !RUNTIME_CLASS(APowerup)->IsAncestorOf(powerupclass))
|
||||
if (powerupclass == NULL || !powerupclass->IsDescendantOf(PClass::FindActor(NAME_Powerup)))
|
||||
{
|
||||
Printf("'%s' is not a type of Powerup.\n", FBehavior::StaticLookupString(args[1]));
|
||||
return 0;
|
||||
|
|
|
@ -5381,15 +5381,13 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
|
|||
oldactor->DestroyAllInventory();
|
||||
}
|
||||
// [BC] Handle temporary invulnerability when respawned
|
||||
if ((state == PST_REBORN || state == PST_ENTER) &&
|
||||
(dmflags2 & DF2_YES_RESPAWN_INVUL) &&
|
||||
(multiplayer || alwaysapplydmflags))
|
||||
if (state == PST_REBORN || state == PST_ENTER)
|
||||
{
|
||||
APowerup *invul = static_cast<APowerup*>(p->mo->GiveInventoryType (PClass::FindActor(NAME_PowerInvulnerable)));
|
||||
invul->EffectTics = 3*TICRATE;
|
||||
invul->BlendColor = 0; // don't mess with the view
|
||||
invul->ItemFlags |= IF_UNDROPPABLE; // Don't drop this
|
||||
p->mo->effects |= FX_RESPAWNINVUL; // [RH] special effect
|
||||
IFVIRTUALPTR(p->mo, APlayerPawn, OnRespawn)
|
||||
{
|
||||
VMValue param = p->mo;
|
||||
GlobalVMStack.Call(func, ¶m, 1, nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (StatusBar != NULL && (playernum == consoleplayer || StatusBar->GetPlayer() == playernum))
|
||||
|
|
|
@ -1166,7 +1166,7 @@ void APlayerPawn::FilterCoopRespawnInventory (APlayerPawn *oldplayer)
|
|||
}
|
||||
else if ((dmflags & DF_COOP_LOSE_POWERUPS) &&
|
||||
defitem == NULL &&
|
||||
item->IsKindOf(RUNTIME_CLASS(APowerupGiver)))
|
||||
item->IsKindOf(PClass::FindActor(NAME_PowerupGiver)))
|
||||
{
|
||||
item->Destroy();
|
||||
}
|
||||
|
|
|
@ -464,10 +464,17 @@ int MatchString (const char *in, const char **strings)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static bool PointerCheck(PType *symtype, PType *checktype)
|
||||
{
|
||||
auto symptype = dyn_cast<PClassPointer>(symtype);
|
||||
auto checkptype = dyn_cast<PClassPointer>(checktype);
|
||||
return symptype != nullptr && checkptype != nullptr && symptype->ClassRestriction->IsDescendantOf(checkptype->ClassRestriction);
|
||||
}
|
||||
|
||||
static void *ScriptVar(DObject *obj, PClass *cls, FName field, PType *type)
|
||||
{
|
||||
auto sym = dyn_cast<PField>(cls->Symbols.FindSymbol(field, true));
|
||||
if (sym && sym->Type == type)
|
||||
if (sym && (sym->Type == type || PointerCheck(sym->Type, type)))
|
||||
{
|
||||
return (((char*)obj) + sym->Offset);
|
||||
}
|
||||
|
@ -2278,14 +2285,11 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory)
|
|||
|
||||
int alpha;
|
||||
PalEntry *pBlendColor;
|
||||
bool isgiver = info->IsDescendantOf(PClass::FindActor(NAME_PowerupGiver));
|
||||
|
||||
if (info->IsDescendantOf(RUNTIME_CLASS(APowerup)))
|
||||
if (info->IsDescendantOf(PClass::FindActor(NAME_Powerup)) || isgiver)
|
||||
{
|
||||
pBlendColor = &((APowerup*)defaults)->BlendColor;
|
||||
}
|
||||
else if (info->IsDescendantOf(RUNTIME_CLASS(APowerupGiver)))
|
||||
{
|
||||
pBlendColor = &((APowerupGiver*)defaults)->BlendColor;
|
||||
pBlendColor = &TypedScriptVar<PalEntry>(defaults, info, NAME_BlendColor, TypeColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2307,7 +2311,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory)
|
|||
*pBlendColor = MakeSpecialColormap(v);
|
||||
return;
|
||||
}
|
||||
else if (!stricmp(name, "none") && info->IsDescendantOf(RUNTIME_CLASS(APowerupGiver)))
|
||||
else if (!stricmp(name, "none") && isgiver)
|
||||
{
|
||||
*pBlendColor = MakeSpecialColormap(65535);
|
||||
return;
|
||||
|
@ -2333,13 +2337,9 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, colormap, FFFfff, Inventory)
|
|||
{
|
||||
PalEntry * pBlendColor;
|
||||
|
||||
if (info->IsDescendantOf(RUNTIME_CLASS(APowerup)))
|
||||
if (info->IsDescendantOf(PClass::FindActor(NAME_Powerup)) || info->IsDescendantOf(PClass::FindActor(NAME_PowerupGiver)))
|
||||
{
|
||||
pBlendColor = &((APowerup*)defaults)->BlendColor;
|
||||
}
|
||||
else if (info->IsDescendantOf(RUNTIME_CLASS(APowerupGiver)))
|
||||
{
|
||||
pBlendColor = &((APowerupGiver*)defaults)->BlendColor;
|
||||
pBlendColor = &TypedScriptVar<PalEntry>(defaults, info, NAME_BlendColor, TypeColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2377,13 +2377,9 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, duration, I, Inventory)
|
|||
{
|
||||
int *pEffectTics;
|
||||
|
||||
if (info->IsDescendantOf(RUNTIME_CLASS(APowerup)))
|
||||
if (info->IsDescendantOf(PClass::FindActor(NAME_Powerup)) || info->IsDescendantOf(PClass::FindActor(NAME_PowerupGiver)))
|
||||
{
|
||||
pEffectTics = &((APowerup*)defaults)->EffectTics;
|
||||
}
|
||||
else if (info->IsDescendantOf(RUNTIME_CLASS(APowerupGiver)))
|
||||
{
|
||||
pEffectTics = &((APowerupGiver*)defaults)->EffectTics;
|
||||
pEffectTics = &TypedScriptVar<int>(defaults, info, NAME_EffectTics, TypeSInt32);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2402,13 +2398,9 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, strength, F, Inventory)
|
|||
{
|
||||
double *pStrength;
|
||||
|
||||
if (info->IsDescendantOf(RUNTIME_CLASS(APowerup)))
|
||||
if (info->IsDescendantOf(PClass::FindActor(NAME_Powerup)) || info->IsDescendantOf(PClass::FindActor(NAME_PowerupGiver)))
|
||||
{
|
||||
pStrength = &((APowerup*)defaults)->Strength;
|
||||
}
|
||||
else if (info->IsDescendantOf(RUNTIME_CLASS(APowerupGiver)))
|
||||
{
|
||||
pStrength = &((APowerupGiver*)defaults)->Strength;
|
||||
pStrength = &TypedScriptVar<double>(defaults, info, NAME_Strength, TypeFloat64);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2426,13 +2418,10 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, mode, S, Inventory)
|
|||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
FName *pMode;
|
||||
if (info->IsDescendantOf(RUNTIME_CLASS(APowerup)))
|
||||
|
||||
if (info->IsDescendantOf(PClass::FindActor(NAME_Powerup)) || info->IsDescendantOf(PClass::FindActor(NAME_PowerupGiver)))
|
||||
{
|
||||
pMode = &((APowerup*)defaults)->Mode;
|
||||
}
|
||||
else if (info->IsDescendantOf(RUNTIME_CLASS(APowerupGiver)))
|
||||
{
|
||||
pMode = &((APowerupGiver*)defaults)->Mode;
|
||||
pMode = &TypedScriptVar<FName>(defaults, info, NAME_Mode, TypeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2445,7 +2434,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, mode, S, Inventory)
|
|||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY_PREFIX(powerup, type, S, PowerupGiver)
|
||||
DEFINE_SCRIPTED_PROPERTY_PREFIX(powerup, type, S, PowerupGiver)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
|
||||
|
@ -2465,8 +2454,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, type, S, PowerupGiver)
|
|||
I_Error("Unknown powerup type %s", str);
|
||||
}
|
||||
}
|
||||
|
||||
defaults->PowerupType = cls;
|
||||
TypedScriptVar<PClassActor*>(defaults, info, NAME_PowerupType, NewClassPointer(RUNTIME_CLASS(AActor))) = cls;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -393,6 +393,11 @@ struct VMReturn
|
|||
TagOfs = 0;
|
||||
RegType = REGT_POINTER;
|
||||
}
|
||||
VMReturn() { }
|
||||
VMReturn(int *loc) { IntAt(loc); }
|
||||
VMReturn(double *loc) { FloatAt(loc); }
|
||||
VMReturn(FString *loc) { StringAt(loc); }
|
||||
VMReturn(void **loc) { PointerAt(loc); }
|
||||
};
|
||||
|
||||
struct VMRegisters;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
class PowerupGiver : Inventory native
|
||||
class PowerupGiver : Inventory
|
||||
{
|
||||
|
||||
native Class<Actor> PowerupType;
|
||||
native int EffectTics; // Non-0 to override the powerup's default tics
|
||||
native color BlendColor; // Non-0 to override the powerup's default blend
|
||||
native Name Mode; // Meaning depends on powerup - used for Invulnerability and Invisibility
|
||||
native double Strength; // Meaning depends on powerup - currently used only by Invisibility
|
||||
Class<Actor> PowerupType;
|
||||
int EffectTics; // Non-0 to override the powerup's default tics
|
||||
color BlendColor; // Non-0 to override the powerup's default blend
|
||||
Name Mode; // Meaning depends on powerup - used for Invulnerability and Invisibility
|
||||
double Strength; // Meaning depends on powerup - currently used only by Invisibility
|
||||
|
||||
Default
|
||||
{
|
||||
|
@ -56,8 +56,6 @@ class PowerupGiver : Inventory native
|
|||
power.GoAwayAndDie ();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class Powerup : Inventory native
|
||||
|
|
|
@ -102,6 +102,36 @@ class PlayerPawn : Actor native
|
|||
virtual void MorphPlayerThink()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void OnRespawn()
|
||||
{
|
||||
if (sv_respawnprotect && (multiplayer || alwaysapplydmflags))
|
||||
{
|
||||
let invul = Powerup(Spawn("PowerInvulnerable"));
|
||||
invul.EffectTics = 3 * TICRATE;
|
||||
invul.BlendColor = 0; // don't mess with the view
|
||||
invul.bUndroppable = true; // Don't drop this
|
||||
bRespawnInvul = true; // [RH] special effect
|
||||
}
|
||||
}
|
||||
|
||||
// This is for SBARINFO.
|
||||
int/*, int*/ GetEffectTicsForItem(class<Inventory> item)
|
||||
{
|
||||
let pg = (class<PowerupGiver>)(item);
|
||||
if (pg != null)
|
||||
{
|
||||
let powerupType = (class<Powerup>)(GetDefaultByType(pg).PowerupType);
|
||||
let powerup = Powerup(FindInventory(powerupType));
|
||||
if(powerup != null)
|
||||
{
|
||||
let maxtics = GetDefaultByType(powerupType).EffectTics;
|
||||
if (maxtics == 0) maxtics = powerup.default.EffectTics;
|
||||
return powerup.EffectTics/*, maxtics*/;
|
||||
}
|
||||
}
|
||||
return 0/*, 0*/;
|
||||
}
|
||||
|
||||
native int GetMaxHealth();
|
||||
native bool ResetAirSupply (bool playgasp = false);
|
||||
|
|
Loading…
Reference in a new issue