diff --git a/src/sc_man_scanner.re b/src/sc_man_scanner.re index 52a5d9f61..519ee4a1e 100644 --- a/src/sc_man_scanner.re +++ b/src/sc_man_scanner.re @@ -159,6 +159,7 @@ std2: 'random2' { RET(TK_Random2); } 'frandom' { RET(TK_FRandom); } 'randompick' { RET(TK_RandomPick); } + 'frandompick' { RET(TK_FRandomPick); } L (L|D)* { RET(TK_Identifier); } diff --git a/src/sc_man_tokens.h b/src/sc_man_tokens.h index 22f6e9cd4..afceaa856 100644 --- a/src/sc_man_tokens.h +++ b/src/sc_man_tokens.h @@ -122,5 +122,6 @@ xx(TK_Array, "'array'") xx(TK_In, "'in'") xx(TK_SizeOf, "'sizeof'") xx(TK_AlignOf, "'alignof'") -xx(TK_RandomPick, "'randompick'") +xx(TK_RandomPick, "'randompick'") +xx(TK_FRandomPick, "'frandompick'") #undef xx diff --git a/src/thingdef/thingdef_exp.cpp b/src/thingdef/thingdef_exp.cpp index 7bd10b38d..5422d1a7c 100644 --- a/src/thingdef/thingdef_exp.cpp +++ b/src/thingdef/thingdef_exp.cpp @@ -371,8 +371,9 @@ static FxExpression *ParseExpression0 (FScanner &sc, const PClass *cls) return new FxRandom(rng, min, max, sc); } - else if (sc.CheckToken(TK_RandomPick)) + else if (sc.CheckToken(TK_RandomPick) || sc.CheckToken(TK_FRandomPick)) { + bool floaty = sc.TokenType == TK_FRandomPick; FRandom *rng; TArray list; list.Clear(); @@ -398,7 +399,7 @@ static FxExpression *ParseExpression0 (FScanner &sc, const PClass *cls) break; sc.MustGetToken(','); } - return new FxRandomPick(rng, list, sc); + return new FxRandomPick(rng, list, floaty, sc); } else if (sc.CheckToken(TK_FRandom)) { diff --git a/src/thingdef/thingdef_exp.h b/src/thingdef/thingdef_exp.h index e05c852a2..40f5d4dc7 100644 --- a/src/thingdef/thingdef_exp.h +++ b/src/thingdef/thingdef_exp.h @@ -587,7 +587,7 @@ protected: public: - FxRandomPick(FRandom *, TArray mi, const FScriptPosition &pos); + FxRandomPick(FRandom *, TArray mi, bool floaty, const FScriptPosition &pos); ~FxRandomPick(); FxExpression *Resolve(FCompileContext&); diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index aa0486dc6..e1f4e1fe4 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -1774,15 +1774,24 @@ ExpVal FxRandom::EvalExpression (AActor *self) // // //========================================================================== -FxRandomPick::FxRandomPick(FRandom * r, TArray mi, const FScriptPosition &pos) +FxRandomPick::FxRandomPick(FRandom * r, TArray mi, bool floaty, const FScriptPosition &pos) : FxExpression(pos) { for (unsigned int index = 0; index < mi.Size(); index++) { - min.Push(new FxIntCast(mi[index])); + FxExpression *casted; + if (floaty) + { + casted = new FxFloatCast(mi[index]); + } + else + { + casted = new FxIntCast(mi[index]); + } + min.Push(casted); } rng = r; - ValueType = VAL_Int; + ValueType = floaty ? VAL_Float : VAL_Int; } //========================================================================== @@ -1822,17 +1831,25 @@ FxExpression *FxRandomPick::Resolve(FCompileContext &ctx) ExpVal FxRandomPick::EvalExpression(AActor *self) { ExpVal val; - val.Type = VAL_Int; int max = min.Size(); if (max > 0) { int select = (*rng)(max); - val.Int = min[select]->EvalExpression(self).GetInt(); + val = min[select]->EvalExpression(self); + } + /* Is a default even important when the parser requires at least one + * choice? Why do we do this? */ + else if (ValueType == VAL_Int) + { + val.Type = VAL_Int; + val.Int = (*rng)(); } else { - val.Int = (*rng)(); + val.Type = VAL_Float; + val.Float = (*rng)(0x40000000) / double(0x40000000); } + assert(val.Type == ValueType); return val; }