mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 23:01:50 +00:00
- Added random2 function to DECORATE's expression evaluator. This is to
better emulate some calculation of internal code pointers. - Added named RNG support to DECORATE's expression evaluator. Just use random[name](min, max). SVN r391 (trunk)
This commit is contained in:
parent
04b80f8de5
commit
d840d9b68a
8 changed files with 133 additions and 43 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
November 26, 2006 (Changes by Graf Zahl)
|
||||||
|
- Added random2 function to DECORATE's expression evaluator. This is to
|
||||||
|
better emulate some calculation of internal code pointers.
|
||||||
|
- Added named RNG support to DECORATE's expression evaluator. Just use
|
||||||
|
random[name](min, max).
|
||||||
|
|
||||||
November 25, 2006
|
November 25, 2006
|
||||||
- Reverted updaterevision.vcproj to r385 and added a note as a build event
|
- Reverted updaterevision.vcproj to r385 and added a note as a build event
|
||||||
explaining the need to use mt.exe 6.0 or newer. Here is the note:
|
explaining the need to use mt.exe 6.0 or newer. Here is the note:
|
||||||
|
|
|
@ -250,6 +250,53 @@ void FRandom::StaticReadRNGState (PNGHandle *png)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function attempts to find an RNG with the given name.
|
||||||
|
// If it can't it will create a new one. Duplicate CRCs will
|
||||||
|
// be ignored and if it happens map to the same RNG.
|
||||||
|
// This is for use by DECORATE.
|
||||||
|
extern FRandom pr_exrandom;
|
||||||
|
|
||||||
|
class NewRNGList : public TArray<FRandom*>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~NewRNGList()
|
||||||
|
{
|
||||||
|
for(unsigned i=0;i<Size();i++)
|
||||||
|
{
|
||||||
|
delete (*this)[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static NewRNGList NewRNGs;
|
||||||
|
|
||||||
|
FRandom *FRandom::StaticFindRNG (const char *name)
|
||||||
|
{
|
||||||
|
DWORD NameCRC = CalcCRC32 ((const BYTE *)name, (unsigned int)strlen (name));
|
||||||
|
|
||||||
|
// Use the default RNG if this one happens to have a CRC of 0.
|
||||||
|
if (NameCRC==0) return &pr_exrandom;
|
||||||
|
|
||||||
|
// Find the RNG in the list, sorted by CRC
|
||||||
|
FRandom **prev = &RNGList, *probe = RNGList;
|
||||||
|
|
||||||
|
while (probe != NULL && probe->NameCRC < NameCRC)
|
||||||
|
{
|
||||||
|
prev = &probe->Next;
|
||||||
|
probe = probe->Next;
|
||||||
|
}
|
||||||
|
// Found one so return it.
|
||||||
|
if (probe == NULL || probe->NameCRC != NameCRC)
|
||||||
|
{
|
||||||
|
// A matching RNG doesn't exist yet so create it.
|
||||||
|
probe = new FRandom(name);
|
||||||
|
|
||||||
|
// Store the new RNG for destruction when ZDoom quits.
|
||||||
|
NewRNGs.Push(probe);
|
||||||
|
}
|
||||||
|
return probe;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
void FRandom::StaticPrintSeeds ()
|
void FRandom::StaticPrintSeeds ()
|
||||||
{
|
{
|
||||||
|
@ -267,3 +314,4 @@ CCMD (showrngs)
|
||||||
FRandom::StaticPrintSeeds ();
|
FRandom::StaticPrintSeeds ();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,7 @@ public:
|
||||||
static DWORD StaticSumSeeds ();
|
static DWORD StaticSumSeeds ();
|
||||||
static void StaticReadRNGState (PNGHandle *png);
|
static void StaticReadRNGState (PNGHandle *png);
|
||||||
static void StaticWriteRNGState (FILE *file);
|
static void StaticWriteRNGState (FILE *file);
|
||||||
|
static FRandom *StaticFindRNG(const char *name);
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
static void StaticPrintSeeds ();
|
static void StaticPrintSeeds ();
|
||||||
|
|
|
@ -1066,32 +1066,6 @@ typedef ActorProps (*ActorPropHandler) (register const char *str, register unsig
|
||||||
|
|
||||||
static const ActorProps *is_actorprop (const char *str);
|
static const ActorProps *is_actorprop (const char *str);
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// Some functions which check for simple tokens
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
inline void ChkCom()
|
|
||||||
{
|
|
||||||
SC_MustGetStringName (",");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void ChkBraceOpn()
|
|
||||||
{
|
|
||||||
SC_MustGetStringName ("{");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool TestBraceCls()
|
|
||||||
{
|
|
||||||
return SC_CheckString ("}");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool TestCom()
|
|
||||||
{
|
|
||||||
return SC_CheckString (",");
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Find a state address
|
// Find a state address
|
||||||
|
@ -1610,7 +1584,7 @@ bool DoSpecialFunctions(FState & state, bool multistate, int * statecount, Bagga
|
||||||
{
|
{
|
||||||
StateParameters[paramindex+i+1]=ParseExpression (false);
|
StateParameters[paramindex+i+1]=ParseExpression (false);
|
||||||
i++;
|
i++;
|
||||||
if (!TestCom()) break;
|
if (!SC_CheckString (",")) break;
|
||||||
}
|
}
|
||||||
SC_MustGetStringName (")");
|
SC_MustGetStringName (")");
|
||||||
}
|
}
|
||||||
|
@ -1719,9 +1693,9 @@ static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag)
|
||||||
intptr_t lastlabel = -1;
|
intptr_t lastlabel = -1;
|
||||||
int minrequiredstate = -1;
|
int minrequiredstate = -1;
|
||||||
|
|
||||||
ChkBraceOpn();
|
SC_MustGetStringName ("{");
|
||||||
SC_SetEscape(false); // disable escape sequences in the state parser
|
SC_SetEscape(false); // disable escape sequences in the state parser
|
||||||
while (!TestBraceCls() && !sc_End)
|
while (!SC_CheckString ("}") && !sc_End)
|
||||||
{
|
{
|
||||||
memset(&state,0,sizeof(state));
|
memset(&state,0,sizeof(state));
|
||||||
statestring = ParseStateString();
|
statestring = ParseStateString();
|
||||||
|
@ -1853,7 +1827,7 @@ do_stop:
|
||||||
SC_MustGetStringName("(");
|
SC_MustGetStringName("(");
|
||||||
SC_MustGetNumber();
|
SC_MustGetNumber();
|
||||||
state.Misc1=sc_Number;
|
state.Misc1=sc_Number;
|
||||||
ChkCom();
|
SC_MustGetStringName (",");
|
||||||
SC_MustGetNumber();
|
SC_MustGetNumber();
|
||||||
state.Misc2=sc_Number;
|
state.Misc2=sc_Number;
|
||||||
SC_MustGetStringName(")");
|
SC_MustGetStringName(")");
|
||||||
|
@ -2092,7 +2066,7 @@ do_stop:
|
||||||
{
|
{
|
||||||
goto endofstate;
|
goto endofstate;
|
||||||
}
|
}
|
||||||
ChkCom();
|
SC_MustGetStringName (",");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SC_MustGetStringName(")");
|
SC_MustGetStringName(")");
|
||||||
|
@ -2418,8 +2392,8 @@ void ParseActorProperties (Baggage &bag)
|
||||||
const PClass *info;
|
const PClass *info;
|
||||||
const ActorProps *prop;
|
const ActorProps *prop;
|
||||||
|
|
||||||
ChkBraceOpn ();
|
SC_MustGetStringName ("{");
|
||||||
while (!TestBraceCls())
|
while (!SC_CheckString ("}"))
|
||||||
{
|
{
|
||||||
if (sc_End)
|
if (sc_End)
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
void InitExpressions ();
|
void InitExpressions ();
|
||||||
void ClearExpressions ();
|
void ClearExpressions ();
|
||||||
|
|
||||||
static FRandom pr_exrandom ("EX_Random");
|
FRandom pr_exrandom ("EX_Random");
|
||||||
|
|
||||||
enum ExpOp
|
enum ExpOp
|
||||||
{
|
{
|
||||||
|
@ -86,6 +86,7 @@ enum ExpOp
|
||||||
EX_Cond, // exp ? exp : exp
|
EX_Cond, // exp ? exp : exp
|
||||||
|
|
||||||
EX_Random, // random (min, max)
|
EX_Random, // random (min, max)
|
||||||
|
EX_Random2, // random2 ([mask])
|
||||||
EX_Sin, // sin (angle)
|
EX_Sin, // sin (angle)
|
||||||
EX_Cos, // cos (angle)
|
EX_Cos, // cos (angle)
|
||||||
EX_ActionSpecial,
|
EX_ActionSpecial,
|
||||||
|
@ -254,6 +255,7 @@ struct ExpData
|
||||||
Type = EX_NOP;
|
Type = EX_NOP;
|
||||||
Value.Type = VAL_Int;
|
Value.Type = VAL_Int;
|
||||||
Value.Int = 0;
|
Value.Int = 0;
|
||||||
|
RNG = NULL;
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
Children[i] = NULL;
|
Children[i] = NULL;
|
||||||
}
|
}
|
||||||
|
@ -321,7 +323,8 @@ struct ExpData
|
||||||
|
|
||||||
if (Type != other->Type ||
|
if (Type != other->Type ||
|
||||||
Value.Type != other->Value.Type ||
|
Value.Type != other->Value.Type ||
|
||||||
Value.Float != other->Value.Float)
|
Value.Float != other->Value.Float ||
|
||||||
|
RNG != other->RNG)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -338,6 +341,7 @@ struct ExpData
|
||||||
ExpOp Type;
|
ExpOp Type;
|
||||||
ExpVal Value;
|
ExpVal Value;
|
||||||
ExpData *Children[2];
|
ExpData *Children[2];
|
||||||
|
FRandom *RNG; // only used by random and random2
|
||||||
};
|
};
|
||||||
|
|
||||||
TArray<ExpData *> StateExpressions;
|
TArray<ExpData *> StateExpressions;
|
||||||
|
@ -699,11 +703,24 @@ static ExpData *ParseExpressionA ()
|
||||||
}
|
}
|
||||||
else if (SC_CheckString ("random"))
|
else if (SC_CheckString ("random"))
|
||||||
{
|
{
|
||||||
|
FRandom *rng;
|
||||||
|
|
||||||
|
if (SC_CheckString("["))
|
||||||
|
{
|
||||||
|
SC_MustGetString();
|
||||||
|
rng = FRandom::StaticFindRNG(sc_String);
|
||||||
|
SC_MustGetStringName("]");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rng = &pr_exrandom;
|
||||||
|
}
|
||||||
if (!SC_CheckString ("("))
|
if (!SC_CheckString ("("))
|
||||||
SC_ScriptError ("'(' expected");
|
SC_ScriptError ("'(' expected");
|
||||||
|
|
||||||
ExpData *data = new ExpData;
|
ExpData *data = new ExpData;
|
||||||
data->Type = EX_Random;
|
data->Type = EX_Random;
|
||||||
|
data->RNG = rng;
|
||||||
|
|
||||||
data->Children[0] = ParseExpressionM ();
|
data->Children[0] = ParseExpressionM ();
|
||||||
|
|
||||||
|
@ -717,6 +734,34 @@ static ExpData *ParseExpressionA ()
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
else if (SC_CheckString ("random2"))
|
||||||
|
{
|
||||||
|
FRandom *rng;
|
||||||
|
|
||||||
|
if (SC_CheckString("["))
|
||||||
|
{
|
||||||
|
SC_MustGetString();
|
||||||
|
rng = FRandom::StaticFindRNG(sc_String);
|
||||||
|
SC_MustGetStringName("]");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rng = &pr_exrandom;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_MustGetStringName("(");
|
||||||
|
|
||||||
|
ExpData *data = new ExpData;
|
||||||
|
data->Type = EX_Random2;
|
||||||
|
data->RNG = rng;
|
||||||
|
|
||||||
|
if (!SC_CheckString(")"))
|
||||||
|
{
|
||||||
|
data->Children[0] = ParseExpressionM();
|
||||||
|
SC_MustGetStringName(")");
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
else if (SC_CheckString ("sin"))
|
else if (SC_CheckString ("sin"))
|
||||||
{
|
{
|
||||||
if (!SC_CheckString ("("))
|
if (!SC_CheckString ("("))
|
||||||
|
@ -1419,22 +1464,38 @@ static ExpVal EvalExpression (ExpData *data, AActor *self)
|
||||||
{
|
{
|
||||||
int num1,num2,num3,num4;
|
int num1,num2,num3,num4;
|
||||||
|
|
||||||
num1 = pr_exrandom();
|
num1 = (*data->RNG)();
|
||||||
num2 = pr_exrandom();
|
num2 = (*data->RNG)();
|
||||||
num3 = pr_exrandom();
|
num3 = (*data->RNG)();
|
||||||
num4 = pr_exrandom();
|
num4 = (*data->RNG)();
|
||||||
|
|
||||||
val.Int = ((num1 << 24) | (num2 << 16) | (num3 << 8) | num4);
|
val.Int = ((num1 << 24) | (num2 << 16) | (num3 << 8) | num4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
val.Int = pr_exrandom();
|
val.Int = (*data->RNG)();
|
||||||
}
|
}
|
||||||
val.Int %= (max - min + 1);
|
val.Int %= (max - min + 1);
|
||||||
val.Int += min;
|
val.Int += min;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EX_Random2:
|
||||||
|
{
|
||||||
|
if (data->Children[0] == NULL)
|
||||||
|
{
|
||||||
|
val.Type = VAL_Int;
|
||||||
|
val.Int = data->RNG->Random2();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExpVal a = EvalExpression (data->Children[0], self);
|
||||||
|
val.Type = VAL_Int;
|
||||||
|
val.Int = data->RNG->Random2((a.Type == VAL_Int) ? a.Int : (int)a.Float);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case EX_Sin:
|
case EX_Sin:
|
||||||
{
|
{
|
||||||
ExpVal a = EvalExpression (data->Children[0], self);
|
ExpVal a = EvalExpression (data->Children[0], self);
|
||||||
|
|
|
@ -30,7 +30,7 @@ ACTOR Clink 90
|
||||||
Melee:
|
Melee:
|
||||||
CLNK E 5 A_FaceTarget
|
CLNK E 5 A_FaceTarget
|
||||||
CLNK F 4 A_FaceTarget
|
CLNK F 4 A_FaceTarget
|
||||||
CLNK G 7 A_CustomMeleeAttack(random(3,9), "clink/attack", "clink/attack")
|
CLNK G 7 A_CustomMeleeAttack(random[ClinkAttack](3,9), "clink/attack", "clink/attack")
|
||||||
Goto See
|
Goto See
|
||||||
Pain:
|
Pain:
|
||||||
CLNK H 3
|
CLNK H 3
|
||||||
|
|
|
@ -30,7 +30,7 @@ ACTOR Beggar : StrifeHumanoid
|
||||||
Loop
|
Loop
|
||||||
Melee:
|
Melee:
|
||||||
BEGR D 8
|
BEGR D 8
|
||||||
BEGR D 8 A_CustomMeleeAttack(2*random(1,5)+2)
|
BEGR D 8 A_CustomMeleeAttack(2*random[PeasantAttack](1,5)+2)
|
||||||
BEGR E 1 A_Chase
|
BEGR E 1 A_Chase
|
||||||
BEGR D 8 A_SentinelRefire
|
BEGR D 8 A_SentinelRefire
|
||||||
Loop
|
Loop
|
||||||
|
|
|
@ -29,7 +29,7 @@ ACTOR Peasant : StrifeHumanoid
|
||||||
Loop
|
Loop
|
||||||
Melee:
|
Melee:
|
||||||
PEAS E 10 A_FaceTarget
|
PEAS E 10 A_FaceTarget
|
||||||
PEAS F 8 A_CustomMeleeAttack(2*random(1,5)+2)
|
PEAS F 8 A_CustomMeleeAttack(2*random[PeasantAttack](1,5)+2)
|
||||||
PEAS E 8
|
PEAS E 8
|
||||||
Goto See
|
Goto See
|
||||||
Pain:
|
Pain:
|
||||||
|
|
Loading…
Reference in a new issue