mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 21:11:39 +00:00
- scriptified the remaining functions in a_artifacts.cpp.
- added some helpers to set scripted member variables through the native property parser. Unfortunately some classes, e.g. PowerMorph, MorphProjectile and the powerup contain some that cannot be handled through the 'property' definition on the script side so they need to be done from the native side.
This commit is contained in:
parent
14f2c39e58
commit
98f9219334
12 changed files with 128 additions and 140 deletions
|
@ -60,46 +60,6 @@ DEFINE_FIELD(APowerupGiver, BlendColor)
|
|||
DEFINE_FIELD(APowerupGiver, Mode)
|
||||
DEFINE_FIELD(APowerupGiver, Strength)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerupGiver :: Use
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool APowerupGiver::Use (bool pickup)
|
||||
{
|
||||
if (PowerupType == NULL) return true; // item is useless
|
||||
if (Owner == nullptr) return true;
|
||||
|
||||
APowerup *power = static_cast<APowerup *> (Spawn (PowerupType));
|
||||
|
||||
if (EffectTics != 0)
|
||||
{
|
||||
power->EffectTics = EffectTics;
|
||||
}
|
||||
if (BlendColor != 0)
|
||||
{
|
||||
if (BlendColor != MakeSpecialColormap(65535)) power->BlendColor = BlendColor;
|
||||
else power->BlendColor = 0;
|
||||
}
|
||||
if (Mode != NAME_None)
|
||||
{
|
||||
power->Mode = Mode;
|
||||
}
|
||||
if (Strength != 0)
|
||||
{
|
||||
power->Strength = Strength;
|
||||
}
|
||||
|
||||
power->ItemFlags |= ItemFlags & (IF_ALWAYSPICKUP|IF_ADDITIVETIME|IF_NOTELEPORTFREEZE);
|
||||
if (power->CallTryPickup (Owner))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
power->GoAwayAndDie ();
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerupGiver :: Serialize
|
||||
|
@ -142,49 +102,3 @@ void APowerup::Serialize(FSerializer &arc)
|
|||
("colormap", Colormap, def->Colormap);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerup :: OwnerDied
|
||||
//
|
||||
// Powerups don't last beyond death.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerup::OwnerDied ()
|
||||
{
|
||||
Destroy ();
|
||||
}
|
||||
|
||||
// Morph powerup ------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLASS(APowerMorph, false, true)
|
||||
|
||||
IMPLEMENT_POINTERS_START(APowerMorph)
|
||||
IMPLEMENT_POINTER(PlayerClass)
|
||||
IMPLEMENT_POINTER(MorphFlash)
|
||||
IMPLEMENT_POINTER(UnMorphFlash)
|
||||
IMPLEMENT_POINTERS_END
|
||||
|
||||
|
||||
DEFINE_FIELD(APowerMorph, PlayerClass)
|
||||
DEFINE_FIELD(APowerMorph, MorphFlash)
|
||||
DEFINE_FIELD(APowerMorph, UnMorphFlash)
|
||||
DEFINE_FIELD(APowerMorph, MorphStyle)
|
||||
DEFINE_FIELD(APowerMorph, MorphedPlayer)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerMorph :: Serialize
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerMorph::Serialize(FSerializer &arc)
|
||||
{
|
||||
Super::Serialize (arc);
|
||||
arc("playerclass", PlayerClass)
|
||||
("morphstyle", MorphStyle)
|
||||
("morphflash", MorphFlash)
|
||||
("unmorphflash", UnMorphFlash)
|
||||
("morphedplayer", MorphedPlayer);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ class APowerup : public AInventory
|
|||
DECLARE_CLASS (APowerup, AInventory)
|
||||
public:
|
||||
virtual void Serialize(FSerializer &arc) override;
|
||||
virtual void OwnerDied () override;
|
||||
|
||||
int EffectTics;
|
||||
PalEntry BlendColor;
|
||||
|
@ -31,7 +30,6 @@ class APowerupGiver : public AInventory
|
|||
DECLARE_CLASS (APowerupGiver, AInventory)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
virtual bool Use (bool pickup) override;
|
||||
virtual void Serialize(FSerializer &arc) override;
|
||||
|
||||
|
||||
|
@ -42,19 +40,5 @@ public:
|
|||
double Strength; // Meaning depends on powerup - currently used only by Invisibility
|
||||
};
|
||||
|
||||
class APowerMorph : public APowerup
|
||||
{
|
||||
DECLARE_CLASS( APowerMorph, APowerup )
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
|
||||
virtual void Serialize(FSerializer &arc) override;
|
||||
|
||||
// Variables
|
||||
PClassPlayerPawn *PlayerClass;
|
||||
PClassActor *MorphFlash, *UnMorphFlash;
|
||||
int MorphStyle;
|
||||
player_t *MorphedPlayer;
|
||||
};
|
||||
|
||||
#endif //__A_ARTIFACTS_H__
|
||||
|
|
|
@ -368,18 +368,6 @@ void AInventory::CallDoEffect()
|
|||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: OwnerDied
|
||||
//
|
||||
// Items receive this message when their owners die.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void AInventory::OwnerDied ()
|
||||
{
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: HandlePickup
|
||||
|
@ -1348,7 +1336,7 @@ bool AInventory::TryPickup (AActor *&toucher)
|
|||
}
|
||||
// The item is placed in the inventory just long enough to be used.
|
||||
toucher->AddInventory (this);
|
||||
bool usegood = Use (true);
|
||||
bool usegood = CallUse (true);
|
||||
toucher->RemoveInventory (this);
|
||||
|
||||
if (usegood)
|
||||
|
|
|
@ -138,8 +138,6 @@ public:
|
|||
// virtual on the script side only.
|
||||
double GetSpeedFactor();
|
||||
bool GetNoTeleportFreeze();
|
||||
// Stuff for later when more features are exported.
|
||||
virtual void OwnerDied();
|
||||
|
||||
|
||||
bool GoAway();
|
||||
|
|
|
@ -706,6 +706,10 @@ xx(WBobSpeed)
|
|||
xx(PlayerClass)
|
||||
xx(Wi_NoAutostartMap)
|
||||
|
||||
xx(MorphStyle)
|
||||
xx(MorphFlash)
|
||||
xx(UnMorphFlash)
|
||||
|
||||
// Decorate compatibility functions
|
||||
xx(BuiltinTypeCheck)
|
||||
xx(BuiltinRandom)
|
||||
|
|
|
@ -357,15 +357,19 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
|
|||
static int dieticks[MAXPLAYERS]; // [ZzZombo] not used? Except if for peeking in debugger...
|
||||
int pnum = int(this->player-players);
|
||||
dieticks[pnum] = gametic;
|
||||
fprintf (debugfile, "died (%d) on tic %d (%s)\n", pnum, gametic,
|
||||
this->player->cheats&CF_PREDICTING?"predicting":"real");
|
||||
fprintf(debugfile, "died (%d) on tic %d (%s)\n", pnum, gametic,
|
||||
this->player->cheats&CF_PREDICTING ? "predicting" : "real");
|
||||
}
|
||||
|
||||
// [RH] Notify this actor's items.
|
||||
for (AInventory *item = Inventory; item != NULL; )
|
||||
{
|
||||
AInventory *next = item->Inventory;
|
||||
item->OwnerDied();
|
||||
IFVIRTUALPTR(item, AInventory, OwnerDied)
|
||||
{
|
||||
VMValue params[1] = { item };
|
||||
GlobalVMStack.Call(func, params, 1, nullptr, 0);
|
||||
}
|
||||
item = next;
|
||||
}
|
||||
|
||||
|
|
|
@ -913,13 +913,14 @@ static void ParseActorProperty(FScanner &sc, Baggage &bag)
|
|||
|
||||
if (prop != NULL)
|
||||
{
|
||||
if (bag.Info->IsDescendantOf(*prop->cls))
|
||||
auto pcls = PClass::FindActor(prop->clsname);
|
||||
if (bag.Info->IsDescendantOf(pcls))
|
||||
{
|
||||
ParsePropertyParams(sc, prop, (AActor *)bag.Info->Defaults, bag);
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptMessage("'%s' requires an actor of type '%s'\n", propname.GetChars(), (*prop->cls)->TypeName.GetChars());
|
||||
sc.ScriptMessage("'%s' requires an actor of type '%s'\n", propname.GetChars(), pcls->TypeName.GetChars());
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ struct FPropertyInfo
|
|||
{
|
||||
const char *name;
|
||||
const char *params;
|
||||
const PClass * const *cls;
|
||||
const char *clsname;
|
||||
PropHandler Handler;
|
||||
int category;
|
||||
};
|
||||
|
@ -242,17 +242,24 @@ int MatchString (const char *in, const char **strings);
|
|||
#define DEFINE_PROPERTY_BASE(name, paramlist, clas, cat) \
|
||||
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, PClassActor *info, Baggage &bag, FPropParam *params); \
|
||||
static FPropertyInfo Prop_##name##_##paramlist##_##clas = \
|
||||
{ #name, #paramlist, &RUNTIME_CLASS_CASTLESS(A##clas), (PropHandler)Handler_##name##_##paramlist##_##clas, cat }; \
|
||||
{ #name, #paramlist, #clas, (PropHandler)Handler_##name##_##paramlist##_##clas, cat }; \
|
||||
MSVC_PSEG FPropertyInfo *infoptr_##name##_##paramlist##_##clas GCC_PSEG = &Prop_##name##_##paramlist##_##clas; \
|
||||
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, PClassActor *info, Baggage &bag, FPropParam *params)
|
||||
|
||||
#define DEFINE_PREFIXED_PROPERTY_BASE(prefix, name, paramlist, clas, cat) \
|
||||
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, PClassActor *info, Baggage &bag, FPropParam *params); \
|
||||
static FPropertyInfo Prop_##name##_##paramlist##_##clas = \
|
||||
{ #prefix"."#name, #paramlist, &RUNTIME_CLASS_CASTLESS(A##clas), (PropHandler)Handler_##name##_##paramlist##_##clas, cat }; \
|
||||
{ #prefix"."#name, #paramlist, #clas, (PropHandler)Handler_##name##_##paramlist##_##clas, cat }; \
|
||||
MSVC_PSEG FPropertyInfo *infoptr_##name##_##paramlist##_##clas GCC_PSEG = &Prop_##name##_##paramlist##_##clas; \
|
||||
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, PClassActor *info, Baggage &bag, FPropParam *params)
|
||||
|
||||
#define DEFINE_PREFIXED_SCRIPTED_PROPERTY_BASE(prefix, name, paramlist, clas, cat) \
|
||||
static void Handler_##name##_##paramlist##_##clas(AActor *defaults, PClassActor *info, Baggage &bag, FPropParam *params); \
|
||||
static FPropertyInfo Prop_##name##_##paramlist##_##clas = \
|
||||
{ #prefix"."#name, #paramlist, #clas, (PropHandler)Handler_##name##_##paramlist##_##clas, cat }; \
|
||||
MSVC_PSEG FPropertyInfo *infoptr_##name##_##paramlist##_##clas GCC_PSEG = &Prop_##name##_##paramlist##_##clas; \
|
||||
static void Handler_##name##_##paramlist##_##clas(AActor *defaults, PClassActor *info, Baggage &bag, FPropParam *params)
|
||||
|
||||
|
||||
#define DEFINE_PROPERTY(name, paramlist, clas) DEFINE_PROPERTY_BASE(name, paramlist, clas, CAT_PROPERTY)
|
||||
#define DEFINE_INFO_PROPERTY(name, paramlist, clas) DEFINE_PROPERTY_BASE(name, paramlist, clas, CAT_INFO)
|
||||
|
@ -260,6 +267,9 @@ int MatchString (const char *in, const char **strings);
|
|||
#define DEFINE_CLASS_PROPERTY(name, paramlist, clas) DEFINE_PREFIXED_PROPERTY_BASE(clas, name, paramlist, clas, CAT_PROPERTY)
|
||||
#define DEFINE_CLASS_PROPERTY_PREFIX(prefix, name, paramlist, clas) DEFINE_PREFIXED_PROPERTY_BASE(prefix, name, paramlist, clas, CAT_PROPERTY)
|
||||
|
||||
#define DEFINE_SCRIPTED_PROPERTY(name, paramlist, clas) DEFINE_PREFIXED_SCRIPTED_PROPERTY_BASE(clas, name, paramlist, clas, CAT_PROPERTY)
|
||||
#define DEFINE_SCRIPTED_PROPERTY_PREFIX(prefix, name, paramlist, clas) DEFINE_PREFIXED_SCRIPTED_PROPERTY_BASE(prefix, name, paramlist, clas, CAT_PROPERTY)
|
||||
|
||||
#define PROP_PARM_COUNT (params[0].i)
|
||||
|
||||
#define PROP_STRING_PARM(var, no) \
|
||||
|
|
|
@ -456,12 +456,38 @@ int MatchString (const char *in, const char **strings)
|
|||
return -1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Get access to scripted fields.
|
||||
// Fortunately there's only a handful that cannot be done with a
|
||||
// scripted property definition, most notably the powerup and morph stuff.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
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)
|
||||
{
|
||||
return (((char*)obj) + sym->Offset);
|
||||
}
|
||||
I_Error("Variable %s of type %s not found in %s\n", field.GetChars(), type->DescriptiveName(), cls->TypeName.GetChars());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T &TypedScriptVar(DObject *obj, PClass *cls, FName field, PType *type)
|
||||
{
|
||||
return *(T*)ScriptVar(obj, cls, field, type);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Info Property handlers
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
@ -3026,37 +3052,37 @@ DEFINE_CLASS_PROPERTY(unmorphflash, S, MorphProjectile)
|
|||
//==========================================================================
|
||||
// (non-fatal with non-existent types only in DECORATE)
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(playerclass, S, PowerMorph)
|
||||
DEFINE_SCRIPTED_PROPERTY(playerclass, S, PowerMorph)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
defaults->PlayerClass = FindClassTentativePlayerPawn(str, bag.fromDecorate);
|
||||
TypedScriptVar<PClassActor*>(defaults, bag.Info, NAME_PlayerClass, NewClassPointer(RUNTIME_CLASS(APlayerPawn))) = FindClassTentativePlayerPawn(str, bag.fromDecorate);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(morphstyle, M, PowerMorph)
|
||||
DEFINE_SCRIPTED_PROPERTY(morphstyle, M, PowerMorph)
|
||||
{
|
||||
PROP_INT_PARM(i, 0);
|
||||
defaults->MorphStyle = i;
|
||||
TypedScriptVar<int>(defaults, bag.Info, NAME_MorphStyle, TypeSInt32) = i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
// (non-fatal with non-existent types only in DECORATE)
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(morphflash, S, PowerMorph)
|
||||
DEFINE_SCRIPTED_PROPERTY(morphflash, S, PowerMorph)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
defaults->MorphFlash = FindClassTentative(str, RUNTIME_CLASS(AActor), bag.fromDecorate);
|
||||
TypedScriptVar<PClassActor*>(defaults, bag.Info, NAME_MorphFlash, NewClassPointer(RUNTIME_CLASS(AActor))) = FindClassTentative(str, RUNTIME_CLASS(AActor), bag.fromDecorate);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
// (non-fatal with non-existent types only in DECORATE)
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(unmorphflash, S, PowerMorph)
|
||||
DEFINE_SCRIPTED_PROPERTY(unmorphflash, S, PowerMorph)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
defaults->UnMorphFlash = FindClassTentative(str, RUNTIME_CLASS(AActor), bag.fromDecorate);
|
||||
TypedScriptVar<PClassActor*>(defaults, bag.Info, NAME_UnMorphFlash, NewClassPointer(RUNTIME_CLASS(AActor))) = FindClassTentative(str, RUNTIME_CLASS(AActor), bag.fromDecorate);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2022,13 +2022,14 @@ void ZCCCompiler::ProcessDefaultProperty(PClassActor *cls, ZCC_PropertyStmt *pro
|
|||
|
||||
if (property != nullptr && property->category != CAT_INFO)
|
||||
{
|
||||
if (cls->IsDescendantOf(*property->cls))
|
||||
auto pcls = PClass::FindActor(property->clsname);
|
||||
if (cls->IsDescendantOf(pcls))
|
||||
{
|
||||
DispatchProperty(property, prop, (AActor *)bag.Info->Defaults, bag);
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(prop, "'%s' requires an actor of type '%s'\n", propname.GetChars(), (*property->cls)->TypeName.GetChars());
|
||||
Error(prop, "'%s' requires an actor of type '%s'\n", propname.GetChars(), pcls->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -64,6 +64,7 @@ class Inventory : Actor native
|
|||
virtual bool GetNoTeleportFreeze() { return false; }
|
||||
virtual void ModifyDamage(int damage, Name damageType, out int newdamage, bool passive) {}
|
||||
virtual void AlterWeaponSprite(VisStyle vis, in out int changed) {}
|
||||
virtual void OwnerDied() {}
|
||||
|
||||
native bool GoAway();
|
||||
native void GoAwayAndDie();
|
||||
|
|
|
@ -14,6 +14,50 @@ class PowerupGiver : Inventory native
|
|||
+INVENTORY.FANCYPICKUPSOUND
|
||||
Inventory.PickupSound "misc/p_pkup";
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerupGiver :: Use
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
override bool Use (bool pickup)
|
||||
{
|
||||
if (PowerupType == NULL) return true; // item is useless
|
||||
if (Owner == null) return true;
|
||||
|
||||
let power = Powerup(Spawn (PowerupType));
|
||||
|
||||
if (EffectTics != 0)
|
||||
{
|
||||
power.EffectTics = EffectTics;
|
||||
}
|
||||
if (BlendColor != 0)
|
||||
{
|
||||
if (BlendColor != Powerup.SPECIALCOLORMAP_MASK | 65535) power.BlendColor = BlendColor;
|
||||
else power.BlendColor = 0;
|
||||
}
|
||||
if (Mode != 'None')
|
||||
{
|
||||
power.Mode = Mode;
|
||||
}
|
||||
if (Strength != 0)
|
||||
{
|
||||
power.Strength = Strength;
|
||||
}
|
||||
|
||||
power.bAlwaysPickup |= bAlwaysPickup;
|
||||
power.bAdditiveTime |= bAdditiveTime;
|
||||
power.bNoTeleportFreeze |= bNoTeleportFreeze;
|
||||
if (power.CallTryPickup (Owner))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
power.GoAwayAndDie ();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class Powerup : Inventory native
|
||||
|
@ -248,6 +292,19 @@ class Powerup : Inventory native
|
|||
return (EffectTics <= BLINKTHRESHOLD && (EffectTics & 8) && !bNoScreenBlink);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerup :: OwnerDied
|
||||
//
|
||||
// Powerups don't last beyond death.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
override void OwnerDied ()
|
||||
{
|
||||
Destroy ();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -1890,12 +1947,12 @@ class PowerInfiniteAmmo : Powerup
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
class PowerMorph : Powerup native
|
||||
class PowerMorph : Powerup
|
||||
{
|
||||
native Class<PlayerPawn> PlayerClass;
|
||||
native Class<Actor> MorphFlash, UnMorphFlash;
|
||||
native int MorphStyle;
|
||||
native PlayerInfo MorphedPlayer;
|
||||
Class<PlayerPawn> PlayerClass;
|
||||
Class<Actor> MorphFlash, UnMorphFlash;
|
||||
int MorphStyle;
|
||||
PlayerInfo MorphedPlayer;
|
||||
|
||||
Default
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue