- Added rclamp(<int>,<int>).

- Usable for DECORATE expressions. Chooses one of the two numbers placed in the field.
This commit is contained in:
MajorCooke 2014-12-13 15:08:18 -06:00
parent b14eded8d8
commit 8c5a8c54f0
6 changed files with 130 additions and 0 deletions

View file

@ -300,6 +300,7 @@ xx(CallACS)
xx(Sqrt)
xx(CheckClass)
xx(IsPointerEqual)
xx(RClamp)
// Various actor names which are used internally
xx(MapSpot)

View file

@ -158,6 +158,7 @@ std2:
'random' { RET(TK_Random); }
'random2' { RET(TK_Random2); }
'frandom' { RET(TK_FRandom); }
'rclamp' { RET(TK_RClamp); }
L (L|D)* { RET(TK_Identifier); }

View file

@ -122,4 +122,5 @@ xx(TK_Array, "'array'")
xx(TK_In, "'in'")
xx(TK_SizeOf, "'sizeof'")
xx(TK_AlignOf, "'alignof'")
xx(TK_RClamp, "'rclamp'")
#undef xx

View file

@ -371,6 +371,29 @@ static FxExpression *ParseExpression0 (FScanner &sc, const PClass *cls)
return new FxRandom(rng, min, max, sc);
}
else if (sc.CheckToken(TK_RClamp))
{
FRandom *rng;
if (sc.CheckToken('['))
{
sc.MustGetToken(TK_Identifier);
rng = FRandom::StaticFindRNG(sc.String);
sc.MustGetToken(']');
}
else
{
rng = &pr_exrandom;
}
sc.MustGetToken('(');
FxExpression *min = ParseExpressionM(sc, cls);
sc.MustGetToken(',');
FxExpression *max = ParseExpressionM(sc, cls);
sc.MustGetToken(')');
return new FxRClamp(rng, min, max, sc);
}
else if (sc.CheckToken(TK_FRandom))
{
FRandom *rng;

View file

@ -559,6 +559,27 @@ public:
//
//==========================================================================
class FxRClamp : public FxExpression
{
protected:
FRandom * rng;
FxExpression *min, *max;
public:
FxRClamp(FRandom *, FxExpression *mi, FxExpression *ma, const FScriptPosition &pos);
~FxRClamp();
FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression(AActor *self);
};
//==========================================================================
//
//
//
//==========================================================================
class FxFRandom : public FxRandom
{
public:

View file

@ -1691,6 +1691,89 @@ ExpVal FxRandom::EvalExpression (AActor *self)
return val;
}
//==========================================================================
//
//
//
//==========================================================================
FxRClamp::FxRClamp(FRandom * r, FxExpression *mi, FxExpression *ma, const FScriptPosition &pos)
: FxExpression(pos)
{
if (mi != NULL && ma != NULL)
{
min = new FxIntCast(mi);
max = new FxIntCast(ma);
}
else min = max = NULL;
rng = r;
ValueType = VAL_Int;
}
//==========================================================================
//
//
//
//==========================================================================
FxRClamp::~FxRClamp()
{
SAFE_DELETE(min);
SAFE_DELETE(max);
}
//==========================================================================
//
//
//
//==========================================================================
FxExpression *FxRClamp::Resolve(FCompileContext &ctx)
{
CHECKRESOLVED();
if (min && max)
{
RESOLVE(min, ctx);
RESOLVE(max, ctx);
ABORT(min && max);
}
return this;
};
//==========================================================================
//
//
//
//==========================================================================
ExpVal FxRClamp::EvalExpression(AActor *self)
{
ExpVal val;
val.Type = VAL_Int;
if (min != NULL && max != NULL)
{
int minval = min->EvalExpression(self).GetInt();
int maxval = max->EvalExpression(self).GetInt();
if (maxval < minval)
{
swapvalues(maxval, minval);
}
val.Int = (*rng)(2); //rng->operator()(2); //(maxval - minval + 1) + minval;
if (val.Int > 0)
val.Int = maxval;
else
val.Int = minval;
}
else
{
val.Int = (*rng)();
}
return val;
}
//==========================================================================
//
//