mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 07:12:16 +00:00
- fixed damage handling in A_BetaSkullAttack. For unknown reasons this completely bypassed the normal damage function semantics and even multiplied that with a random value.
- made some tests about calling script code from native functions. * scriptified A_SkullAttack to have something to test * changed the A_SkullAttack call in A_PainShootSkull. * use a macro to declare the function pointer. Using local static variable init directly results in hideous code for the need of being thread-safe (which, even if the engine was made multithreaded is not needed here.) * Importsnt node here: Apparently passing an actor pointer to the VMValue constructor results in the void * version being called, not the DObject * version.
This commit is contained in:
parent
dbde0971ef
commit
062574b726
12 changed files with 97 additions and 98 deletions
|
@ -24,7 +24,6 @@
|
||||||
// Include all the other Doom stuff here to reduce compile time
|
// Include all the other Doom stuff here to reduce compile time
|
||||||
#include "a_bossbrain.cpp"
|
#include "a_bossbrain.cpp"
|
||||||
#include "a_doomweaps.cpp"
|
#include "a_doomweaps.cpp"
|
||||||
#include "a_lostsoul.cpp"
|
|
||||||
#include "a_painelemental.cpp"
|
#include "a_painelemental.cpp"
|
||||||
#include "a_revenant.cpp"
|
#include "a_revenant.cpp"
|
||||||
#include "a_scriptedmarine.cpp"
|
#include "a_scriptedmarine.cpp"
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
/*
|
|
||||||
#include "templates.h"
|
|
||||||
#include "actor.h"
|
|
||||||
#include "info.h"
|
|
||||||
#include "m_random.h"
|
|
||||||
#include "s_sound.h"
|
|
||||||
#include "p_local.h"
|
|
||||||
#include "p_enemy.h"
|
|
||||||
#include "gi.h"
|
|
||||||
#include "gstrings.h"
|
|
||||||
#include "a_action.h"
|
|
||||||
#include "vm.h"
|
|
||||||
*/
|
|
||||||
|
|
||||||
FRandom pr_oldsoul ("BetaLostSoul");
|
|
||||||
|
|
||||||
//
|
|
||||||
// SkullAttack
|
|
||||||
// Fly at the player like a missile.
|
|
||||||
//
|
|
||||||
|
|
||||||
void A_SkullAttack(AActor *self, double speed)
|
|
||||||
{
|
|
||||||
AActor *dest;
|
|
||||||
if (!self->target)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dest = self->target;
|
|
||||||
self->flags |= MF_SKULLFLY;
|
|
||||||
|
|
||||||
S_Sound (self, CHAN_VOICE, self->AttackSound, 1, ATTN_NORM);
|
|
||||||
A_FaceTarget (self);
|
|
||||||
self->VelFromAngle(speed);
|
|
||||||
self->Vel.Z = (dest->Center() - self->Z()) / self->DistanceBySpeed(dest, speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullAttack)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
PARAM_FLOAT_DEF(speed);
|
|
||||||
|
|
||||||
if (speed <= 0)
|
|
||||||
speed = SKULLSPEED;
|
|
||||||
A_SkullAttack(self, speed);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_BetaSkullAttack)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
int damage;
|
|
||||||
if (!self || !self->target || self->target->GetSpecies() == self->GetSpecies())
|
|
||||||
return 0;
|
|
||||||
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
|
|
||||||
A_FaceTarget(self);
|
|
||||||
damage = (pr_oldsoul()%8+1)*self->GetMissileDamage(0,1);
|
|
||||||
P_DamageMobj(self->target, self, self, damage, NAME_None);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// CVAR transsouls
|
|
||||||
//
|
|
||||||
// How translucent things drawn with STYLE_SoulTrans are. Normally, only
|
|
||||||
// Lost Souls have this render style, but a dehacked patch could give other
|
|
||||||
// things this style. Values less than 0.25 will automatically be set to
|
|
||||||
// 0.25 to ensure some degree of visibility. Likewise, values above 1.0 will
|
|
||||||
// be set to 1.0, because anything higher doesn't make sense.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
CUSTOM_CVAR (Float, transsouls, 0.75f, CVAR_ARCHIVE)
|
|
||||||
{
|
|
||||||
if (self < 0.25f)
|
|
||||||
{
|
|
||||||
self = 0.25f;
|
|
||||||
}
|
|
||||||
else if (self > 1.f)
|
|
||||||
{
|
|
||||||
self = 1.f;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -21,7 +21,7 @@ enum PA_Flags
|
||||||
// A_PainShootSkull
|
// A_PainShootSkull
|
||||||
// Spawn a lost soul and launch it at the target
|
// Spawn a lost soul and launch it at the target
|
||||||
//
|
//
|
||||||
void A_PainShootSkull (AActor *self, DAngle Angle, PClassActor *spawntype, int flags = 0, int limit = -1)
|
void A_PainShootSkull (VMFrameStack *stack, AActor *self, DAngle Angle, PClassActor *spawntype, int flags = 0, int limit = -1)
|
||||||
{
|
{
|
||||||
AActor *other;
|
AActor *other;
|
||||||
double prestep;
|
double prestep;
|
||||||
|
@ -137,7 +137,10 @@ void A_PainShootSkull (AActor *self, DAngle Angle, PClassActor *spawntype, int f
|
||||||
other->CopyFriendliness (self, !(flags & PAF_NOTARGET));
|
other->CopyFriendliness (self, !(flags & PAF_NOTARGET));
|
||||||
|
|
||||||
if (!(flags & PAF_NOSKULLATTACK))
|
if (!(flags & PAF_NOSKULLATTACK))
|
||||||
A_SkullAttack(other, SKULLSPEED);
|
{
|
||||||
|
DECLARE_VMFUNC(AActor, A_SkullAttack);
|
||||||
|
CallAction(stack, A_SkullAttack, other);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,7 +151,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_PainShootSkull)
|
||||||
PARAM_FLOAT(angle);
|
PARAM_FLOAT(angle);
|
||||||
PARAM_INT_DEF(flags);
|
PARAM_INT_DEF(flags);
|
||||||
PARAM_INT_DEF(limit);
|
PARAM_INT_DEF(limit);
|
||||||
A_PainShootSkull(self, angle, spawntype, flags, limit);
|
A_PainShootSkull(stack, self, angle, spawntype, flags, limit);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ cycle_t ActionCycles;
|
||||||
|
|
||||||
void FState::SetAction(const char *name)
|
void FState::SetAction(const char *name)
|
||||||
{
|
{
|
||||||
ActionFunc = FindGlobalActionFunction(name)->Variants[0].Implementation;
|
ActionFunc = FindVMFunction(RUNTIME_CLASS(AActor), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret)
|
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret)
|
||||||
|
|
|
@ -6445,6 +6445,12 @@ FName AActor::GetSpecies()
|
||||||
return Species = thistype->TypeName; // [GZ] Speeds up future calls.
|
return Species = thistype->TypeName; // [GZ] Speeds up future calls.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(AActor, GetSpecies)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
ACTION_RETURN_INT(self->GetSpecies());
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// AActor :: IsFriend
|
// AActor :: IsFriend
|
||||||
|
@ -6850,6 +6856,14 @@ DEFINE_ACTION_FUNCTION(AActor, VelFromAngle)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(AActor, DistanceBySpeed)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
PARAM_OBJECT(targ, AActor);
|
||||||
|
PARAM_FLOAT(speed);
|
||||||
|
ACTION_RETURN_FLOAT(self->DistanceBySpeed(targ, speed));
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, SetXYZ)
|
DEFINE_ACTION_FUNCTION(AActor, SetXYZ)
|
||||||
{
|
{
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
@ -6879,6 +6893,7 @@ DEFINE_ACTION_FUNCTION(AActor, Vec2OffsetZ)
|
||||||
PARAM_BOOL_DEF(absolute);
|
PARAM_BOOL_DEF(absolute);
|
||||||
ACTION_RETURN_VEC3(self->Vec2OffsetZ(x, y, z, absolute));
|
ACTION_RETURN_VEC3(self->Vec2OffsetZ(x, y, z, absolute));
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// DropItem handling
|
// DropItem handling
|
||||||
|
|
|
@ -1104,3 +1104,27 @@ void FCanvasTextureInfo::Mark()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// CVAR transsouls
|
||||||
|
//
|
||||||
|
// How translucent things drawn with STYLE_SoulTrans are. Normally, only
|
||||||
|
// Lost Souls have this render style.
|
||||||
|
// Values less than 0.25 will automatically be set to
|
||||||
|
// 0.25 to ensure some degree of visibility. Likewise, values above 1.0 will
|
||||||
|
// be set to 1.0, because anything higher doesn't make sense.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
CUSTOM_CVAR(Float, transsouls, 0.75f, CVAR_ARCHIVE)
|
||||||
|
{
|
||||||
|
if (self < 0.25f)
|
||||||
|
{
|
||||||
|
self = 0.25f;
|
||||||
|
}
|
||||||
|
else if (self > 1.f)
|
||||||
|
{
|
||||||
|
self = 1.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -99,7 +99,9 @@ FxVMFunctionCall *DoActionSpecials(FScanner &sc, FState & state, Baggage &bag)
|
||||||
{
|
{
|
||||||
sc.ScriptError ("Too many arguments to %s", specname.GetChars());
|
sc.ScriptError ("Too many arguments to %s", specname.GetChars());
|
||||||
}
|
}
|
||||||
return new FxVMFunctionCall(new FxSelf(sc), FindGlobalActionFunction("A_CallSpecial"), args, sc, false);
|
auto f = dyn_cast<PFunction>(RUNTIME_CLASS(AActor)->Symbols.FindSymbol("A_CallSpecial", false));
|
||||||
|
assert(f != nullptr);
|
||||||
|
return new FxVMFunctionCall(new FxSelf(sc), f, args, sc, false);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -602,9 +602,10 @@ AFuncDesc *FindFunction(const char * string)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
PFunction *FindGlobalActionFunction(const char *name)
|
VMFunction *FindVMFunction(PClass *cls, const char *name)
|
||||||
{
|
{
|
||||||
return dyn_cast<PFunction>(RUNTIME_CLASS(AActor)->Symbols.FindSymbol(name, false));
|
auto f = dyn_cast<PFunction>(cls->Symbols.FindSymbol(name, true));
|
||||||
|
return f == nullptr ? nullptr : f->Variants[0].Implementation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1071,7 +1071,8 @@ void CallAction(VMFrameStack *stack, VMFunction *vmfunc, AActor *self);
|
||||||
|
|
||||||
class PFunction;
|
class PFunction;
|
||||||
|
|
||||||
PFunction *FindGlobalActionFunction(const char *name);
|
VMFunction *FindVMFunction(PClass *cls, const char *name);
|
||||||
|
#define DECLARE_VMFUNC(cls, name) static VMFunction *name; if (name == nullptr) name = FindVMFunction(RUNTIME_CLASS(cls), #name);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -495,6 +495,7 @@ int VMFrameStack::Call(VMFunction *func, VMValue *params, int numparams, VMRetur
|
||||||
class AActor;
|
class AActor;
|
||||||
void CallAction(VMFrameStack *stack, VMFunction *vmfunc, AActor *self)
|
void CallAction(VMFrameStack *stack, VMFunction *vmfunc, AActor *self)
|
||||||
{
|
{
|
||||||
VMValue params[3] = { self, self, VMValue(nullptr, ATAG_GENERIC) };
|
// Without the type cast this picks the 'void *' assignment...
|
||||||
|
VMValue params[3] = { (DObject*)self, (DObject*)self, VMValue(nullptr, ATAG_GENERIC) };
|
||||||
stack->Call(vmfunc, params, vmfunc->ImplicitArgs, nullptr, 0, nullptr);
|
stack->Call(vmfunc, params, vmfunc->ImplicitArgs, nullptr, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,8 @@ class Actor : Thinker native
|
||||||
native void CopyFriendliness (Actor other, bool changeTarget, bool resetHealth = true);
|
native void CopyFriendliness (Actor other, bool changeTarget, bool resetHealth = true);
|
||||||
native bool LookForPlayers(bool allaround);
|
native bool LookForPlayers(bool allaround);
|
||||||
native bool TeleportMove(Vector3 pos, bool telefrag, bool modifyactor = true);
|
native bool TeleportMove(Vector3 pos, bool telefrag, bool modifyactor = true);
|
||||||
|
native double DistanceBySpeed(Actor other, double speed);
|
||||||
|
native name GetSpecies();
|
||||||
|
|
||||||
// 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);
|
||||||
|
@ -241,8 +243,6 @@ class Actor : Thinker native
|
||||||
native void A_SkelFist();
|
native void A_SkelFist();
|
||||||
native void A_SkelMissile();
|
native void A_SkelMissile();
|
||||||
native void A_BossDeath();
|
native void A_BossDeath();
|
||||||
native void A_SkullAttack(float speed = 20);
|
|
||||||
native void A_BetaSkullAttack();
|
|
||||||
native void A_Detonate();
|
native void A_Detonate();
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -81,3 +81,41 @@ class BetaSkull : LostSoul
|
||||||
Wait;
|
Wait;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Code (must be attached to Actor)
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
extend class Actor
|
||||||
|
{
|
||||||
|
const SKULLSPEED = 20;
|
||||||
|
|
||||||
|
void A_SkullAttack(float skullspeed = SKULLSPEED)
|
||||||
|
{
|
||||||
|
if (target == null) return;
|
||||||
|
|
||||||
|
if (skullspeed <= 0) skullspeed = SKULLSPEED;
|
||||||
|
|
||||||
|
bSkullfly = true;
|
||||||
|
A_PlaySound(AttackSound, CHAN_VOICE);
|
||||||
|
A_FaceTarget();
|
||||||
|
VelFromAngle(skullspeed);
|
||||||
|
Vel.Z = (target.pos.Z + target.Height/2 - Vel.Z) / DistanceBySpeed(target, speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void A_BetaSkullAttack()
|
||||||
|
{
|
||||||
|
if (target == null || target.GetSpecies() == self.GetSpecies()) return;
|
||||||
|
|
||||||
|
A_PlaySound(AttackSound, CHAN_WEAPON);
|
||||||
|
A_FaceTarget();
|
||||||
|
|
||||||
|
int damage = GetMissileDamage(7,1);
|
||||||
|
target.DamageMobj(self, self, damage, 'None');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue