- actually evaluate the default parameters and store them in the VMFunction.

- disabled the assert in PType::GetRegType. This assert blocks any use to check for types that are incompatible with function parameters.
- pass the default parameter constants to the native functions. At the moment this is not used yet.
- use the function defaults to complete argument lists to script functions.
- fixed all default values that got flagged by the expression evaluator as non-constant. Most were state labels and colors which were defaulted to "". The proper value is null for states and 0 for colors.
- also replaced all "" defaults for names with "none".
This commit is contained in:
Christoph Oelckers 2016-10-27 01:30:34 +02:00
parent d32d52c0b9
commit 66b1f36e56
12 changed files with 152 additions and 62 deletions

View File

@ -521,7 +521,7 @@ int PType::GetMoveOp() const
int PType::GetRegType() const
{
assert(0 && "No register for this type");
//assert(0 && "No register for this type"); // wrong place for this assert, it makes it impossible to use this function to check for bad types.
return REGT_NIL;
}

View File

@ -96,7 +96,7 @@ FCompileContext::FCompileContext(PFunction *fnc, PPrototype *ret, bool fromdecor
if (fnc != nullptr) Class = fnc->OwningClass;
}
FCompileContext::FCompileContext(PClass *cls) : ReturnProto(nullptr), Function(nullptr), Class(cls), FromDecorate(true) // only used by DECORATE constants.
FCompileContext::FCompileContext(PClass *cls, bool fromdecorate) : ReturnProto(nullptr), Function(nullptr), Class(cls), FromDecorate(fromdecorate)
{
}
@ -3745,7 +3745,7 @@ FxExpression *FxRandom::Resolve(FCompileContext &ctx)
//
//==========================================================================
int DecoRandom(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret)
int DecoRandom(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
{
assert(numparam >= 1 && numparam <= 3);
FRandom *rng = reinterpret_cast<FRandom *>(param[0].a);
@ -3995,7 +3995,7 @@ FxFRandom::FxFRandom(FRandom *r, FxExpression *mi, FxExpression *ma, const FScri
//
//==========================================================================
int DecoFRandom(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret)
int DecoFRandom(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
{
assert(numparam == 1 || numparam == 3);
FRandom *rng = reinterpret_cast<FRandom *>(param[0].a);
@ -5255,7 +5255,7 @@ FxExpression *FxActionSpecialCall::Resolve(FCompileContext& ctx)
//
//==========================================================================
int DecoCallLineSpecial(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret)
int DecoCallLineSpecial(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
{
assert(numparam > 2 && numparam < 8);
assert(param[0].Type == REGT_INT);
@ -6702,7 +6702,7 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx)
//
//==========================================================================
int DecoNameToClass(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret)
int DecoNameToClass(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
{
assert(numparam == 2);
assert(numret == 1);
@ -6842,7 +6842,7 @@ static bool VerifyJumpTarget(AActor *stateowner, FStateParamInfo *stateinfo, int
return false;
}
static int DecoHandleRuntimeState(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret)
static int DecoHandleRuntimeState(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
{
PARAM_PROLOGUE;
PARAM_OBJECT(stateowner, AActor);
@ -7008,7 +7008,7 @@ static int DoFindState(VMFrameStack *stack, VMValue *param, int numparam, VMRetu
}
// Find a state with any number of dots in its name.
int BuiltinFindMultiNameState(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret)
int BuiltinFindMultiNameState(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
{
assert(numparam > 1);
assert(numret == 1);
@ -7024,7 +7024,7 @@ int BuiltinFindMultiNameState(VMFrameStack *stack, VMValue *param, int numparam,
}
// Find a state without any dots in its name.
int BuiltinFindSingleNameState(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret)
int BuiltinFindSingleNameState(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
{
assert(numparam == 2);
assert(numret == 1);

View File

@ -77,7 +77,7 @@ struct FCompileContext
TDeletingArray<FxLocalVariableDeclaration *> FunctionArgs;
FCompileContext(PFunction *func, PPrototype *ret, bool fromdecorate);
FCompileContext(PClass *cls); // only to be used to resolve constants!
FCompileContext(PClass *cls, bool fromdecorate); // only to be used to resolve constants!
PSymbol *FindInClass(FName identifier, PSymbolTable *&symt);
PSymbol *FindInSelfClass(FName identifier, PSymbolTable *&symt);

View File

@ -87,7 +87,7 @@ FxExpression *ParseExpression (FScanner &sc, PClassActor *cls, bool mustresolve)
if (mustresolve)
{
FCompileContext ctx(cls);
FCompileContext ctx(cls, true);
data = data->Resolve(ctx);
}

View File

@ -667,8 +667,8 @@ void InitThingdef()
symt.AddSymbol(new PField(NAME_MomX, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.X)));
symt.AddSymbol(new PField(NAME_MomY, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.Y)));
symt.AddSymbol(new PField(NAME_MomZ, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.Z)));
symt.AddSymbol(new PField(NAME_ScaleX, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Scale.X)));
symt.AddSymbol(new PField(NAME_ScaleY, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Scale.Y)));
symt.AddSymbol(new PField(NAME_ScaleX, TypeFloat64, VARF_Native|VARF_Deprecated, myoffsetof(AActor, Scale.X)));
symt.AddSymbol(new PField(NAME_ScaleY, TypeFloat64, VARF_Native|VARF_Deprecated, myoffsetof(AActor, Scale.Y)));
symt.AddSymbol(new PField(NAME_Score, TypeSInt32, VARF_Native, myoffsetof(AActor, Score)));
symt.AddSymbol(new PField(NAME_Accuracy, TypeSInt32, VARF_Native, myoffsetof(AActor, accuracy)));
symt.AddSymbol(new PField(NAME_Stamina, TypeSInt32, VARF_Native, myoffsetof(AActor, stamina)));

View File

@ -173,20 +173,6 @@ enum EVMAbortException
X_BAD_SELF,
};
class VMFunction : public DObject
{
DECLARE_ABSTRACT_CLASS(VMFunction, DObject);
HAS_OBJECT_POINTERS;
public:
bool Native;
BYTE ImplicitArgs = 0; // either 0 for static, 1 for method or 3 for action
FName Name;
class PPrototype *Proto;
VMFunction(FName name = NAME_None) : Native(false), ImplicitArgs(0), Name(name), Proto(NULL) {}
};
enum EVMOpMode
{
MODE_ASHIFT = 0,
@ -642,6 +628,21 @@ do_double: if (inexact)
}
};
class VMFunction : public DObject
{
DECLARE_ABSTRACT_CLASS(VMFunction, DObject);
HAS_OBJECT_POINTERS;
public:
bool Native;
BYTE ImplicitArgs = 0; // either 0 for static, 1 for method or 3 for action
FName Name;
TArray<VMValue> Defaults;
class PPrototype *Proto;
VMFunction(FName name = NAME_None) : Native(false), ImplicitArgs(0), Name(name), Proto(NULL) {}
};
// VM frame layout:
// VMFrame header
// parameter stack - 16 byte boundary, 16 bytes each
@ -829,7 +830,7 @@ class VMNativeFunction : public VMFunction
{
DECLARE_CLASS(VMNativeFunction, VMFunction);
public:
typedef int (*NativeCallType)(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret);
typedef int (*NativeCallType)(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret);
VMNativeFunction() : NativeCall(NULL) { Native = true; }
VMNativeFunction(NativeCallType call) : NativeCall(call) { Native = true; }
@ -900,8 +901,8 @@ void VMDumpConstants(FILE *out, const VMScriptFunction *func);
void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction *func);
// Use this in the prototype for a native function.
#define VM_ARGS VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret
#define VM_ARGS_NAMES stack, param, numparam, ret, numret
#define VM_ARGS VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret
#define VM_ARGS_NAMES stack, param, defaultparam, numparam, ret, numret
// Use these to collect the parameters in a native function.
// variable name <x> at position <p>
@ -924,6 +925,16 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
// PARAM_INT_OPT(0,myint) { myint = 55; }
// Just make sure to fill it in when using these macros, because the compiler isn't likely
// to give useful error messages if you don't.
#define PARAM_EXISTS ((p) < numparam && param[p].Type != REGT_NIL)
#define ASSERTINT(p) assert((p).Type == REGT_INT)
#define ASSERTFLOAT(p) assert((p).Type == REGT_FLOAT)
#define ASSERTSTRING(p) assert((p).Type == REGT_STRING)
#define ASSERTOBJECT(p) assert((p).Type == REGT_POINTER && (p).atag == ATAG_OBJECT)
#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 PARAM_INT_DEF_AT(p,x) int x; if (PARAM_EXISTS) { ASSERTINT(param[p]); x = param[p].i; } else { ASSERTINT(defaultparam[p]); x = defaultparam[p].i; }
#define PARAM_INT_OPT_AT(p,x) int 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
@ -954,6 +965,20 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
#define PARAM_OBJECT(x,type) ++paramnum; PARAM_OBJECT_AT(paramnum,x,type)
#define PARAM_CLASS(x,base) ++paramnum; PARAM_CLASS_AT(paramnum,x,base)
#define PARAM_INT_DEF(x) ++paramnum; PARAM_INT_DEF_AT(paramnum,x)
#define PARAM_BOOL_DEF(x) ++paramnum; PARAM_BOOL_DEF_AT(paramnum,x)
#define PARAM_NAME_DEF(x) ++paramnum; PARAM_NAME_DEF_AT(paramnum,x)
#define PARAM_SOUND_DEF(x) ++paramnum; PARAM_SOUND_DEF_AT(paramnum,x)
#define PARAM_COLOR_DEF(x) ++paramnum; PARAM_COLOR_DEF_AT(paramnum,x)
#define PARAM_FLOAT_DEF(x) ++paramnum; PARAM_FLOAT_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_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_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_INT_OPT(x) ++paramnum; PARAM_INT_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)
@ -968,7 +993,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
#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)
typedef int(*actionf_p)(VMFrameStack *stack, VMValue *param, 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)*/
struct AFuncDesc
{

View File

@ -188,13 +188,14 @@ void VMFillParams(VMValue *params, VMFrame *callee, int numparam)
const VMRegisters calleereg(callee);
assert(calleefunc != NULL && !calleefunc->Native);
assert(numparam == calleefunc->NumArgs);
assert(numparam == calleefunc->NumArgs || ((int)calleefunc->Defaults.Size() == numparam));
assert(REGT_INT == 0 && REGT_FLOAT == 1 && REGT_STRING == 2 && REGT_POINTER == 3);
regd = regf = regs = rega = 0;
for (int i = 0; i < numparam; ++i)
for (int i = 0; i < calleefunc->NumArgs; ++i)
{
VMValue &p = params[i];
// get all actual parameters and fill the rest from the defaults.
VMValue &p = i < numparam? params[i] : calleefunc->Defaults[i];
if (p.Type < REGT_STRING)
{
if (p.Type == REGT_INT)

View File

@ -506,7 +506,7 @@ begin:
FillReturns(reg, f, returns, pc+1, C);
if (call->Native)
{
numret = static_cast<VMNativeFunction *>(call)->NativeCall(stack, reg.param + f->NumParam - B, B, returns, C);
numret = static_cast<VMNativeFunction *>(call)->NativeCall(stack, reg.param + f->NumParam - B, call->Defaults, B, returns, C);
}
else
{
@ -550,7 +550,7 @@ begin:
if (call->Native)
{
return static_cast<VMNativeFunction *>(call)->NativeCall(stack, reg.param + f->NumParam - B, B, ret, numret);
return static_cast<VMNativeFunction *>(call)->NativeCall(stack, reg.param + f->NumParam - B, call->Defaults, B, ret, numret);
}
else
{ // FIXME: Not a true tail call

View File

@ -415,7 +415,7 @@ int VMFrameStack::Call(VMFunction *func, VMValue *params, int numparams, VMRetur
{
if (func->Native)
{
return static_cast<VMNativeFunction *>(func)->NativeCall(this, params, numparams, results, numresults);
return static_cast<VMNativeFunction *>(func)->NativeCall(this, params, func->Defaults, numparams, results, numresults);
}
else
{

View File

@ -1952,6 +1952,7 @@ void ZCCCompiler::InitFunctions()
TArray<PType *> rets(1);
TArray<PType *> args;
TArray<uint32_t> argflags;
TArray<VMValue> argdefaults;
TArray<FName> argnames;
for (auto c : Classes)
@ -1961,6 +1962,7 @@ void ZCCCompiler::InitFunctions()
rets.Clear();
args.Clear();
argflags.Clear();
bool hasdefault = false;
// For the time being, let's not allow overloading. This may be reconsidered later but really just adds an unnecessary amount of complexity here.
if (AddTreeNode(f->Name, f, &c->TreeNodes, false))
{
@ -2018,36 +2020,96 @@ void ZCCCompiler::InitFunctions()
}
}
SetImplicitArgs(&args, &argflags, &argnames, c->Type(), varflags);
argdefaults.Resize(argnames.Size());
auto p = f->Params;
if (p != nullptr)
{
do
{
VMValue vmval; // default is REGT_NIL which means 'no default value' here.
if (p->Type != nullptr)
{
auto type = DetermineType(c->Type(), p, f->Name, p->Type, false, false);
int flags = 0;
if (p->Flags & ZCC_In) flags |= VARF_In;
if (p->Flags & ZCC_Out) flags |= VARF_Out;
if (p->Default != nullptr)
if ((type->IsA(RUNTIME_CLASS(PStruct))) || (flags & VARF_Out))
{
auto val = Simplify(p->Default, &c->Type()->Symbols, true);
flags |= VARF_Optional;
if (val->Operation != PEX_ConstValue)
// 'out' parameters and all structs except vectors are passed by reference
if ((flags & VARF_Out) || (type != TypeVector2 && type != TypeVector3))
{
Error(c->cls, "Default parameter %s is not constant in %s", FName(p->Name).GetChars(), FName(f->Name).GetChars());
type = NewPointer(type);
}
// Todo: Store and handle the default value (native functions will discard it anyway but for scripted ones this should be done decently.)
}
if (type->GetRegType() == REGT_NIL && type != TypeVector2 && type != TypeVector3)
{
Error(p, "Invalid type %s for function parameter", type->DescriptiveName());
}
else if (p->Default != nullptr)
{
flags |= VARF_Optional;
// The simplifier is not suited to convert the constant into something usable.
// All it does is reduce the expression to a constant but we still got to do proper type checking and conversion.
// It will also lose important type info about enums, once these get implemented
// The code generator can do this properly for us.
FxExpression *x = new FxTypeCast(ConvertNode(p->Default), type, false);
FCompileContext ctx(c->Type(), false);
x = x->Resolve(ctx);
if (x != nullptr)
{
if (!x->isConstant())
{
Error(p, "Default parameter %s is not constant in %s", FName(p->Name).GetChars(), FName(f->Name).GetChars());
}
else if (x->ValueType != type)
{
Error(p, "Default parameter %s could not be converted to target type %s", FName(p->Name).GetChars(), c->Type()->TypeName.GetChars());
}
else
{
auto cnst = static_cast<FxConstant *>(x);
hasdefault = true;
switch (type->GetRegType())
{
case REGT_INT:
vmval = cnst->GetValue().GetInt();
break;
case REGT_FLOAT:
vmval = cnst->GetValue().GetFloat();
break;
case REGT_POINTER:
if (type->IsKindOf(RUNTIME_CLASS(PClassPointer)))
vmval = (DObject*)cnst->GetValue().GetPointer();
else
vmval = cnst->GetValue().GetPointer();
break;
case REGT_STRING:
vmval = cnst->GetValue().GetString();
break;
default:
assert(0 && "no valid type for constant");
break;
}
}
}
if (x != nullptr) delete x;
}
// TBD: disallow certain types? For now, let everything pass that isn't an array.
args.Push(type);
argflags.Push(flags);
}
else
{
args.Push(nullptr);
argflags.Push(0);
}
argdefaults.Push(vmval);
p = static_cast<decltype(p)>(p->SiblingNext);
} while (p != f->Params);
}
@ -2064,9 +2126,11 @@ void ZCCCompiler::InitFunctions()
sym->Variants[0].Implementation = FunctionBuildList.AddFunction(sym, code, FStringf("%s.%s", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars()), false);
}
}
if (sym->Variants[0].Implementation != nullptr && hasdefault) // do not copy empty default lists, they only waste space and processing time.
{
sym->Variants[0].Implementation->Defaults = std::move(argdefaults);
}
// todo: Check inheritance.
// todo: Process function bodies.
}
}
}

View File

@ -90,7 +90,7 @@ class Actor : Thinker native
native void A_NoBlocking();
native void A_XScream();
native void A_Look();
native void A_Chase(state melee = "*", state missile = "none", int flags = 0);
native void A_Chase(state melee = null, state missile = null, int flags = 0);
native void A_FaceTarget(float max_turn = 0, float max_pitch = 270, float ang_offset = 0, float pitch_offset = 0, int flags = 0, float z_ofs = 0);
native void A_FaceTracer(float max_turn = 0, float max_pitch = 270, float ang_offset = 0, float pitch_offset = 0, int flags = 0, float z_ofs = 0);
native void A_FaceMaster(float max_turn = 0, float max_pitch = 270, float ang_offset = 0, float pitch_offset = 0, int flags = 0, float z_ofs = 0);
@ -203,8 +203,8 @@ class Actor : Thinker native
native void A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10);
native state A_Jump(int chance = 256, state label, ...);
native void A_CustomMissile(class<Actor> missiletype, float spawnheight = 32, float spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET);
native void A_CustomBulletAttack(float spread_xy, float spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET, class<Actor> missile = "", float Spawnheight = 32, float Spawnofs_xy = 0);
native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, int aim = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float spread_xy = 0, float spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
native void A_CustomBulletAttack(float spread_xy, float spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET, class<Actor> missile = null, float Spawnheight = 32, float 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, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float spread_xy = 0, float spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
native state A_JumpIfHealthLower(int health, state label, int ptr_selector = AAPTR_DEFAULT);
native state A_JumpIfCloser(float distance, state label, bool noz = false);
native state A_JumpIfTracerCloser(float distance, state label, bool noz = false);
@ -217,8 +217,8 @@ class Actor : Thinker native
native bool A_TakeInventory(class<Inventory> itemtype, int amount = 0, int flags = 0, int giveto = AAPTR_DEFAULT);
action native bool A_SpawnItem(class<Actor> itemtype = "Unknown", float distance = 0, float zheight = 0, bool useammo = true, bool transfer_translation = false);
native bool A_SpawnItemEx(class<Actor> itemtype, float xofs = 0, float yofs = 0, float zofs = 0, float xvel = 0, float yvel = 0, float zvel = 0, float angle = 0, int flags = 0, int failchance = 0, int tid=0);
native void A_Print(string whattoprint, float time = 0, name fontname = "");
native void A_PrintBold(string whattoprint, float time = 0, name fontname = "");
native void A_Print(string whattoprint, float time = 0, name fontname = "none");
native void A_PrintBold(string whattoprint, float time = 0, name fontname = "none");
native void A_Log(string whattoprint);
native void A_LogInt(int whattoprint);
native void A_LogFloat(float whattoprint);
@ -234,7 +234,7 @@ class Actor : Thinker native
native state A_CheckSight(state label);
native void A_ExtChase(bool usemelee, bool usemissile, bool playactive = true, bool nightmarefast = false);
native void A_DropInventory(class<Inventory> itemtype);
native void A_SetBlend(color color1, float alpha, int tics, color color2 = "");
native void A_SetBlend(color color1, float alpha, int tics, color color2 = 0);
deprecated native void A_ChangeFlag(string flagname, bool value);
deprecated native state A_CheckFlag(string flagname, state label, int check_pointer = AAPTR_DEFAULT);
native void A_ChangeCountFlags(int kill = FLAG_NO_CHANGE, int item = FLAG_NO_CHANGE, int secret = FLAG_NO_CHANGE);
@ -247,8 +247,8 @@ class Actor : Thinker native
native state A_CheckCeiling(state label);
native state A_PlayerSkinCheck(state label);
deprecated native void A_BasicAttack(int meleedamage, sound meleesound, class<actor> missiletype, float missileheight);
native state, bool A_Teleport(state teleportstate = "", class<SpecialSpot> targettype = "BossSpot", class<Actor> fogtype = "TeleportFog", int flags = 0, float mindist = 0, float maxdist = 0, int ptr = AAPTR_DEFAULT);
native state, bool A_Warp(int ptr_destination, float xofs = 0, float yofs = 0, float zofs = 0, float angle = 0, int flags = 0, state success_state = "", float heightoffset = 0, float radiusoffset = 0, float pitch = 0);
native state, bool A_Teleport(state teleportstate = null, class<SpecialSpot> targettype = "BossSpot", class<Actor> fogtype = "TeleportFog", int flags = 0, float mindist = 0, float maxdist = 0, int ptr = AAPTR_DEFAULT);
native state, bool A_Warp(int ptr_destination, float xofs = 0, float yofs = 0, float zofs = 0, float angle = 0, int flags = 0, state success_state = null, float heightoffset = 0, float radiusoffset = 0, float pitch = 0);
action native bool A_ThrowGrenade(class<Actor> itemtype, float zheight = 0, float xyvel = 0, float zvel = 0, bool useammo = true);
native void A_Weave(int xspeed, int yspeed, float xdist, float ydist);
@ -257,8 +257,8 @@ class Actor : Thinker native
native bool A_GiveToTarget(class<Inventory> itemtype, int amount = 0, int forward_ptr = AAPTR_DEFAULT);
native bool A_TakeFromTarget(class<Inventory> itemtype, int amount = 0, int flags = 0, int forward_ptr = AAPTR_DEFAULT);
native int A_RadiusGive(class<Inventory> itemtype, float distance, int flags, int amount = 0, class<Actor> filter = "None", name species = "None", float mindist = 0, int limit = 0);
native state A_CheckSpecies(state jump, name species = "", int ptr = AAPTR_DEFAULT);
native void A_CountdownArg(int argnum, state targstate = "");
native state A_CheckSpecies(state jump, name species = 'none', int ptr = AAPTR_DEFAULT);
native void A_CountdownArg(int argnum, state targstate = null);
native void A_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true);
native void A_CustomComboAttack(class<Actor> missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true);
native void A_Burst(class<Actor> chunktype);
@ -271,7 +271,7 @@ class Actor : Thinker native
native void A_BarrelDestroy();
native void A_QueueCorpse();
native void A_DeQueueCorpse();
native void A_LookEx(int flags = 0, float minseedist = 0, float maxseedist = 0, float maxheardist = 0, float fov = 0, state label = "");
native void A_LookEx(int flags = 0, float minseedist = 0, float maxseedist = 0, float maxheardist = 0, float fov = 0, state label = null);
native void A_ClearLastHeard();
native void A_ClearTarget();
native state A_CheckLOF(state jump, int flags = 0, float range = 0, float minrange = 0, float angle = 0, float pitch = 0, float offsetheight = 0, float offsetwidth = 0, int ptr_target = AAPTR_DEFAULT, float offsetforward = 0);
@ -357,7 +357,7 @@ class Actor : Thinker native
native void A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0);
native void A_CopyFriendliness(int ptr_source = AAPTR_MASTER);
action native bool A_Overlay(int layer, state start = "", bool nooverride = false);
action native bool A_Overlay(int layer, state start = null, bool nooverride = false);
native void A_WeaponOffset(float wx = 0, float wy = 32, int flags = 0);
action native void A_OverlayOffset(int layer = PSP_WEAPON, float wx = 0, float wy = 32, int flags = 0);
action native void A_OverlayFlags(int layer, int flags, bool set);

View File

@ -42,10 +42,10 @@ class Inventory : Actor native
class StateProvider : Inventory native
{
action native state A_JumpIfNoAmmo(state label);
action native void A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class<Actor> pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus", sound MeleeSound = "", sound MissSound = "");
action native void A_FireBullets(float spread_xy, float spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", int flags = 1, float range = 0, class<Actor> missile = "", float Spawnheight = 32, float Spawnofs_xy = 0);
action native void A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class<Actor> pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus", sound MeleeSound = 0, sound MissSound = "");
action native void A_FireBullets(float spread_xy, float spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", int flags = 1, float range = 0, class<Actor> missile = null, float Spawnheight = 32, float Spawnofs_xy = 0);
action native void A_FireCustomMissile(class<Actor> missiletype, float angle = 0, bool useammo = true, float spawnofs_xy = 0, float spawnheight = 0, int flags = 0, float pitch = 0);
action native void A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float spread_xy = 0, float spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
action native void A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = 0, color color2 = 0, int flags = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float spread_xy = 0, float spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
native void A_Light(int extralight);
native void A_Light0();
native void A_Light1();
@ -71,10 +71,10 @@ class StateProvider : Inventory native
native void A_BFGsound();
action native void A_FireBFG();
action native void A_FireOldBFG();
native void A_ReFire(state flash = "");
native void A_ReFire(state flash = null);
native void A_ClearReFire();
native void A_CheckReload();
native void A_GunFlash(state flash = "", int flags = 0);
native void A_GunFlash(state flash = null, int flags = 0);
action native void A_Saw(sound fullsound = "weapons/sawfull", sound hitsound = "weapons/sawhit", int damage = 2, class<Actor> pufftype = "BulletPuff", int flags = 0, float range = 0, float spread_xy = 2.8125, float spread_z = 0, float lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus");
native state A_CheckForReload(int counter, state label, bool dontincrement = false);
native void A_ResetReloadCounter();