mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 23:01:50 +00:00
- deconstruct A_Jump with multiple labels into A_Jump(chance, RandomPick(label1, label2, label3,...)) to remove this ugly special case from the VM calling convention.
This also adds the number of available choices to OP_IJMP.
This commit is contained in:
parent
68afc419af
commit
adde0510fe
4 changed files with 52 additions and 10 deletions
|
@ -75,7 +75,6 @@ AActor *SingleActorFromTID(int tid, AActor *defactor);
|
|||
|
||||
static FRandom pr_camissile ("CustomActorfire");
|
||||
static FRandom pr_cabullet ("CustomBullet");
|
||||
static FRandom pr_cajump ("CustomJump");
|
||||
static FRandom pr_cwbullet ("CustomWpBullet");
|
||||
static FRandom pr_cwjump ("CustomWpJump");
|
||||
static FRandom pr_cwpunch ("CustomWpPunch");
|
||||
|
@ -87,6 +86,7 @@ static FRandom pr_burst ("Burst");
|
|||
static FRandom pr_monsterrefire ("MonsterRefire");
|
||||
static FRandom pr_teleport("A_Teleport");
|
||||
static FRandom pr_bfgselfdamage("BFGSelfDamage");
|
||||
FRandom pr_cajump("CustomJump");
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -1129,13 +1129,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_Jump)
|
|||
{
|
||||
PARAM_ACTION_PROLOGUE(AActor);
|
||||
PARAM_INT(maxchance);
|
||||
PARAM_STATE_ACTION(jumpto);
|
||||
|
||||
paramnum++; // Increment paramnum to point at the first jump target
|
||||
int count = numparam - paramnum;
|
||||
if (count > 0 && (maxchance >= 256 || pr_cajump() < maxchance))
|
||||
if (maxchance >= 256 || pr_cajump() < maxchance)
|
||||
{
|
||||
int jumpnum = (count == 1 ? 0 : (pr_cajump() % count));
|
||||
PARAM_STATE_ACTION_AT(paramnum + jumpnum, jumpto);
|
||||
ACTION_RETURN_STATE(jumpto);
|
||||
}
|
||||
ACTION_RETURN_STATE(NULL);
|
||||
|
|
|
@ -5660,7 +5660,7 @@ ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build)
|
|||
|
||||
ExpEmit resultreg(build, REGT_INT);
|
||||
build->Emit(OP_RESULT, 0, REGT_INT, resultreg.RegNum);
|
||||
build->Emit(OP_IJMP, resultreg.RegNum, 0);
|
||||
build->Emit(OP_IJMP, resultreg.RegNum, choices.Size());
|
||||
|
||||
// Free the result register now. The simple code generation algorithm should
|
||||
// automatically pick it as the destination register for each case.
|
||||
|
@ -8781,6 +8781,41 @@ VMFunction *FxVMFunctionCall::GetDirectFunction(PFunction *callingfunc, const Ve
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxVMFunctionCall :: UnravelVarArgAJump
|
||||
//
|
||||
// Converts A_Jump(chance, a, b, c, d) -> A_Jump(chance, RandomPick[cajump](a, b, c, d))
|
||||
// so that varargs are restricted to either text formatting or graphics drawing.
|
||||
//
|
||||
//==========================================================================
|
||||
extern FRandom pr_cajump;
|
||||
|
||||
bool FxVMFunctionCall::UnravelVarArgAJump(FCompileContext &ctx)
|
||||
{
|
||||
FArgumentList rplist;
|
||||
|
||||
for (unsigned i = 1; i < ArgList.Size(); i++)
|
||||
{
|
||||
// This needs a bit of casting voodoo because RandomPick wants integer parameters.
|
||||
auto x = new FxIntCast(new FxTypeCast(ArgList[i], TypeStateLabel, true, true), true, true);
|
||||
rplist.Push(x->Resolve(ctx));
|
||||
ArgList[i] = nullptr;
|
||||
if (rplist[i - 1] == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
FxExpression *x = new FxRandomPick(&pr_cajump, rplist, false, ScriptPosition, true);
|
||||
x = x->Resolve(ctx);
|
||||
// This cannot be done with a cast because that interprets the value as an index.
|
||||
// All we want here is to take the literal value and change its type.
|
||||
if (x) x->ValueType = TypeStateLabel;
|
||||
ArgList[1] = x;
|
||||
ArgList.Clamp(2);
|
||||
return x != nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxVMFunctionCall :: Resolve
|
||||
|
@ -8813,9 +8848,18 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (Function->Variants[0].Implementation->PrintableName.CompareNoCase("CustomStatusBar.DrawTexture") == 0)
|
||||
// Unfortunately the PrintableName is the only safe thing to catch this special case here.
|
||||
if (Function->Variants[0].Implementation->PrintableName.CompareNoCase("Actor.A_Jump [Native]") == 0)
|
||||
{
|
||||
int a = 0;
|
||||
// Unravel the varargs part of this function here so that the VM->native interface does not have to deal with it anymore.
|
||||
if (ArgList.Size() > 2)
|
||||
{
|
||||
auto ret = UnravelVarArgAJump(ctx);
|
||||
if (!ret)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CallingFunction = ctx.Function;
|
||||
|
|
|
@ -1764,6 +1764,7 @@ class FxVMFunctionCall : public FxExpression
|
|||
PFunction *CallingFunction;
|
||||
|
||||
bool CheckAccessibility(const VersionInfo &ver);
|
||||
bool UnravelVarArgAJump(FCompileContext&);
|
||||
|
||||
public:
|
||||
FxVMFunctionCall(FxExpression *self, PFunction *func, FArgumentList &args, const FScriptPosition &pos, bool novirtual);
|
||||
|
|
|
@ -1062,7 +1062,7 @@ class Actor : Thinker native
|
|||
deprecated("2.3") native void A_PlaySoundEx(sound whattoplay, name slot, bool looping = false, int attenuation = 0);
|
||||
deprecated("2.3") native void A_StopSoundEx(name slot);
|
||||
native void A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10);
|
||||
native action state A_Jump(int chance, statelabel label, ...);
|
||||
native action state A_Jump(int chance, statelabel label);
|
||||
native Actor A_SpawnProjectile(class<Actor> missiletype, double spawnheight = 32, double spawnofs_xy = 0, double angle = 0, int flags = 0, double pitch = 0, int ptr = AAPTR_TARGET);
|
||||
native void A_CustomBulletAttack(double spread_xy, double spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", double range = 0, int flags = 0, int ptr = AAPTR_TARGET, class<Actor> missile = null, double Spawnheight = 32, double Spawnofs_xy = 0);
|
||||
native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = 0, color color2 = 0, int flags = 0, int aim = 0, double maxdiff = 0, class<Actor> pufftype = "BulletPuff", double spread_xy = 0, double spread_z = 0, double range = 0, int duration = 0, double sparsity = 1.0, double driftspeed = 1.0, class<Actor> spawnclass = null, double spawnofs_z = 0, int spiraloffset = 270, int limit = 0, double veleffect = 3);
|
||||
|
|
Loading…
Reference in a new issue