diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 465b34f3e0..0ed2b90cf6 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -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 - 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: diff --git a/src/m_random.cpp b/src/m_random.cpp index 7977db90b8..3ebcd2dd72 100644 --- a/src/m_random.cpp +++ b/src/m_random.cpp @@ -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 +{ +public: + ~NewRNGList() + { + for(unsigned i=0;iNameCRC < 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 void FRandom::StaticPrintSeeds () { @@ -267,3 +314,4 @@ CCMD (showrngs) FRandom::StaticPrintSeeds (); } #endif + diff --git a/src/m_random.h b/src/m_random.h index 11e699b644..ff0078e616 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -77,6 +77,7 @@ public: static DWORD StaticSumSeeds (); static void StaticReadRNGState (PNGHandle *png); static void StaticWriteRNGState (FILE *file); + static FRandom *StaticFindRNG(const char *name); #ifdef _DEBUG static void StaticPrintSeeds (); diff --git a/src/thingdef.cpp b/src/thingdef.cpp index d162e3bcf8..14daffb8e4 100644 --- a/src/thingdef.cpp +++ b/src/thingdef.cpp @@ -1066,32 +1066,6 @@ typedef ActorProps (*ActorPropHandler) (register const char *str, register unsig 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 @@ -1610,7 +1584,7 @@ bool DoSpecialFunctions(FState & state, bool multistate, int * statecount, Bagga { StateParameters[paramindex+i+1]=ParseExpression (false); i++; - if (!TestCom()) break; + if (!SC_CheckString (",")) break; } SC_MustGetStringName (")"); } @@ -1719,9 +1693,9 @@ static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag) intptr_t lastlabel = -1; int minrequiredstate = -1; - ChkBraceOpn(); + SC_MustGetStringName ("{"); SC_SetEscape(false); // disable escape sequences in the state parser - while (!TestBraceCls() && !sc_End) + while (!SC_CheckString ("}") && !sc_End) { memset(&state,0,sizeof(state)); statestring = ParseStateString(); @@ -1853,7 +1827,7 @@ do_stop: SC_MustGetStringName("("); SC_MustGetNumber(); state.Misc1=sc_Number; - ChkCom(); + SC_MustGetStringName (","); SC_MustGetNumber(); state.Misc2=sc_Number; SC_MustGetStringName(")"); @@ -2092,7 +2066,7 @@ do_stop: { goto endofstate; } - ChkCom(); + SC_MustGetStringName (","); } } SC_MustGetStringName(")"); @@ -2418,8 +2392,8 @@ void ParseActorProperties (Baggage &bag) const PClass *info; const ActorProps *prop; - ChkBraceOpn (); - while (!TestBraceCls()) + SC_MustGetStringName ("{"); + while (!SC_CheckString ("}")) { if (sc_End) { diff --git a/src/thingdef_exp.cpp b/src/thingdef_exp.cpp index f4f18d8409..c9a7f5feb4 100644 --- a/src/thingdef_exp.cpp +++ b/src/thingdef_exp.cpp @@ -52,7 +52,7 @@ void InitExpressions (); void ClearExpressions (); -static FRandom pr_exrandom ("EX_Random"); +FRandom pr_exrandom ("EX_Random"); enum ExpOp { @@ -86,6 +86,7 @@ enum ExpOp EX_Cond, // exp ? exp : exp EX_Random, // random (min, max) + EX_Random2, // random2 ([mask]) EX_Sin, // sin (angle) EX_Cos, // cos (angle) EX_ActionSpecial, @@ -254,6 +255,7 @@ struct ExpData Type = EX_NOP; Value.Type = VAL_Int; Value.Int = 0; + RNG = NULL; for (int i = 0; i < 2; i++) Children[i] = NULL; } @@ -321,7 +323,8 @@ struct ExpData if (Type != other->Type || Value.Type != other->Value.Type || - Value.Float != other->Value.Float) + Value.Float != other->Value.Float || + RNG != other->RNG) { return false; } @@ -338,6 +341,7 @@ struct ExpData ExpOp Type; ExpVal Value; ExpData *Children[2]; + FRandom *RNG; // only used by random and random2 }; TArray StateExpressions; @@ -699,11 +703,24 @@ static ExpData *ParseExpressionA () } 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 ("(")) SC_ScriptError ("'(' expected"); ExpData *data = new ExpData; data->Type = EX_Random; + data->RNG = rng; data->Children[0] = ParseExpressionM (); @@ -717,6 +734,34 @@ static ExpData *ParseExpressionA () 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")) { if (!SC_CheckString ("(")) @@ -1419,22 +1464,38 @@ static ExpVal EvalExpression (ExpData *data, AActor *self) { int num1,num2,num3,num4; - num1 = pr_exrandom(); - num2 = pr_exrandom(); - num3 = pr_exrandom(); - num4 = pr_exrandom(); + num1 = (*data->RNG)(); + num2 = (*data->RNG)(); + num3 = (*data->RNG)(); + num4 = (*data->RNG)(); val.Int = ((num1 << 24) | (num2 << 16) | (num3 << 8) | num4); } else { - val.Int = pr_exrandom(); + val.Int = (*data->RNG)(); } val.Int %= (max - min + 1); val.Int += min; } 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: { ExpVal a = EvalExpression (data->Children[0], self); diff --git a/wadsrc/decorate/heretic/clink.txt b/wadsrc/decorate/heretic/clink.txt index 087ca919e4..ec8cf6b9c1 100644 --- a/wadsrc/decorate/heretic/clink.txt +++ b/wadsrc/decorate/heretic/clink.txt @@ -30,7 +30,7 @@ ACTOR Clink 90 Melee: CLNK E 5 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 Pain: CLNK H 3 diff --git a/wadsrc/decorate/strife/beggars.txt b/wadsrc/decorate/strife/beggars.txt index 45347d9f1c..318fd844e6 100644 --- a/wadsrc/decorate/strife/beggars.txt +++ b/wadsrc/decorate/strife/beggars.txt @@ -30,7 +30,7 @@ ACTOR Beggar : StrifeHumanoid Loop Melee: 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 D 8 A_SentinelRefire Loop diff --git a/wadsrc/decorate/strife/peasants.txt b/wadsrc/decorate/strife/peasants.txt index c29862aeda..05b8243385 100644 --- a/wadsrc/decorate/strife/peasants.txt +++ b/wadsrc/decorate/strife/peasants.txt @@ -29,7 +29,7 @@ ACTOR Peasant : StrifeHumanoid Loop Melee: 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 Goto See Pain: