From 1311f08f4714138fb1bfa837a91672760f77d944 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 28 Feb 2017 12:11:25 +0100 Subject: [PATCH] - 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. --- src/actor.h | 30 +--------- src/dobjtype.cpp | 4 -- src/info.cpp | 5 -- src/info.h | 4 -- src/p_mobj.cpp | 21 +++++-- src/scripting/backend/codegen.cpp | 80 ++++++++++++++++++++++++--- src/scripting/thingdef_properties.cpp | 34 +----------- wadsrc/static/zscript/actor.txt | 43 +++++++++++--- 8 files changed, 129 insertions(+), 92 deletions(-) diff --git a/src/actor.h b/src/actor.h index 2ed0047405..6e64b6033e 100644 --- a/src/actor.h +++ b/src/actor.h @@ -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 diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 1d5cd15122..f86797dfd2 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -722,10 +722,6 @@ PBool::PBool() { mDescriptiveName = "Bool"; MemberOnly = false; - // Override the default max set by PInt's constructor - PSymbolConstNumeric *maxsym = static_cast(Symbols.FindSymbol(NAME_Max, false)); - assert(maxsym != nullptr && maxsym->IsKindOf(RUNTIME_CLASS(PSymbolConstNumeric))); - maxsym->Value = 1; } /* PFloat *****************************************************************/ diff --git a/src/info.cpp b/src/info.cpp index 0db6c7fbc5..6f9b95f36d 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -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; diff --git a/src/info.h b/src/info.h index 9e684f462b..fd89145465 100644 --- a/src/info.h +++ b/src/info.h @@ -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; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 40fa7e0c95..d95bae5b2f 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -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) diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index bd18103fca..893a50eed9 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -6088,19 +6088,85 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx) if (Object->ExprType == EFX_Identifier) { + auto id = static_cast(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(Object)->Identifier, ctx); - if (ccls != nullptr) static_cast(Object)->noglobal = true; + ccls = FindStructType(id, ctx); + if (ccls != nullptr) + { + static_cast(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(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) { diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 0e34e2da48..3838c3a89a 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -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(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(info)->CameraHeight = i; + defaults->CameraHeight = i; } //========================================================================== diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 6a12e00f8f..9796c3e8df 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -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 GetBloodType(int type) + { + Class 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 GetReplacement(class cls); native static class GetReplacee(class cls);