public float GetValue(
Formulae fdb,
SkillDef scontext = null,
Character ccontext = null,
Character tcontext = null,
Equipment econtext = null,
Item icontext = null
)
{
if (firstTime)
{
lookupReference = lookupReference == null ? "" : lookupReference.NormalizeName();
firstTime = false;
}
// if(scontext != null && scontext.currentTargetCharacter != null) {
// Debug.Log("get value from "+this);
// }
float result = float.NaN;
switch (formulaType)
{
case FormulaType.Constant:
result = constantValue;
break;
case FormulaType.Lookup:
result = fdb.Lookup(lookupReference, lookupType, scontext, ccontext, tcontext, econtext, icontext, this);
break;
case FormulaType.ReactedEffectValue:
if (scontext == null)
{
Debug.LogError("No skill context.");
return(float.NaN);
}
if (scontext.currentReactedEffect == null)
{
Debug.LogError("Skill context is reacting to no particular effect.");
return(float.NaN);
}
result = scontext.currentReactedEffect.value;
break;
case FormulaType.SkillEffectValue:
if (scontext == null)
{
Debug.LogError("No skill context.");
return(float.NaN);
}
if (scontext.lastEffects == null || scontext.lastEffects.Count == 0)
{
Debug.LogError("Skill context has no prior effects.");
return(float.NaN);
}
result = scontext.lastEffects[scontext.lastEffects.Count - 1].value;
break;
case FormulaType.Add:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
for (int i = 1; i < arguments.Count; i++)
{
result += arguments[i].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
}
break;
case FormulaType.Subtract:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
for (int i = 1; i < arguments.Count; i++)
{
result -= arguments[i].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
}
break;
case FormulaType.Multiply:
if (arguments == null)
{
Debug.LogError("no args at all! " + name + ":" + text);
}
if (arguments[0] == null)
{
if (arguments[1] != null)
{
Debug.Log("a1 was ok, it's " + arguments[1].name + ":" + arguments[1].text + " " + arguments[1].formulaType + "." + arguments[1].lookupType + " => " + arguments[1].lookupReference);
}
Debug.LogError("nm " + name + " txt " + text + " args " + arguments.Count);
}
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
for (int i = 1; i < arguments.Count; i++)
{
result *= arguments[i].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
}
// Debug.Log("multiplied to "+result);
break;
case FormulaType.Divide:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
for (int i = 1; i < arguments.Count; i++)
{
result /= arguments[i].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
}
// Debug.Log("divided to "+result);
break;
case FormulaType.IntDivide:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
for (int i = 1; i < arguments.Count; i++)
{
result = (float)((int)(result / arguments[i].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext)));
}
result = (float)((int)result);
// Debug.Log("int divided to "+result);
break;
case FormulaType.Trunc:
result = (float)((int)arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext));
break;
case FormulaType.And:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
for (int i = 1; i < arguments.Count; i++)
{
result = ((result != 0) && (arguments[i].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) != 0)) ? 1 : 0;
}
break;
case FormulaType.Or:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
for (int i = 1; i < arguments.Count; i++)
{
result = ((result != 0) || (arguments[i].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) != 0)) ? 1 : 0;
}
break;
case FormulaType.Not:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) != 0 ? 0 : 1;
break;
case FormulaType.Remainder:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
for (int i = 1; i < arguments.Count; i++)
{
result = result % arguments[i].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
}
break;
case FormulaType.Exponent:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
if (arguments.Count == 1)
{
result = result * result;
}
else
{
for (int i = 1; i < arguments.Count; i++)
{
result = Mathf.Pow(result, arguments[i].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext));
}
}
break;
case FormulaType.Root:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
if (arguments.Count == 1)
{
result = Mathf.Sqrt(result);
}
else
{
for (int i = 1; i < arguments.Count; i++)
{
result = Mathf.Pow(result, 1.0f / arguments[i].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext));
}
}
break;
case FormulaType.Mean:
result = arguments.Sum(a => a.GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext)) / arguments.Count();
break;
case FormulaType.Min:
result = arguments.Min(a => a.GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext));
break;
case FormulaType.Max:
result = arguments.Max(a => a.GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext));
break;
case FormulaType.RandomRange: {
float low = 0, high = 1;
if (arguments.Count >= 2)
{
low = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
high = arguments[1].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
}
else if (arguments.Count == 1)
{
high = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
}
result = Random.Range(low, high);
break;
}
case FormulaType.ClampRange: {
float r = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
float low = 0, high = 1;
if (arguments.Count >= 2)
{
low = arguments[1].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
}
if (arguments.Count >= 3)
{
high = arguments[2].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
}
result = Mathf.Clamp(r, low, high);
break;
}
case FormulaType.RoundDown:
result = Mathf.Floor(arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext));
break;
case FormulaType.RoundUp:
result = Mathf.Ceil(arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext));
break;
case FormulaType.Round:
result = Mathf.Round(arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext));
break;
case FormulaType.AbsoluteValue:
result = Mathf.Abs(arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext));
break;
case FormulaType.Negate:
result = -1 * arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
// Debug.Log("negated to "+result);
break;
case FormulaType.Equal:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) == arguments[1].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) ? 1 : 0;
break;
case FormulaType.NotEqual:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) != arguments[1].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) ? 1 : 0;
break;
case FormulaType.GreaterThan:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) > arguments[1].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) ? 1 : 0;
break;
case FormulaType.GreaterThanOrEqual:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) >= arguments[1].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) ? 1 : 0;
break;
case FormulaType.LessThan:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) < arguments[1].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) ? 1 : 0;
break;
case FormulaType.LessThanOrEqual:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) <= arguments[1].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) ? 1 : 0;
break;
case FormulaType.Any:
result = arguments[Random.Range(0, arguments.Count)].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
break;
case FormulaType.LookupSuccessful:
result = fdb.CanLookup(lookupReference, lookupType, scontext, ccontext, null, econtext, icontext, this) ? 1 : 0;
break;
case FormulaType.LookupOrElse:
if (fdb.CanLookup(lookupReference, lookupType, scontext, ccontext, null, econtext, icontext, this))
{
result = fdb.Lookup(lookupReference, lookupType, scontext, ccontext, tcontext, econtext, icontext, this);
}
else
{
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
}
break;
case FormulaType.BranchIfNotZero:
result = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) != 0 ?
arguments[1].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) :
arguments[2].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
break;
case FormulaType.BranchApplierSide:
result = FacingSwitch(fdb, StatEffectTarget.Applier, scontext, ccontext, tcontext, econtext, icontext);
break;
case FormulaType.BranchAppliedSide:
result = FacingSwitch(fdb, StatEffectTarget.Applied, scontext, ccontext, tcontext, econtext, icontext);
break;
case FormulaType.BranchPDF: {
result = float.NaN;
float rval = Random.value;
float val = 0;
int halfLen = arguments.Count / 2;
for (int i = 0; i < halfLen; i++)
{
val += arguments[i].GetValue(
fdb,
scontext,
ccontext,
tcontext,
econtext,
icontext
);
// Debug.Log("branch cond check "+val+" against "+rval);
if (val >= rval)
{
result = arguments[i + halfLen].GetValue(
fdb,
scontext,
ccontext,
tcontext,
econtext,
icontext
);
// Debug.Log("got "+result);
break;
}
}
if (float.IsNaN(result))
{
Debug.LogError("PDF adds up to less than 1");
}
break;
}
case FormulaType.BranchCond: {
result = float.NaN;
int halfLen = arguments.Count / 2;
for (int i = 0; i < halfLen; i++)
{
if (arguments[i].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) != 0)
{
result = arguments[i + halfLen].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
break;
}
}
if (float.IsNaN(result))
{
Debug.LogError("No cond branch applied");
}
break;
}
case FormulaType.BranchSwitch: {
result = float.NaN;
float val = arguments[0].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
int halfLen = (arguments.Count - 1) / 2;
for (int i = 1; (i - 1) < halfLen; i++)
{
if (!NullFormula(arguments[i]) &&
arguments[i].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext) == val)
{
result = arguments[i + halfLen].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
break;
}
}
if (float.IsNaN(result))
{
for (int i = 1; (i - 1) < halfLen; i++)
{
if (NullFormula(arguments[i]) && !NullFormula(arguments[i + halfLen]))
{
result = arguments[i + halfLen].GetValue(fdb, scontext, ccontext, tcontext, econtext, icontext);
break;
}
}
}
if (float.IsNaN(result))
{
Debug.LogError("No cond branch applied");
}
break;
}
case FormulaType.TargetIsNull:
result = (scontext != null ? scontext.currentTargetCharacter == null : tcontext == null) ? 1 : 0;
break;
case FormulaType.TargetIsNotNull:
result = (scontext != null ? scontext.currentTargetCharacter != null : tcontext != null) ? 1 : 0;
break;
}
lastValue = result;
return(result);
}