- scriptified A_FatAttack*.

- swapped parameters of two-parameter VelToAngle method, so that internal and script version are in line.
- fixed parameter asserts to handle NULL pointers properly.
This commit is contained in:
Christoph Oelckers 2016-10-27 17:47:46 +02:00
parent 948ef62fcd
commit c7347608a4
18 changed files with 152 additions and 154 deletions

View file

@ -1366,7 +1366,7 @@ public:
Vel.Y = speed * Angles.Yaw.Sin(); Vel.Y = speed * Angles.Yaw.Sin();
} }
void VelFromAngle(DAngle angle, double speed) void VelFromAngle(double speed, DAngle angle)
{ {
Vel.X = speed * angle.Cos(); Vel.X = speed * angle.Cos();
Vel.Y = speed * angle.Sin(); Vel.Y = speed * angle.Sin();

View file

@ -15,99 +15,6 @@
// firing three missiles in three different directions? // firing three missiles in three different directions?
// Doesn't look like it. // Doesn't look like it.
// //
#define FATSPREAD (90./8)
DEFINE_ACTION_FUNCTION(AActor, A_FatRaise)
{
PARAM_SELF_PROLOGUE(AActor);
A_FaceTarget (self);
S_Sound (self, CHAN_WEAPON, "fatso/raiseguns", 1, ATTN_NORM);
return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
AActor *missile;
if (!self->target)
return 0;
if (spawntype == NULL) spawntype = PClass::FindActor("FatShot");
A_FaceTarget (self);
// Change direction to ...
self->Angles.Yaw += FATSPREAD;
P_SpawnMissile (self, self->target, spawntype);
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->Angles.Yaw += FATSPREAD;
missile->VelFromAngle();
}
return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
AActor *missile;
if (!self->target)
return 0;
if (spawntype == NULL) spawntype = PClass::FindActor("FatShot");
A_FaceTarget (self);
// Now here choose opposite deviation.
self->Angles.Yaw -= FATSPREAD;
P_SpawnMissile (self, self->target, spawntype);
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->Angles.Yaw -= FATSPREAD*2;
missile->VelFromAngle();
}
return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
AActor *missile;
if (!self->target)
return 0;
if (spawntype == NULL) spawntype = PClass::FindActor("FatShot");
A_FaceTarget (self);
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->Angles.Yaw -= FATSPREAD/2;
missile->VelFromAngle();
}
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->Angles.Yaw += FATSPREAD/2;
missile->VelFromAngle();
}
return 0;
}
// //
// killough 9/98: a mushroom explosion effect, sorta :) // killough 9/98: a mushroom explosion effect, sorta :)
// Original idea: Linguica // Original idea: Linguica

View file

@ -84,7 +84,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove)
} }
// Adjust velocity vector to new direction // Adjust velocity vector to new direction
self->VelFromAngle(newangle, self->Speed); self->VelFromAngle(self->Speed, newangle);
if (pr_batmove()<15) if (pr_batmove()<15)
{ {

View file

@ -162,7 +162,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameRotate)
PARAM_SELF_PROLOGUE(AActor); PARAM_SELF_PROLOGUE(AActor);
DAngle an = self->Angles.Yaw + 90.; DAngle an = self->Angles.Yaw + 90.;
self->VelFromAngle(an, FLAMEROTSPEED); self->VelFromAngle(FLAMEROTSPEED, an);
self->Vel += DVector2(self->specialf1, self->specialf2); self->Vel += DVector2(self->specialf1, self->specialf2);
self->Angles.Yaw += 6.; self->Angles.Yaw += 6.;

View file

@ -415,7 +415,7 @@ void P_MinotaurSlam (AActor *source, AActor *target)
angle = source->AngleTo(target); angle = source->AngleTo(target);
thrust = 16 + pr_minotaurslam() / 64.; thrust = 16 + pr_minotaurslam() / 64.;
target->VelFromAngle(angle, thrust); target->VelFromAngle(thrust, angle);
damage = pr_minotaurslam.HitDice (static_cast<AMinotaur *>(source) ? 4 : 6); damage = pr_minotaurslam.HitDice (static_cast<AMinotaur *>(source) ? 4 : 6);
int newdam = P_DamageMobj (target, NULL, NULL, damage, NAME_Melee); int newdam = P_DamageMobj (target, NULL, NULL, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, target, angle, 0.); P_TraceBleed (newdam > 0 ? newdam : damage, target, angle, 0.);

View file

@ -109,7 +109,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_EntityDeath)
second = Spawn("EntitySecond", pos, ALLOW_REPLACE); second = Spawn("EntitySecond", pos, ALLOW_REPLACE);
second->CopyFriendliness(self, true); second->CopyFriendliness(self, true);
A_FaceTarget(second); A_FaceTarget(second);
second->VelFromAngle(an, velmul[i]); second->VelFromAngle(velmul[i], an);
} }
return 0; return 0;
} }

View file

@ -988,7 +988,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil1)
spot = Spawn("SpectralLightningSpot", self->Pos(), ALLOW_REPLACE); spot = Spawn("SpectralLightningSpot", self->Pos(), ALLOW_REPLACE);
if (spot != NULL) if (spot != NULL)
{ {
spot->VelFromAngle(self->Angles.Yaw, 28.); spot->VelFromAngle(28., self->Angles.Yaw);
} }
} }
if (spot != NULL) if (spot != NULL)
@ -1089,7 +1089,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil4)
spot = P_SpawnPlayerMissile (self, PClass::FindActor("SpectralLightningBigV1")); spot = P_SpawnPlayerMissile (self, PClass::FindActor("SpectralLightningBigV1"));
if (spot != NULL) if (spot != NULL)
{ {
spot->VelFromAngle(self->Angles.Yaw, spot->Speed); spot->VelFromAngle(spot->Speed, self->Angles.Yaw);
} }
} }
return 0; return 0;

View file

@ -78,7 +78,7 @@ bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info,
ActionCycles.Clock(); ActionCycles.Clock();
VMFrameStack stack; VMFrameStack stack;
VMValue params[3] = { self, stateowner, VMValue(info, ATAG_STATEINFO) }; VMValue params[3] = { self, stateowner, VMValue(info, ATAG_GENERIC) };
// If the function returns a state, store it at *stateret. // If the function returns a state, store it at *stateret.
// If it doesn't return a state but stateret is non-NULL, we need // If it doesn't return a state but stateret is non-NULL, we need
// to set *stateret to NULL. // to set *stateret to NULL.

View file

@ -137,7 +137,7 @@ bool ACustomInventory::CallStateChain (AActor *actor, FState *state)
VMReturn *wantret; VMReturn *wantret;
FStateParamInfo stp = { state, STATE_StateChain, PSP_WEAPON }; FStateParamInfo stp = { state, STATE_StateChain, PSP_WEAPON };
params[2] = VMValue(&stp, ATAG_STATEINFO); params[2] = VMValue(&stp, ATAG_GENERIC);
retval = true; // assume success retval = true; // assume success
wantret = NULL; // assume no return value wanted wantret = NULL; // assume no return value wanted
numret = 0; numret = 0;
@ -4218,15 +4218,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF)
PARAM_SELF_PROLOGUE(AActor); PARAM_SELF_PROLOGUE(AActor);
PARAM_STATE (jump); PARAM_STATE (jump);
PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_DEF (flags)
PARAM_FLOAT_OPT (range) { range = 0; } PARAM_FLOAT_DEF (range)
PARAM_FLOAT_OPT (minrange) { minrange = 0; } PARAM_FLOAT_DEF (minrange)
PARAM_ANGLE_OPT (angle) { angle = 0.; } PARAM_ANGLE_DEF (angle)
PARAM_ANGLE_OPT (pitch) { pitch = 0.; } PARAM_ANGLE_DEF (pitch)
PARAM_FLOAT_OPT (offsetheight) { offsetheight = 0; } PARAM_FLOAT_DEF (offsetheight)
PARAM_FLOAT_OPT (offsetwidth) { offsetwidth = 0; } PARAM_FLOAT_DEF (offsetwidth)
PARAM_INT_OPT (ptr_target) { ptr_target = AAPTR_DEFAULT; } PARAM_INT_DEF (ptr_target)
PARAM_FLOAT_OPT (offsetforward) { offsetforward = 0; } PARAM_FLOAT_DEF (offsetforward)
DAngle ang; DAngle ang;

View file

@ -2500,7 +2500,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
DAngle ang = actor->AngleTo(actor->target); DAngle ang = actor->AngleTo(actor->target);
if (pr_chase() < 128) ang += 90.; if (pr_chase() < 128) ang += 90.;
else ang -= 90.; else ang -= 90.;
actor->VelFromAngle(ang, 13.); actor->VelFromAngle(13., ang);
actor->FastChaseStrafeCount = 3; // strafe time actor->FastChaseStrafeCount = 3; // strafe time
} }
} }
@ -3315,16 +3315,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_Pain)
return 0; return 0;
} }
// killough 11/98: kill an object
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Die)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_NAME_OPT (damagetype) { damagetype = NAME_None; }
P_DamageMobj(self, NULL, NULL, self->health, damagetype, DMG_FORCED);
return 0;
}
// //
// A_Detonate // A_Detonate
// killough 8/9/98: same as A_Explode, except that the damage is variable // killough 8/9/98: same as A_Explode, except that the damage is variable

View file

@ -1562,8 +1562,8 @@ DEFINE_ACTION_FUNCTION(AActor, DamageMobj)
PARAM_OBJECT(source, AActor); PARAM_OBJECT(source, AActor);
PARAM_INT(damage); PARAM_INT(damage);
PARAM_NAME(mod); PARAM_NAME(mod);
PARAM_INT_OPT(flags) { flags = 0; } PARAM_INT_DEF(flags);
PARAM_FLOAT_OPT(angle) { angle = 0; } PARAM_FLOAT_DEF(angle);
ACTION_RETURN_INT(P_DamageMobj(self, inflictor, source, damage, mod, flags, angle)); ACTION_RETURN_INT(P_DamageMobj(self, inflictor, source, damage, mod, flags, angle));
} }

View file

@ -4048,11 +4048,11 @@ DEFINE_ACTION_FUNCTION(AActor, AimLineAttack)
PARAM_SELF_PROLOGUE(AActor); PARAM_SELF_PROLOGUE(AActor);
PARAM_ANGLE(angle); PARAM_ANGLE(angle);
PARAM_FLOAT(distance); PARAM_FLOAT(distance);
PARAM_POINTER_OPT(pLineTarget, FTranslatedLineTarget) { pLineTarget = nullptr; } PARAM_POINTER_DEF(pLineTarget, FTranslatedLineTarget);
PARAM_ANGLE_OPT(vrange) { vrange = 0.; } PARAM_ANGLE_DEF(vrange);
PARAM_INT_OPT(flags) { flags = 0; } PARAM_INT_DEF(flags);
PARAM_OBJECT_OPT(target, AActor) { target = nullptr; } PARAM_OBJECT_DEF(target, AActor);
PARAM_OBJECT_OPT(friender, AActor) { friender = nullptr; } PARAM_OBJECT_DEF(friender, AActor);
ACTION_RETURN_FLOAT(P_AimLineAttack(self, angle, distance, pLineTarget, vrange, flags, target, friender).Degrees); ACTION_RETURN_FLOAT(P_AimLineAttack(self, angle, distance, pLineTarget, vrange, flags, target, friender).Degrees);
} }
@ -4431,8 +4431,8 @@ DEFINE_ACTION_FUNCTION(AActor, LineAttack)
PARAM_INT(damage); PARAM_INT(damage);
PARAM_NAME(damageType); PARAM_NAME(damageType);
PARAM_CLASS(puffType, AActor); PARAM_CLASS(puffType, AActor);
PARAM_INT_OPT(flags) { flags = 0; } PARAM_INT_DEF(flags);
PARAM_POINTER_OPT(victim, FTranslatedLineTarget) { victim = nullptr; } PARAM_POINTER_DEF(victim, FTranslatedLineTarget);
int acdmg; int acdmg;
auto puff = P_LineAttack(self, angle, distance, pitch, damage, damageType, puffType, flags, victim, &acdmg); auto puff = P_LineAttack(self, angle, distance, pitch, damage, damageType, puffType, flags, victim, &acdmg);

View file

@ -5838,7 +5838,7 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnMissile)
PARAM_SELF_PROLOGUE(AActor); PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(dest, AActor); PARAM_OBJECT(dest, AActor);
PARAM_CLASS(type, AActor); PARAM_CLASS(type, AActor);
PARAM_OBJECT_OPT(owner, AActor) { owner = self; } PARAM_OBJECT_DEF(owner, AActor);
ACTION_RETURN_OBJECT(P_SpawnMissile(self, dest, type, owner)); ACTION_RETURN_OBJECT(P_SpawnMissile(self, dest, type, owner));
} }
@ -6584,6 +6584,31 @@ void AActor::SetTranslation(const char *trname)
// silently ignore if the name does not exist, this would create some insane message spam otherwise. // silently ignore if the name does not exist, this would create some insane message spam otherwise.
} }
// This combines all 3 variations of the internal function
DEFINE_ACTION_FUNCTION(AActor, VelFromAngle)
{
PARAM_SELF_PROLOGUE(AActor);
if (numparam == 1)
{
self->VelFromAngle();
}
else
{
PARAM_FLOAT(speed);
if (numparam == 2)
{
self->VelFromAngle(speed);
}
else
{
PARAM_ANGLE(angle);
self->VelFromAngle(speed, angle);
}
}
return 0;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// //
// DropItem handling // DropItem handling

View file

@ -159,7 +159,6 @@ enum
ATAG_AREGISTER, // pointer to an address register ATAG_AREGISTER, // pointer to an address register
ATAG_STATE, // pointer to FState ATAG_STATE, // pointer to FState
ATAG_STATEINFO, // FState plus some info.
ATAG_RNG, // pointer to FRandom ATAG_RNG, // pointer to FRandom
}; };
@ -929,7 +928,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
#define ASSERTINT(p) assert((p).Type == REGT_INT) #define ASSERTINT(p) assert((p).Type == REGT_INT)
#define ASSERTFLOAT(p) assert((p).Type == REGT_FLOAT) #define ASSERTFLOAT(p) assert((p).Type == REGT_FLOAT)
#define ASSERTSTRING(p) assert((p).Type == REGT_STRING) #define ASSERTSTRING(p) assert((p).Type == REGT_STRING)
#define ASSERTOBJECT(p) assert((p).Type == REGT_POINTER && (p).atag == ATAG_OBJECT) #define ASSERTOBJECT(p) assert((p).Type == REGT_POINTER && ((p).atag == ATAG_OBJECT || (p).a == nullptr))
#define ASSERTPOINTER(p) assert((p).Type == REGT_POINTER && (p).atag == ATAG_GENERIC) #define ASSERTPOINTER(p) assert((p).Type == REGT_POINTER && (p).atag == ATAG_GENERIC)
#define ASSERTSTATE(p) assert((p).Type == REGT_POINTER && ((p).atag == ATAG_GENERIC || (p).atag == ATAG_STATE)) #define ASSERTSTATE(p) assert((p).Type == REGT_POINTER && ((p).atag == ATAG_GENERIC || (p).atag == ATAG_STATE))
@ -950,14 +949,9 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
#define PARAM_BOOL_OPT_AT(p,x) bool x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_INT); x = !!param[p].i; } else #define PARAM_BOOL_OPT_AT(p,x) bool x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_INT); x = !!param[p].i; } else
#define PARAM_NAME_OPT_AT(p,x) FName x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_INT); x = ENamedName(param[p].i); } else #define PARAM_NAME_OPT_AT(p,x) FName x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_INT); x = ENamedName(param[p].i); } else
#define PARAM_SOUND_OPT_AT(p,x) FSoundID x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_INT); x = FSoundID(param[p].i); } else #define PARAM_SOUND_OPT_AT(p,x) FSoundID x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_INT); x = FSoundID(param[p].i); } else
#define PARAM_COLOR_OPT_AT(p,x) PalEntry x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_INT); x.d = param[p].i; } else
#define PARAM_FLOAT_OPT_AT(p,x) double x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = param[p].f; } else #define PARAM_FLOAT_OPT_AT(p,x) double x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = param[p].f; } else
#define PARAM_ANGLE_OPT_AT(p,x) DAngle x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = param[p].f; } else #define PARAM_ANGLE_OPT_AT(p,x) DAngle x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = param[p].f; } else
#define PARAM_STRING_OPT_AT(p,x) FString x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_STRING); x = param[p].s(); } else
#define PARAM_STATE_OPT_AT(p,x) FState *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATE || param[p].atag == ATAG_GENERIC || param[p].a == NULL)); x = (FState *)param[p].a; } else #define PARAM_STATE_OPT_AT(p,x) FState *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATE || param[p].atag == ATAG_GENERIC || param[p].a == NULL)); x = (FState *)param[p].a; } else
#define PARAM_STATEINFO_OPT_AT(p,x) FStateParamInfo *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATEINFO || param[p].atag == ATAG_GENERIC || param[p].a == NULL)); x = (FStateParamInfo *)param[p].a; } else
#define PARAM_POINTER_OPT_AT(p,x,type) type *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER); x = (type *)param[p].a; } else
#define PARAM_OBJECT_OPT_AT(p,x,type) type *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type))); } else
#define PARAM_CLASS_OPT_AT(p,x,base) base::MetaClass *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); x = (base::MetaClass *)param[p].a; assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base))); } else #define PARAM_CLASS_OPT_AT(p,x,base) base::MetaClass *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); x = (base::MetaClass *)param[p].a; assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base))); } else
// The above, but with an automatically increasing position index. // The above, but with an automatically increasing position index.
@ -985,7 +979,6 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
#define PARAM_ANGLE_DEF(x) ++paramnum; PARAM_ANGLE_DEF_AT(paramnum,x) #define PARAM_ANGLE_DEF(x) ++paramnum; PARAM_ANGLE_DEF_AT(paramnum,x)
#define PARAM_STRING_DEF(x) ++paramnum; PARAM_STRING_DEF_AT(paramnum,x) #define PARAM_STRING_DEF(x) ++paramnum; PARAM_STRING_DEF_AT(paramnum,x)
#define PARAM_STATE_DEF(x) ++paramnum; PARAM_STATE_DEF_AT(paramnum,x) #define PARAM_STATE_DEF(x) ++paramnum; PARAM_STATE_DEF_AT(paramnum,x)
#define PARAM_STATEINFO_DEF(x) ++paramnum; PARAM_STATEINFO_DEF_AT(paramnum,x)
#define PARAM_POINTER_DEF(x,type) ++paramnum; PARAM_POINTER_DEF_AT(paramnum,x,type) #define PARAM_POINTER_DEF(x,type) ++paramnum; PARAM_POINTER_DEF_AT(paramnum,x,type)
#define PARAM_OBJECT_DEF(x,type) ++paramnum; PARAM_OBJECT_DEF_AT(paramnum,x,type) #define PARAM_OBJECT_DEF(x,type) ++paramnum; PARAM_OBJECT_DEF_AT(paramnum,x,type)
#define PARAM_CLASS_DEF(x,base) ++paramnum; PARAM_CLASS_DEF_AT(paramnum,x,base) #define PARAM_CLASS_DEF(x,base) ++paramnum; PARAM_CLASS_DEF_AT(paramnum,x,base)
@ -994,14 +987,9 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
#define PARAM_BOOL_OPT(x) ++paramnum; PARAM_BOOL_OPT_AT(paramnum,x) #define PARAM_BOOL_OPT(x) ++paramnum; PARAM_BOOL_OPT_AT(paramnum,x)
#define PARAM_NAME_OPT(x) ++paramnum; PARAM_NAME_OPT_AT(paramnum,x) #define PARAM_NAME_OPT(x) ++paramnum; PARAM_NAME_OPT_AT(paramnum,x)
#define PARAM_SOUND_OPT(x) ++paramnum; PARAM_SOUND_OPT_AT(paramnum,x) #define PARAM_SOUND_OPT(x) ++paramnum; PARAM_SOUND_OPT_AT(paramnum,x)
#define PARAM_COLOR_OPT(x) ++paramnum; PARAM_COLOR_OPT_AT(paramnum,x)
#define PARAM_FLOAT_OPT(x) ++paramnum; PARAM_FLOAT_OPT_AT(paramnum,x) #define PARAM_FLOAT_OPT(x) ++paramnum; PARAM_FLOAT_OPT_AT(paramnum,x)
#define PARAM_ANGLE_OPT(x) ++paramnum; PARAM_ANGLE_OPT_AT(paramnum,x) #define PARAM_ANGLE_OPT(x) ++paramnum; PARAM_ANGLE_OPT_AT(paramnum,x)
#define PARAM_STRING_OPT(x) ++paramnum; PARAM_STRING_OPT_AT(paramnum,x)
#define PARAM_STATE_OPT(x) ++paramnum; PARAM_STATE_OPT_AT(paramnum,x) #define PARAM_STATE_OPT(x) ++paramnum; PARAM_STATE_OPT_AT(paramnum,x)
#define PARAM_STATEINFO_OPT(x) ++paramnum; PARAM_STATEINFO_OPT_AT(paramnum,x)
#define PARAM_POINTER_OPT(x,type) ++paramnum; PARAM_POINTER_OPT_AT(paramnum,x,type)
#define PARAM_OBJECT_OPT(x,type) ++paramnum; PARAM_OBJECT_OPT_AT(paramnum,x,type)
#define PARAM_CLASS_OPT(x,base) ++paramnum; PARAM_CLASS_OPT_AT(paramnum,x,base) #define PARAM_CLASS_OPT(x,base) ++paramnum; PARAM_CLASS_OPT_AT(paramnum,x,base)
typedef int(*actionf_p)(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret);/*(VM_ARGS)*/ typedef int(*actionf_p)(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret);/*(VM_ARGS)*/
@ -1043,7 +1031,7 @@ struct AFuncDesc
//#define PUSH_PARAMINFO self, stateowner, CallingState, ParameterIndex, statecall //#define PUSH_PARAMINFO self, stateowner, CallingState, ParameterIndex, statecall
#define CALL_ACTION(name,self) { /*AF_##name(self, self, NULL, 0, NULL)*/ \ #define CALL_ACTION(name,self) { /*AF_##name(self, self, NULL, 0, NULL)*/ \
VMValue params[3] = { self, self, VMValue(NULL, ATAG_STATEINFO) }; \ VMValue params[3] = { self, self, VMValue(NULL, ATAG_GENERIC) }; \
stack->Call(name##_VMPtr, params, countof(params), NULL, 0, NULL); \ stack->Call(name##_VMPtr, params, countof(params), NULL, 0, NULL); \
} }
@ -1066,8 +1054,8 @@ struct AFuncDesc
#define PARAM_ACTION_PROLOGUE(type) \ #define PARAM_ACTION_PROLOGUE(type) \
PARAM_PROLOGUE; \ PARAM_PROLOGUE; \
PARAM_OBJECT (self, type); \ PARAM_OBJECT (self, type); \
PARAM_OBJECT_OPT (stateowner, AActor) { stateowner = self; } \ PARAM_OBJECT (stateowner, AActor) \
PARAM_STATEINFO_OPT (stateinfo) { stateinfo = nullptr; } \ PARAM_POINTER (stateinfo, FStateParamInfo) \
// Number of action paramaters // Number of action paramaters
#define NAP 3 #define NAP 3

View file

@ -188,7 +188,7 @@ void VMFillParams(VMValue *params, VMFrame *callee, int numparam)
const VMRegisters calleereg(callee); const VMRegisters calleereg(callee);
assert(calleefunc != NULL && !calleefunc->Native); assert(calleefunc != NULL && !calleefunc->Native);
assert(numparam == calleefunc->NumArgs || ((int)calleefunc->Defaults.Size() == numparam)); assert(numparam == calleefunc->NumArgs || ((int)calleefunc->Defaults.Size() == calleefunc->NumArgs));
assert(REGT_INT == 0 && REGT_FLOAT == 1 && REGT_STRING == 2 && REGT_POINTER == 3); assert(REGT_INT == 0 && REGT_FLOAT == 1 && REGT_STRING == 2 && REGT_POINTER == 3);
regd = regf = regs = rega = 0; regd = regf = regs = rega = 0;

View file

@ -65,6 +65,7 @@ class Actor : Thinker native
native bool SetState(state st, bool nofunction = false); native bool SetState(state st, bool nofunction = false);
native void LinkToWorld(); native void LinkToWorld();
native void UnlinkFromWorld(); native void UnlinkFromWorld();
native void VelFromAngle(float speed = 0, float angle = 0);
// DECORATE compatible functions // DECORATE compatible functions
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false); native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
@ -166,6 +167,12 @@ class Actor : Thinker native
LinkToWorld(); LinkToWorld();
} }
// killough 11/98: kill an object
void A_Die(name damagetype = "none")
{
DamageMobj(null, null, health, damagetype, DMG_FORCED);
}
// Action functions // Action functions
// Meh, MBF redundant functions. Only for DeHackEd support. // Meh, MBF redundant functions. Only for DeHackEd support.
native bool A_LineEffect(int boomspecial = 0, int tag = 0); native bool A_LineEffect(int boomspecial = 0, int tag = 0);
@ -193,10 +200,6 @@ class Actor : Thinker native
native void A_SkelWhoosh(); native void A_SkelWhoosh();
native void A_SkelFist(); native void A_SkelFist();
native void A_SkelMissile(); native void A_SkelMissile();
native void A_FatRaise();
native void A_FatAttack1(class<Actor> spawntype = "FatShot");
native void A_FatAttack2(class<Actor> spawntype = "FatShot");
native void A_FatAttack3(class<Actor> spawntype = "FatShot");
native void A_BossDeath(); native void A_BossDeath();
native void A_SkullAttack(float speed = 20); native void A_SkullAttack(float speed = 20);
native void A_BetaSkullAttack(); native void A_BetaSkullAttack();
@ -212,7 +215,6 @@ class Actor : Thinker native
native void A_SpawnSound(); native void A_SpawnSound();
native void A_SpawnFly(class<Actor> spawntype = null); // needs special treatment for default native void A_SpawnFly(class<Actor> spawntype = null); // needs special treatment for default
native void A_BrainExplode(); native void A_BrainExplode();
native void A_Die(name damagetype = "none");
native void A_Detonate(); native void A_Detonate();
native void A_Mushroom(class<Actor> spawntype = "FatShot", int numspawns = 0, int flags = 0, float vrange = 4.0, float hrange = 0.5); native void A_Mushroom(class<Actor> spawntype = "FatShot", int numspawns = 0, int flags = 0, float vrange = 4.0, float hrange = 0.5);
native bool A_CallSpecial(int special, int arg1=0, int arg2=0, int arg3=0, int arg4=0, int arg5=0); native bool A_CallSpecial(int special, int arg1=0, int arg2=0, int arg3=0, int arg4=0, int arg5=0);

View file

@ -862,3 +862,17 @@ enum ESightFlags
SF_SEEPASTBLOCKEVERYTHING=4, SF_SEEPASTBLOCKEVERYTHING=4,
SF_IGNOREWATERBOUNDARY=8 SF_IGNOREWATERBOUNDARY=8
} }
enum EDmgFlags
{
DMG_NO_ARMOR = 1,
DMG_INFLICTOR_IS_PUFF = 2,
DMG_THRUSTLESS = 4,
DMG_FORCED = 8,
DMG_NO_FACTOR = 16,
DMG_PLAYERATTACK = 32,
DMG_FOILINVUL = 64,
DMG_FOILBUDDHA = 128,
DMG_NO_PROTECT = 256,
DMG_USEANGLE = 512,
}

View file

@ -93,3 +93,75 @@ class FatShot : Actor
} }
//===========================================================================
//
// Code (must be attached to Actor)
//
//===========================================================================
extend class Actor
{
const FATSPREAD = 90./8;
void A_FatRaise()
{
A_FaceTarget();
A_PlaySound("fatso/raiseguns", CHAN_WEAPON);
}
void A_FatAttack1(class<Actor> spawntype = "FatShot")
{
if (target)
{
A_FaceTarget ();
// Change direction to ...
Angle += FATSPREAD;
SpawnMissile (target, spawntype);
Actor missile = SpawnMissile (target, spawntype);
if (missile)
{
missile.Angle += FATSPREAD;
missile.VelFromAngle();
}
}
}
void A_FatAttack2(class<Actor> spawntype = "FatShot")
{
if (target)
{
A_FaceTarget ();
// Now here choose opposite deviation.
Angle -= FATSPREAD;
SpawnMissile (target, spawntype);
Actor missile = SpawnMissile (target, spawntype);
if (missile)
{
missile.Angle -= FATSPREAD;
missile.VelFromAngle();
}
}
}
void A_FatAttack3(class<Actor> spawntype = "FatShot")
{
if (target)
{
A_FaceTarget ();
Actor missile = SpawnMissile (target, spawntype);
if (missile)
{
missile.Angle -= FATSPREAD/2;
missile.VelFromAngle();
}
missile = SpawnMissile (target, spawntype);
if (missile)
{
missile.Angle += FATSPREAD/2;
missile.VelFromAngle();
}
}
}
}