- scriptified PowerLightAmp and PowerTorch.

- allow calling qualified super methods so skipping some levels is possible.
This commit is contained in:
Christoph Oelckers 2017-01-16 00:46:15 +01:00
parent d2d6e5d486
commit d207b571d9
5 changed files with 141 additions and 139 deletions

View File

@ -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 -------------------------------------------------------------

View File

@ -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)

View File

@ -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<PClass>(ctx.Function->Variants[0].SelfClass);
if (clstype != nullptr)
{
novirtual = clstype->IsDescendantOf(static_cast<PClass*>(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<PClass>(ctx.Class);
auto ccls = dyn_cast<PClass>(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<PClass>(ctx.Class);
auto ccls = dyn_cast<PClass>(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;
}
}
}

View File

@ -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);
}
}
}
}
}
//===========================================================================
//

View File

@ -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;