diff --git a/src/g_inventory/a_artifacts.cpp b/src/g_inventory/a_artifacts.cpp index 7ffdab6c8..f8e34c9a7 100644 --- a/src/g_inventory/a_artifacts.cpp +++ b/src/g_inventory/a_artifacts.cpp @@ -903,110 +903,6 @@ void APowerMask::DoEffect () } } -// Light-Amp Powerup --------------------------------------------------------- - -IMPLEMENT_CLASS(APowerLightAmp, false, false) - -//=========================================================================== -// -// APowerLightAmp :: DoEffect -// -//=========================================================================== - -void APowerLightAmp::DoEffect () -{ - Super::DoEffect (); - - if (Owner->player != NULL && Owner->player->fixedcolormap < NUMCOLORMAPS) - { - if (!isBlinking()) - { - Owner->player->fixedlightlevel = 1; - } - else - { - Owner->player->fixedlightlevel = -1; - } - } -} - -//=========================================================================== -// -// APowerLightAmp :: EndEffect -// -//=========================================================================== - -void APowerLightAmp::EndEffect () -{ - Super::EndEffect(); - if (Owner != NULL && Owner->player != NULL && Owner->player->fixedcolormap < NUMCOLORMAPS) - { - Owner->player->fixedlightlevel = -1; - } -} - -// Torch Powerup ------------------------------------------------------------- - -IMPLEMENT_CLASS(APowerTorch, false, false) - -//=========================================================================== -// -// APowerTorch :: Serialize -// -//=========================================================================== - -void APowerTorch::Serialize(FSerializer &arc) -{ - Super::Serialize (arc); - arc("newtorch", NewTorch) - ("newtorchdelta", NewTorchDelta); -} - -//=========================================================================== -// -// APowerTorch :: DoEffect -// -//=========================================================================== - -void APowerTorch::DoEffect () -{ - if (Owner == NULL || Owner->player == NULL) - { - return; - } - - if (EffectTics <= BLINKTHRESHOLD || Owner->player->fixedcolormap >= NUMCOLORMAPS) - { - Super::DoEffect (); - } - else - { - APowerup::DoEffect (); - - if (!(level.time & 16) && Owner->player != NULL) - { - if (NewTorch != 0) - { - if (Owner->player->fixedlightlevel + NewTorchDelta > 7 - || Owner->player->fixedlightlevel + NewTorchDelta < 0 - || NewTorch == Owner->player->fixedlightlevel) - { - NewTorch = 0; - } - else - { - Owner->player->fixedlightlevel += NewTorchDelta; - } - } - else - { - NewTorch = (pr_torch() & 7) + 1; - NewTorchDelta = (NewTorch == Owner->player->fixedlightlevel) ? - 0 : ((NewTorch > Owner->player->fixedlightlevel) ? 1 : -1); - } - } - } -} // Speed Powerup ------------------------------------------------------------- diff --git a/src/g_inventory/a_artifacts.h b/src/g_inventory/a_artifacts.h index 65f8d7cea..d72ed42c3 100644 --- a/src/g_inventory/a_artifacts.h +++ b/src/g_inventory/a_artifacts.h @@ -105,25 +105,6 @@ public: virtual void DoEffect () override; }; -class APowerLightAmp : public APowerup -{ - DECLARE_CLASS (APowerLightAmp, APowerup) -protected: - virtual void DoEffect () override; - virtual void EndEffect () override; -}; - -class APowerTorch : public APowerLightAmp -{ - DECLARE_CLASS (APowerTorch, APowerLightAmp) -public: - - virtual void Serialize(FSerializer &arc) override; -protected: - virtual void DoEffect () override; - int NewTorch, NewTorchDelta; -}; - class APowerSpeed : public APowerup { DECLARE_CLASS (APowerSpeed, APowerup) diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index cd63636f6..1eefba216 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -7450,7 +7450,28 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) { cls = ccls; staticonly = true; - goto isresolved; + if (ccls->IsKindOf(RUNTIME_CLASS(PClass))) + { + auto clstype = dyn_cast(ctx.Function->Variants[0].SelfClass); + if (clstype != nullptr) + { + novirtual = clstype->IsDescendantOf(static_cast(ccls)); + if (novirtual) + { + bool error; + PFunction *afd = FindClassMemberFunction(ccls, ctx.Class, MethodName, ScriptPosition, &error); + if ((afd->Variants[0].Flags & VARF_Method) && (afd->Variants[0].Flags & VARF_Virtual)) + { + staticonly = false; + novirtual = true; + delete Self; + Self = new FxSelf(ScriptPosition); + Self->ValueType = NewPointer(cls); + } + } + } + } + if (!novirtual) goto isresolved; } } } @@ -7685,20 +7706,23 @@ isresolved: if (staticonly && (afd->Variants[0].Flags & VARF_Method)) { - auto clstype = dyn_cast(ctx.Class); - auto ccls = dyn_cast(cls); - if (clstype == nullptr || ccls == nullptr || !clstype->IsDescendantOf(ccls)) + if (!novirtual || !(afd->Variants[0].Flags & VARF_Virtual)) { - ScriptPosition.Message(MSG_ERROR, "Cannot call non-static function %s::%s from here\n", cls->TypeName.GetChars(), MethodName.GetChars()); - delete this; - return nullptr; - } - else - { - // Todo: If this is a qualified call to a parent class function, let it through (but this needs to disable virtual calls later.) - ScriptPosition.Message(MSG_ERROR, "Qualified member call to parent class %s::%s is not yet implemented\n", cls->TypeName.GetChars(), MethodName.GetChars()); - delete this; - return nullptr; + auto clstype = dyn_cast(ctx.Class); + auto ccls = dyn_cast(cls); + if (clstype == nullptr || ccls == nullptr || !clstype->IsDescendantOf(ccls)) + { + ScriptPosition.Message(MSG_ERROR, "Cannot call non-static function %s::%s from here\n", cls->TypeName.GetChars(), MethodName.GetChars()); + delete this; + return nullptr; + } + else + { + // Todo: If this is a qualified call to a parent class function, let it through (but this needs to disable virtual calls later.) + ScriptPosition.Message(MSG_ERROR, "Qualified member call to parent class %s::%s is not yet implemented\n", cls->TypeName.GetChars(), MethodName.GetChars()); + delete this; + return nullptr; + } } } diff --git a/wadsrc/static/zscript/inventory/powerups.txt b/wadsrc/static/zscript/inventory/powerups.txt index adee447f5..db838b904 100644 --- a/wadsrc/static/zscript/inventory/powerups.txt +++ b/wadsrc/static/zscript/inventory/powerups.txt @@ -104,15 +104,112 @@ class PowerMask : PowerIronFeet native } } -class PowerLightAmp : Powerup native +//=========================================================================== +// +// LightAmp +// +//=========================================================================== + +class PowerLightAmp : Powerup { Default { Powerup.Duration -120; } + + //=========================================================================== + // + // APowerLightAmp :: DoEffect + // + //=========================================================================== + + override void DoEffect () + { + Super.DoEffect (); + + let player = Owner.player; + if (player != NULL && player.fixedcolormap < PlayerInfo.NUMCOLORMAPS) + { + if (!isBlinking()) + { + player.fixedlightlevel = 1; + } + else + { + player.fixedlightlevel = -1; + } + } + } + + //=========================================================================== + // + // APowerLightAmp :: EndEffect + // + //=========================================================================== + + override void EndEffect () + { + Super.EndEffect(); + if (Owner != NULL && Owner.player != NULL && Owner.player.fixedcolormap < PlayerInfo.NUMCOLORMAPS) + { + Owner.player.fixedlightlevel = -1; + } + } + } -class PowerTorch : PowerLightAmp native {} +//=========================================================================== +// +// Torch +// +//=========================================================================== + +class PowerTorch : PowerLightAmp +{ + int NewTorch, NewTorchDelta; + + override void DoEffect () + { + if (Owner == NULL || Owner.player == NULL) + { + return; + } + + let player = Owner.player; + if (EffectTics <= BLINKTHRESHOLD || player.fixedcolormap >= PlayerInfo.NUMCOLORMAPS) + { + Super.DoEffect (); + } + else + { + Powerup.DoEffect (); + + if (!(level.time & 16) && Owner.player != NULL) + { + if (NewTorch != 0) + { + if (player.fixedlightlevel + NewTorchDelta > 7 + || player.fixedlightlevel + NewTorchDelta < 0 + || NewTorch == player.fixedlightlevel) + { + NewTorch = 0; + } + else + { + player.fixedlightlevel += NewTorchDelta; + } + } + else + { + NewTorch = (random[torch]() & 7) + 1; + NewTorchDelta = (NewTorch == Owner.player.fixedlightlevel) ? + 0 : ((NewTorch > player.fixedlightlevel) ? 1 : -1); + } + } + } + } + +} //=========================================================================== // diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 1648a8a40..56a6dc427 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -173,6 +173,10 @@ enum EPlayerState struct PlayerInfo native // this is what internally is known as player_t { + // technically engine constants but the only part of the playsim using them is the player. + const NOFIXEDCOLORMAP = -1; + const NUMCOLORMAPS = 32; + native PlayerPawn mo; native uint8 playerstate; native uint original_oldbuttons;