mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 06:53:58 +00:00
- Added action special support to the thingdef expression evaluator. Now you
can use them like normal functions, which is probably most useful for ACS_ExecuteWithResult. SVN r294 (trunk)
This commit is contained in:
parent
ed12bdc0f4
commit
7dc4be302f
4 changed files with 123 additions and 14 deletions
|
@ -1,4 +1,7 @@
|
||||||
August 16, 2006
|
August 16, 2006
|
||||||
|
- Added action special support to the thingdef expression evaluator. Now you
|
||||||
|
can use them like normal functions, which is probably most useful for
|
||||||
|
ACS_ExecuteWithResult.
|
||||||
- Switched to IJG code for reading JPEG images. I have included a stripped-
|
- Switched to IJG code for reading JPEG images. I have included a stripped-
|
||||||
down version of the library with the ZDoom source. (It actually uses less
|
down version of the library with the ZDoom source. (It actually uses less
|
||||||
space than zlib now.) Unix users probably ought to use the system-supplied
|
space than zlib now.) Unix users probably ought to use the system-supplied
|
||||||
|
|
|
@ -1306,6 +1306,29 @@ int FindLineSpecial(const char * string)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FindLineSpecialEx
|
||||||
|
//
|
||||||
|
// Like FindLineSpecial, but also returns the min and max argument count.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int FindLineSpecialEx (const char *string, int *min_args, int *max_args)
|
||||||
|
{
|
||||||
|
const ACSspecials *spec;
|
||||||
|
|
||||||
|
spec = is_special(string, (unsigned int)strlen(string));
|
||||||
|
if (spec != NULL)
|
||||||
|
{
|
||||||
|
*min_args = spec->MinArgs;
|
||||||
|
*max_args = MAX(spec->MinArgs, spec->MaxArgs);
|
||||||
|
return spec->Special;
|
||||||
|
}
|
||||||
|
*min_args = *max_args = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// DoSpecialFunctions
|
// DoSpecialFunctions
|
||||||
|
|
|
@ -57,6 +57,9 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// The contents of string must be lowercase (for now, anyway)
|
||||||
|
int FindLineSpecialEx (const char *string, int *minargs, int *maxargs);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "a_pickups.h"
|
#include "a_pickups.h"
|
||||||
|
#include "thingdef.h"
|
||||||
|
#include "p_lnspec.h"
|
||||||
|
|
||||||
void InitExpressions ();
|
void InitExpressions ();
|
||||||
void ClearExpressions ();
|
void ClearExpressions ();
|
||||||
|
@ -87,6 +89,8 @@ enum ExpOp
|
||||||
EX_Sin, // sin (angle)
|
EX_Sin, // sin (angle)
|
||||||
EX_Cos, // cos (angle)
|
EX_Cos, // cos (angle)
|
||||||
EX_InvCount, // invcount (type)
|
EX_InvCount, // invcount (type)
|
||||||
|
EX_ActionSpecial,
|
||||||
|
EX_Right,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ExpValType
|
enum ExpValType
|
||||||
|
@ -251,12 +255,12 @@ struct ExpData
|
||||||
Type = EX_NOP;
|
Type = EX_NOP;
|
||||||
Value.Type = VAL_Int;
|
Value.Type = VAL_Int;
|
||||||
Value.Int = 0;
|
Value.Int = 0;
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
Children[i] = NULL;
|
Children[i] = NULL;
|
||||||
}
|
}
|
||||||
~ExpData ()
|
~ExpData ()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
if (Children[i])
|
if (Children[i])
|
||||||
{
|
{
|
||||||
|
@ -287,12 +291,14 @@ struct ExpData
|
||||||
if (Children[0]->Type == EX_Const)
|
if (Children[0]->Type == EX_Const)
|
||||||
{
|
{
|
||||||
bool cond = (Children[0]->Value.Type == VAL_Int) ? (Children[0]->Value.Int != 0) : (Children[0]->Value.Float != 0);
|
bool cond = (Children[0]->Value.Type == VAL_Int) ? (Children[0]->Value.Int != 0) : (Children[0]->Value.Float != 0);
|
||||||
ExpData *data = Children[cond ? 1 : 2];
|
ExpData *data = Children[1]->Children[cond];
|
||||||
delete Children[cond ? 2 : 1];
|
delete Children[1]->Children[!cond];
|
||||||
|
delete Children[1];
|
||||||
|
delete Children[0];
|
||||||
|
|
||||||
Type = data->Type;
|
Type = data->Type;
|
||||||
Value = data->Value;
|
Value = data->Value;
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
Children[i] = data->Children[i];
|
Children[i] = data->Children[i];
|
||||||
data->Children[i] = NULL;
|
data->Children[i] = NULL;
|
||||||
|
@ -301,7 +307,7 @@ struct ExpData
|
||||||
delete data;
|
delete data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Type != EX_Random && Type != EX_Sin && Type != EX_Cos && Type != EX_InvCount)
|
else if (Type != EX_Random && Type != EX_Sin && Type != EX_Cos && Type != EX_InvCount && Type != EX_ActionSpecial)
|
||||||
{
|
{
|
||||||
if (Children[0]->Type == EX_Const && Children[1]->Type == EX_Const)
|
if (Children[0]->Type == EX_Const && Children[1]->Type == EX_Const)
|
||||||
{
|
{
|
||||||
|
@ -324,7 +330,7 @@ struct ExpData
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
if (Children[i] && !Children[i]->Compare (other->Children[i]))
|
if (Children[i] && !Children[i]->Compare (other->Children[i]))
|
||||||
return false;
|
return false;
|
||||||
|
@ -335,7 +341,7 @@ struct ExpData
|
||||||
|
|
||||||
ExpOp Type;
|
ExpOp Type;
|
||||||
ExpVal Value;
|
ExpVal Value;
|
||||||
ExpData *Children[3];
|
ExpData *Children[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
TArray<ExpData *> StateExpressions;
|
TArray<ExpData *> StateExpressions;
|
||||||
|
@ -402,10 +408,13 @@ static ExpData *ParseExpressionM ()
|
||||||
ExpData *data = new ExpData;
|
ExpData *data = new ExpData;
|
||||||
data->Type = EX_Cond;
|
data->Type = EX_Cond;
|
||||||
data->Children[0] = tmp;
|
data->Children[0] = tmp;
|
||||||
data->Children[1] = ParseExpressionM ();
|
ExpData *choices = new ExpData;
|
||||||
|
data->Children[1] = choices;
|
||||||
|
choices->Type = EX_Right;
|
||||||
|
choices->Children[0] = ParseExpressionM ();
|
||||||
if (!SC_CheckString (":"))
|
if (!SC_CheckString (":"))
|
||||||
SC_ScriptError ("':' expected");
|
SC_ScriptError ("':' expected");
|
||||||
data->Children[2] = ParseExpressionM ();
|
choices->Children[1] = ParseExpressionM ();
|
||||||
data->EvalConst ();
|
data->EvalConst ();
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -778,8 +787,47 @@ static ExpData *ParseExpressionA ()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int specnum, min_args, max_args;
|
||||||
|
|
||||||
SC_MustGetString ();
|
SC_MustGetString ();
|
||||||
|
|
||||||
|
// Check if this is an action special
|
||||||
|
strlwr (sc_String);
|
||||||
|
specnum = FindLineSpecialEx (sc_String, &min_args, &max_args);
|
||||||
|
if (specnum != 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!SC_CheckString ("("))
|
||||||
|
SC_ScriptError ("'(' expected");
|
||||||
|
|
||||||
|
ExpData *data = new ExpData, **left;
|
||||||
|
data->Type = EX_ActionSpecial;
|
||||||
|
data->Value.Int = specnum;
|
||||||
|
|
||||||
|
data->Children[0] = ParseExpressionM ();
|
||||||
|
left = &data->Children[1];
|
||||||
|
|
||||||
|
for (i = 1; i < 5 && SC_CheckString (","); ++i)
|
||||||
|
{
|
||||||
|
ExpData *right = new ExpData;
|
||||||
|
right->Type = EX_Right;
|
||||||
|
right->Children[0] = ParseExpressionM ();
|
||||||
|
*left = right;
|
||||||
|
left = &right->Children[1];
|
||||||
|
}
|
||||||
|
*left = NULL;
|
||||||
|
if (!SC_CheckString (")"))
|
||||||
|
SC_ScriptError ("')' expected");
|
||||||
|
if (i < min_args)
|
||||||
|
SC_ScriptError ("Not enough arguments to action special");
|
||||||
|
if (i > max_args)
|
||||||
|
SC_ScriptError ("Too many arguments to action special");
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's a variable we understand
|
||||||
int varid = -1;
|
int varid = -1;
|
||||||
for (size_t i = 0; i < countof(ExpVars); i++)
|
for (size_t i = 0; i < countof(ExpVars); i++)
|
||||||
{
|
{
|
||||||
|
@ -1363,10 +1411,10 @@ static ExpVal EvalExpression (ExpData *data, AActor *self)
|
||||||
{
|
{
|
||||||
ExpVal a = EvalExpression (data->Children[0], self);
|
ExpVal a = EvalExpression (data->Children[0], self);
|
||||||
|
|
||||||
if (a.Type == VAL_Int)
|
if (a.Type == VAL_Float)
|
||||||
val = a.Int ? EvalExpression (data->Children[1], self) : EvalExpression (data->Children[2], self);
|
a.Int = (int)a.Float;
|
||||||
else
|
|
||||||
val = a.Float ? EvalExpression (data->Children[1], self) : EvalExpression (data->Children[2], self);
|
val = EvalExpression (data->Children[1]->Children[!!a.Int], self);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1442,6 +1490,38 @@ static ExpVal EvalExpression (ExpData *data, AActor *self)
|
||||||
val.Int = item->Amount;
|
val.Int = item->Amount;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EX_ActionSpecial:
|
||||||
|
{
|
||||||
|
int parms[5] = { 0, 0, 0, 0 };
|
||||||
|
int i = 0;
|
||||||
|
ExpData *parm = data;
|
||||||
|
|
||||||
|
while (parm != NULL && i < 5)
|
||||||
|
{
|
||||||
|
ExpVal val = EvalExpression (parm->Children[0], self);
|
||||||
|
if (val.Type == VAL_Int)
|
||||||
|
{
|
||||||
|
parms[i] = val.Int;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parms[i] = (int)val.Float;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
parm = parm->Children[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
val.Type = VAL_Int;
|
||||||
|
val.Int = LineSpecials[data->Value.Int] (NULL, self, false,
|
||||||
|
parms[0], parms[1], parms[2], parms[3], parms[4]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EX_Right:
|
||||||
|
// This should never be a top-level expression.
|
||||||
|
assert (data->Type != EX_Right);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
|
|
Loading…
Reference in a new issue