- scriptified Actor.GetBloodType as a virtual function to allow mods more flexibility here.

- made CameraHeight a modifiable actor property - it was readonly before.
- allow accessing the type constants from ZScript, this required quite a bit of explicit coding because the type system has no capabilities to search for basic types by name.
This commit is contained in:
Christoph Oelckers 2017-02-28 12:11:25 +01:00
parent b6a1fe7fc6
commit 1311f08f47
8 changed files with 129 additions and 92 deletions

View file

@ -817,32 +817,7 @@ public:
void SetAngle(DAngle ang, bool interpolate);
void SetRoll(DAngle roll, bool interpolate);
PClassActor *GetBloodType(int type = 0) const
{
PClassActor *bloodcls;
if (type == 0)
{
bloodcls = PClass::FindActor(GetClass()->BloodType);
}
else if (type == 1)
{
bloodcls = PClass::FindActor(GetClass()->BloodType2);
}
else if (type == 2)
{
bloodcls = PClass::FindActor(GetClass()->BloodType3);
}
else
{
return NULL;
}
if (bloodcls != NULL)
{
bloodcls = bloodcls->GetReplacement();
}
return bloodcls;
}
PClassActor *GetBloodType(int type = 0) const;
double Distance2DSquared(AActor *other, bool absolute = false)
{
@ -1048,7 +1023,8 @@ public:
double renderradius;
double projectilepassheight; // height for clipping projectile movement against this actor
double CameraHeight; // Height of camera when used as such
SDWORD tics; // state tic counter
FState *state;
//VMFunction *Damage; // For missiles and monster railgun

View file

@ -722,10 +722,6 @@ PBool::PBool()
{
mDescriptiveName = "Bool";
MemberOnly = false;
// Override the default max set by PInt's constructor
PSymbolConstNumeric *maxsym = static_cast<PSymbolConstNumeric *>(Symbols.FindSymbol(NAME_Max, false));
assert(maxsym != nullptr && maxsym->IsKindOf(RUNTIME_CLASS(PSymbolConstNumeric)));
maxsym->Value = 1;
}
/* PFloat *****************************************************************/

View file

@ -259,7 +259,6 @@ PClassActor::PClassActor()
RDFactor = 1.;
SelfDamageFactor = 1.;
StealthAlpha = 0.;
CameraHeight = INT_MIN;
DropItems = NULL;
// Record this in the master list.
@ -316,11 +315,7 @@ void PClassActor::DeriveData(PClass *newclass)
newa->RDFactor = RDFactor;
newa->SelfDamageFactor = SelfDamageFactor;
newa->StealthAlpha = StealthAlpha;
newa->CameraHeight = CameraHeight;
newa->HowlSound = HowlSound;
newa->BloodType = BloodType;
newa->BloodType2 = BloodType2;
newa->BloodType3 = BloodType3;
newa->distancecheck = distancecheck;
newa->DropItems = DropItems;

View file

@ -300,12 +300,8 @@ public:
double FastSpeed; // speed in fast mode
double RDFactor; // Radius damage factor
double SelfDamageFactor;
double CameraHeight; // Height of camera when used as such
double StealthAlpha; // Minmum alpha for MF_STEALTH.
FSoundID HowlSound; // Sound being played when electrocuted or poisoned
FName BloodType; // Blood replacement type
FName BloodType2; // Bloopsplatter replacement type
FName BloodType3; // AxeBlood replacement type
FDropItem *DropItems;
FString SourceLumpName;

View file

@ -311,6 +311,7 @@ DEFINE_FIELD(AActor, ConversationRoot)
DEFINE_FIELD(AActor, Conversation)
DEFINE_FIELD(AActor, DecalGenerator)
DEFINE_FIELD(AActor, fountaincolor)
DEFINE_FIELD(AActor, CameraHeight)
DEFINE_FIELD(PClassActor, Obituary)
DEFINE_FIELD(PClassActor, HitObituary)
@ -323,11 +324,7 @@ DEFINE_FIELD(PClassActor, FastSpeed)
DEFINE_FIELD(PClassActor, RDFactor)
DEFINE_FIELD(PClassActor, SelfDamageFactor)
DEFINE_FIELD(PClassActor, StealthAlpha)
DEFINE_FIELD(PClassActor, CameraHeight)
DEFINE_FIELD(PClassActor, HowlSound)
DEFINE_FIELD(PClassActor, BloodType)
DEFINE_FIELD(PClassActor, BloodType2)
DEFINE_FIELD(PClassActor, BloodType3)
//==========================================================================
//
@ -488,6 +485,7 @@ void AActor::Serialize(FSerializer &arc)
A("spriteangle", SpriteAngle)
A("spriterotation", SpriteRotation)
("alternative", alternative)
A("cameraheight", CameraHeight)
A("tag", Tag)
A("visiblestartangle",VisibleStartAngle)
A("visibleendangle",VisibleEndAngle)
@ -3816,6 +3814,19 @@ void AActor::SetRoll(DAngle r, bool interpolate)
}
}
PClassActor *AActor::GetBloodType(int type) const
{
IFVIRTUAL(AActor, GetBloodType)
{
VMValue params[] = { (DObject*)this, type };
PClassActor *res;
VMReturn ret((void**)&res);
GlobalVMStack.Call(func, params, countof(params), &ret, 1);
return res;
}
return nullptr;
}
DVector3 AActor::GetPortalTransition(double byoffset, sector_t **pSec)
{
@ -7593,7 +7604,7 @@ int AActor::GetGibHealth() const
double AActor::GetCameraHeight() const
{
return GetClass()->CameraHeight == INT_MIN ? Height / 2 : GetClass()->CameraHeight;
return CameraHeight == INT_MIN ? Height / 2 : CameraHeight;
}
DEFINE_ACTION_FUNCTION(AActor, GetCameraHeight)

View file

@ -6088,19 +6088,85 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx)
if (Object->ExprType == EFX_Identifier)
{
auto id = static_cast<FxIdentifier *>(Object)->Identifier;
// If the left side is a class name for a static member function call it needs to be resolved manually
// because the resulting value type would cause problems in nearly every other place where identifiers are being used.
ccls = FindStructType(static_cast<FxIdentifier *>(Object)->Identifier, ctx);
if (ccls != nullptr) static_cast<FxIdentifier *>(Object)->noglobal = true;
ccls = FindStructType(id, ctx);
if (ccls != nullptr)
{
static_cast<FxIdentifier *>(Object)->noglobal = true;
}
else
{
PType *type;
// Another special case to deal with here is constants assigned to non-struct types. The code below cannot deal with them so it needs to be done here explicitly.
// Thanks to the messed up search logic of the type system, which doesn't allow any search by type name for the basic types at all,
// we have to do this manually, though and check for all types that may have values attached explicitly.
// (What's the point of attached fields to types if you cannot even search for the types...???)
switch (id)
{
default:
type = nullptr;
break;
case NAME_Byte:
case NAME_uint8:
type = TypeUInt8;
break;
case NAME_sByte:
case NAME_int8:
type = TypeSInt8;
break;
case NAME_uShort:
case NAME_uint16:
type = TypeUInt16;
break;
case NAME_Short:
case NAME_int16:
type = TypeSInt16;
break;
case NAME_Int:
type = TypeSInt32;
break;
case NAME_uInt:
type = TypeUInt32;
break;
case NAME_Float:
type = TypeFloat32;
break;
case NAME_Double:
type = TypeFloat64;
break;
}
if (type != nullptr)
{
auto sym = type->Symbols.FindSymbol(Identifier, true);
if (sym != nullptr)
{
// non-struct symbols must be constant numbers and can only be defined internally.
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolConstNumeric)));
auto sn = static_cast<PSymbolConstNumeric*>(sym);
VMValue vmv;
if (sn->ValueType->IsKindOf(RUNTIME_CLASS(PInt))) vmv = sn->Value;
else vmv = sn->Float;
auto x = new FxConstant(sn->ValueType, vmv, ScriptPosition);
delete this;
return x->Resolve(ctx);
}
}
}
}
SAFE_RESOLVE(Object, ctx);
if (Identifier == FName("allmap"))
{
int a = 2;
}
// check for class or struct constants if the left side is a type name.
if (Object->ValueType == TypeError)
{

View file

@ -1121,37 +1121,6 @@ DEFINE_PROPERTY(bloodcolor, C, Actor)
}
//==========================================================================
//
//==========================================================================
DEFINE_PROPERTY(bloodtype, Sss, Actor)
{
PROP_STRING_PARM(str, 0)
PROP_STRING_PARM(str1, 1)
PROP_STRING_PARM(str2, 2)
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
PClassActor *ainfo = static_cast<PClassActor *>(info);
FName blood = str;
// normal blood
ainfo->BloodType = blood;
if (PROP_PARM_COUNT > 1)
{
blood = str1;
}
// blood splatter
ainfo->BloodType2 = blood;
if (PROP_PARM_COUNT > 2)
{
blood = str2;
}
// axe blood
ainfo->BloodType3 = blood;
}
//==========================================================================
//
//==========================================================================
@ -1387,8 +1356,7 @@ DEFINE_PROPERTY(stealthalpha, F, Actor)
DEFINE_PROPERTY(cameraheight, F, Actor)
{
PROP_DOUBLE_PARM(i, 0);
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
static_cast<PClassActor *>(info)->CameraHeight = i;
defaults->CameraHeight = i;
}
//==========================================================================

View file

@ -189,6 +189,7 @@ class Actor : Thinker native
native State MissileState;
native voidptr /*DecalBase*/ DecalGenerator;
native uint8 fountaincolor;
native double CameraHeight; // Height of camera when used as such
native meta String Obituary; // Player was killed by this actor
native meta String HitObituary; // Player was killed by this actor in melee
@ -199,12 +200,11 @@ class Actor : Thinker native
native meta int WoundHealth; // Health needed to enter wound state
native meta double FastSpeed; // speed in fast mode
native meta double RDFactor; // Radius damage factor
native meta double CameraHeight; // Height of camera when used as such
native meta Sound HowlSound; // Sound being played when electrocuted or poisoned
native meta Name BloodType; // Blood replacement type
native meta Name BloodType2; // Bloopsplatter replacement type
native meta Name BloodType3; // AxeBlood replacement type
meta Name BloodType; // Blood replacement type
meta Name BloodType2; // Bloopsplatter replacement type
meta Name BloodType3; // AxeBlood replacement type
meta bool DontHurtShooter;
meta int ExplosionRadius;
meta int ExplosionDamage;
@ -221,6 +221,7 @@ class Actor : Thinker native
Property DontHurtShooter: DontHurtShooter;
Property ExplosionRadius: ExplosionRadius;
Property ExplosionDamage: ExplosionDamage;
Property BloodType: BloodType, BloodType2, BloodType3;
// need some definition work first
//FRenderStyle RenderStyle;
@ -248,7 +249,7 @@ class Actor : Thinker native
Health DEFAULT_HEALTH;
Reactiontime 8;
Radius 20;
RenderRadius 0;
RenderRadius 0;
Height 16;
Mass 100;
RenderStyle 'Normal';
@ -288,6 +289,7 @@ class Actor : Thinker native
VisibleAngles 0, 0;
VisiblePitch 0, 0;
DefaultStateUsage SUF_ACTOR|SUF_OVERLAY;
CameraHeight int.min;
}
// Functions
@ -320,7 +322,7 @@ class Actor : Thinker native
virtual native void Touch(Actor toucher);
virtual native void MarkPrecacheSounds();
// Called by PIT_CheckThing to check if two actos actually can collide.
// Called by PIT_CheckThing to check if two actors actually can collide.
virtual bool CanCollideWith(Actor other, bool passive)
{
return true;
@ -344,6 +346,33 @@ class Actor : Thinker native
{
return false;
}
virtual class<Actor> GetBloodType(int type)
{
Class<Actor> bloodcls;
if (type == 0)
{
bloodcls = BloodType;
}
else if (type == 1)
{
bloodcls = BloodType2;
}
else if (type == 2)
{
bloodcls = BloodType3;
}
else
{
return NULL;
}
if (bloodcls != NULL)
{
bloodcls = GetReplacement(bloodcls);
}
return bloodcls;
}
native static class<Actor> GetReplacement(class<Actor> cls);
native static class<Actor> GetReplacee(class<Actor> cls);