public long Calc(SceneContextInfo context, CharacterProperty source, CharacterProperty target, string proc, params long[] args) { if (GlobalVariables.s_EnableCalculatorLog) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < args.Length; ++i) { sb.Append(args[i].ToString()); if (i + 1 < args.Length) { sb.Append(","); } } LogSystem.Info("[calculator] begin calc proc {0} ({1})", proc, sb.ToString()); } long ret = 0; m_Variables.Clear(); List <Interpreter> exps; if (m_Procs.TryGetValue(proc, out exps)) { for (int i = 0; i < exps.Count; ++i) { ret = exps[i].Calc(context, source, target, args, m_Variables); if (GlobalVariables.s_EnableCalculatorLog) { LogSystem.Info("[calculator] calc proc {0} index {1} result {2}", proc, i, ret); } } } if (GlobalVariables.s_EnableCalculatorLog) { LogSystem.Info("[calculator] end calc proc {0}", proc); } return(ret); }
internal long Calc(SceneContextInfo context, CharacterProperty source, CharacterProperty target, long[] args, Dictionary <int, long> variables) { m_Stack.Clear(); for (int i = 0; i < m_Codes.Count; ++i) { Instruction ins = m_Codes[i]; switch (ins.Opcode) { case InsEnum.CONST: m_Stack.Push(ins.Operand); break; case InsEnum.ATTR: { int id = (int)ins.Operand; long val = source.GetLong((CharacterPropertyEnum)id); m_Stack.Push(val); } break; case InsEnum.ATTR2: { int id = (int)ins.Operand; long val = target.GetLong((CharacterPropertyEnum)id); m_Stack.Push(val); } break; case InsEnum.VALUE: { int id = (int)ins.Operand; TableConfig.Const cfg = TableConfig.ConstProvider.Instance.GetConst(id); if (null != cfg) { m_Stack.Push(cfg.value); } else { m_Stack.Push(0); } } break; case InsEnum.ARG: { int index = (int)ins.Operand; if (index >= 0 && index < args.Length) { m_Stack.Push(args[index]); } else { m_Stack.Push(0); } } break; case InsEnum.VAR: { int id = (int)ins.Operand; long ret; if (!variables.TryGetValue(id, out ret)) { ret = 0; } m_Stack.Push(ret); } break; case InsEnum.ATTRSET: { long op2 = m_Stack.Pop(); int id = (int)ins.Operand; TableConfig.AttrDefine cfg = TableConfig.AttrDefineProvider.Instance.GetAttrDefine(id); if (null != cfg) { if (op2 < cfg.minValue) { op2 = cfg.minValue; } if (op2 > cfg.maxValue) { op2 = cfg.maxValue; } } source.SetLong((CharacterPropertyEnum)id, op2); m_Stack.Push(op2); } break; case InsEnum.VARSET: { long op2 = m_Stack.Pop(); int id = (int)ins.Operand; variables[id] = op2; m_Stack.Push(op2); } break; case InsEnum.ADD: { long op2 = m_Stack.Pop(); long op1 = m_Stack.Pop(); m_Stack.Push(op1 + op2); } break; case InsEnum.SUB: { long op2 = m_Stack.Pop(); long op1 = m_Stack.Pop(); m_Stack.Push(op1 - op2); } break; case InsEnum.MUL: { long op2 = m_Stack.Pop(); long op1 = m_Stack.Pop(); m_Stack.Push(op1 * op2); } break; case InsEnum.DIV: { long op2 = m_Stack.Pop(); long op1 = m_Stack.Pop(); m_Stack.Push(op1 / op2); } break; case InsEnum.MOD: { long op2 = m_Stack.Pop(); long op1 = m_Stack.Pop(); m_Stack.Push(op1 % op2); } break; case InsEnum.MAX: { long op2 = m_Stack.Pop(); long op1 = m_Stack.Pop(); m_Stack.Push(op1 >= op2 ? op1 : op2); } break; case InsEnum.MIN: { long op2 = m_Stack.Pop(); long op1 = m_Stack.Pop(); m_Stack.Push(op1 <= op2 ? op1 : op2); } break; case InsEnum.ABS: { long op2 = m_Stack.Pop(); m_Stack.Push(op2 >= 0 ? op2 : -op2); } break; case InsEnum.CLAMP: { long op3 = m_Stack.Pop(); long op2 = m_Stack.Pop(); long op1 = m_Stack.Pop(); if (op3 < op1) { m_Stack.Push(op1); } else if (op3 > op2) { m_Stack.Push(op2); } else { m_Stack.Push(op3); } } break; } } return(m_Stack.Pop()); }