Formulae.Lookup C# (CSharp) Method

Lookup() public method

public Lookup ( string fname, LookupType type, SkillDef, scontext = null, Character, ccontext = null, Character, tcontext = null, Equipment, econtext = null, Item, icontext = null, Formula, f = null ) : float
fname string
type LookupType
scontext SkillDef,
ccontext Character,
tcontext Character,
econtext Equipment,
icontext Item,
f Formula,
return float
    public float Lookup(
		string fname, LookupType type,
		SkillDef scontext=null,
		Character ccontext=null,
		Character tcontext=null,
		Equipment econtext=null,
		Item icontext=null,
		Formula f=null
	)
    {
        switch(type) {
            case LookupType.Auto: {
                float ret =
                    (icontext != null ? icontext.GetParam(fname) :
                    (econtext != null ? econtext.GetParam(fname) :
                    (scontext != null ? scontext.GetParam(fname) :
                    (ccontext != null ? ccontext.GetStat(fname) :
                    (tcontext != null ? tcontext.GetStat(fname) :
                    (HasFormula(fname) ? LookupFormula(fname).GetValue(this, scontext, ccontext, tcontext, econtext, icontext) : float.NaN))))));
                if(float.IsNaN(ret)) {
                    Debug.LogError("auto lookup failed for "+fname);
                }
                return ret;
            }
            case LookupType.SkillParam:
                return scontext.GetParam(fname);
            case LookupType.ItemParam: {
                if(icontext == null && scontext != null) {
                    icontext = scontext.InvolvedItem;
                }
                if(icontext == null && econtext != null) {
                    icontext = econtext.baseItem;
                }
                return icontext.GetParam(fname, scontext);
            }
            case LookupType.ReactedItemParam: {
                icontext = scontext.currentReactedSkill.InvolvedItem;
                return icontext.GetParam(fname, scontext);
            }
            case LookupType.ActorStat:
                if(scontext != null) { return scontext.character.GetStat(fname); }
                if(econtext != null) { return econtext.wielder.GetStat(fname); }
                if(ccontext != null) { return ccontext.GetStat(fname); }
                Debug.LogError("Cannot find actor stat "+fname);
                return float.NaN;
            case LookupType.ActorMountStat: {
                Character m = null;
                if(scontext != null) { m = scontext.character.mountedCharacter; }
                if(econtext != null) { m = econtext.wielder.mountedCharacter; }
                if(ccontext != null) { m = ccontext.mountedCharacter; }
                // Debug.Log("lookup "+fname+" on mount "+m+" ? "+(m != null ? m.GetStat(fname) : 0));
                if(m != null) {
                    return m.GetStat(fname);
                }
                Debug.LogError("Cannot find actor mount stat "+fname);
                return float.NaN;
            }
            case LookupType.ActorMounterStat: {
                Character m = null;
                if(scontext != null) { m = scontext.character.mountingCharacter; }
                if(econtext != null) { m = econtext.wielder.mountingCharacter; }
                if(ccontext != null) { m = ccontext.mountingCharacter; }
                if(m != null) {
                    return m.GetStat(fname);
                }
                Debug.LogError("Cannot find actor mounter stat "+fname);
                return float.NaN;
            }
            case LookupType.ActorEquipmentParam:
                if(scontext != null) {
                    ccontext = scontext.character;
                } else if(ccontext == null && econtext != null) {
                    if(econtext.Matches(f.equipmentSlots, f.equipmentCategories)) {
                        return econtext.GetParam(fname);
                    } else {
                        ccontext = econtext.wielder;
                    }
                }
                return LookupEquipmentParamOn(fname, type, ccontext, f, scontext);
            case LookupType.ActorMountEquipmentParam:
                if(scontext != null) {
                    ccontext = scontext.character.mountedCharacter;
                } else if(ccontext == null && econtext != null) {
                    if(econtext.Matches(f.equipmentSlots, f.equipmentCategories)) {
                        return econtext.GetParam(fname);
                    } else {
                        ccontext = econtext.wielder.mountedCharacter;
                    }
                }
                return LookupEquipmentParamOn(fname, type, ccontext, f, scontext);
            case LookupType.ActorMounterEquipmentParam:
                if(scontext != null) {
                    ccontext = scontext.character.mountingCharacter;
                } else if(ccontext == null && econtext != null) {
                    if(econtext.Matches(f.equipmentSlots, f.equipmentCategories)) {
                        return econtext.GetParam(fname);
                    } else {
                        ccontext = econtext.wielder.mountingCharacter;
                    }
                }
                return LookupEquipmentParamOn(fname, type, ccontext, f, scontext);
            case LookupType.ActorStatusEffect:
            case LookupType.ActorMountStatusEffect:
            case LookupType.ActorMounterStatusEffect:
                Debug.LogError("lookup semantics not defined for own status effect "+fname);
                return float.NaN;
            case LookupType.ActorSkillParam:
                //TODO: look up skill by slot, name, type?
                if(scontext != null) { return scontext.GetParam(fname); }
                Debug.LogError("Cannot find skill param "+fname);
                return float.NaN;
            case LookupType.TargetStat:
                if(scontext != null) { return scontext.currentTargetCharacter.GetStat(fname); }
                if(tcontext != null) { return tcontext.GetStat(fname); }
                Debug.LogError("Cannot find target stat "+fname);
                return float.NaN;
            case LookupType.TargetMountStat: {
                Character m = null;
                if(scontext != null) { m = scontext.currentTargetCharacter.mountedCharacter; }
                if(tcontext != null) { m = tcontext.mountedCharacter; }
                if(m != null) { return m.GetStat(fname); }
                Debug.LogError("Cannot find target stat "+fname);
                return float.NaN;
            }
            case LookupType.TargetMounterStat: {
                Character m = null;
                if(scontext != null) { m = scontext.currentTargetCharacter.mountingCharacter; }
                if(tcontext != null) { m = tcontext.mountingCharacter; }
                if(m != null) { return m.GetStat(fname); }
                Debug.LogError("Cannot find target stat "+fname);
                return float.NaN;
            }
            case LookupType.TargetEquipmentParam:
                if(scontext != null) {
                    ccontext = scontext.currentTargetCharacter;
                } else if(tcontext != null) {
                    ccontext = tcontext;
                } else {
                    ccontext = null;
                }
                return LookupEquipmentParamOn(fname, type, ccontext, f, scontext);
            case LookupType.TargetMountEquipmentParam:
                if(scontext != null) {
                    ccontext = scontext.currentTargetCharacter.mountedCharacter;
                } else if(tcontext != null) {
                    ccontext = tcontext.mountedCharacter;
                } else {
                    ccontext = null;
                }
                return LookupEquipmentParamOn(fname, type, ccontext, f, scontext);
            case LookupType.TargetMounterEquipmentParam:
                if(scontext != null) {
                    ccontext = scontext.currentTargetCharacter.mountingCharacter;
                } else if(tcontext != null) {
                    ccontext = tcontext.mountingCharacter;
                } else {
                    ccontext = null;
                }
                return LookupEquipmentParamOn(fname, type, ccontext, f, scontext);
            case LookupType.TargetStatusEffect:
            case LookupType.TargetMountStatusEffect:
            case LookupType.TargetMounterStatusEffect:
                Debug.LogError("lookup semantics not defined for target status effect "+fname);
                return float.NaN;
            case LookupType.TargetSkillParam:
            case LookupType.ActorMountSkillParam:
            case LookupType.ActorMounterSkillParam:
            case LookupType.TargetMountSkillParam:
            case LookupType.TargetMounterSkillParam:
            //TODO: look up skill by slot, name, type?
                Debug.LogError("Cannot find "+type+" "+fname);
                return float.NaN;
            case LookupType.NamedFormula:
                if(!HasFormula(fname)) {
                    Debug.LogError("Missing formula "+fname);
                    return float.NaN;
                }
                // Debug.Log("F:"+LookupFormula(fname));
                return LookupFormula(fname).GetValue(this, scontext, ccontext, tcontext, econtext, icontext);
            case LookupType.ReactedSkillParam:
                if(scontext != null) {
                    return scontext.currentReactedSkill.GetParam(fname);
                }
                Debug.LogError("Cannot find reacted skill for "+fname);
                return float.NaN;
            case LookupType.ReactedEffectType:
                if(scontext != null) {
                    //ignore lookupRef
                    string[] fnames = f.searchReactedStatNames;
                    var results = scontext.currentReactedSkill.lastEffects.
                        Where(fx => fx.Matches(fnames, f.searchReactedStatChanges, f.searchReactedEffectCategories)).
                        Select(fx => fx.value);
                    switch(f.mergeMode) {
                        case FormulaMergeMode.Sum:
                            return results.Sum();
                        case FormulaMergeMode.Mean:
                            return results.Average(x => x);
                        case FormulaMergeMode.Min:
                            return results.Min(x => x);
                        case FormulaMergeMode.Max:
                            return results.Max(x => x);
                        case FormulaMergeMode.First:
                            return results.First();
                        case FormulaMergeMode.Last:
                            return results.Last();
                        case FormulaMergeMode.Nth:
                            return results.ElementAt(f.mergeNth);
                    }
                } else {
                    Debug.LogError("Skill effect lookups require a skill context.");
                    return float.NaN;
                }
                Debug.LogError("Cannot find reacted effects for "+f);
                return float.NaN;
            case LookupType.SkillEffectType:
                if(scontext != null) {
                    string[] fnames = f.searchReactedStatNames;
                    //ignore lookupRef
                    var results = scontext.lastEffects.
                        Where(fx => fx.Matches(fnames, f.searchReactedStatChanges, f.searchReactedEffectCategories)).
                        Select(fx => fx.value);
                    switch(f.mergeMode) {
                        case FormulaMergeMode.Sum:
                            return results.Sum();
                        case FormulaMergeMode.Mean:
                            return results.Average(x => x);
                        case FormulaMergeMode.Min:
                            return results.Min(x => x);
                        case FormulaMergeMode.Max:
                            return results.Max(x => x);
                        case FormulaMergeMode.First:
                            return results.First();
                        case FormulaMergeMode.Last:
                            return results.Last();
                        case FormulaMergeMode.Nth:
                            Debug.Log("nth "+f.mergeNth+" is "+results.ElementAt(f.mergeNth));
                            return results.ElementAt(f.mergeNth);
                    }
                } else {
                    Debug.LogError("Skill effect lookups require a skill context.");
                    return float.NaN;
                }
                Debug.LogError("Cannot find effects for "+f);
                return float.NaN;
        }
        Debug.LogError("failed to look up "+type+" "+fname+" with context s:"+scontext+", c:"+ccontext+", e:"+econtext+", i:"+icontext+" and formula "+f);
        return float.NaN;
    }

Usage Example

Beispiel #1
0
    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);
    }
All Usage Examples Of Formulae::Lookup