From 5c5a5cc66227439be7a7b61da5d1ff68cf187ac3 Mon Sep 17 00:00:00 2001
From: hch <305670599@qq.com>
Date: 星期一, 18 八月 2025 22:47:05 +0800
Subject: [PATCH] 117 【武将】武将系统 - 战力计算
---
Main/Common/Jace/CalculationEngine.cs.meta | 2
Main/System/Hero/HeroInfo.Fetter.cs | 51
Main/Common/Jace/Util/MemoryCache.cs | 165 +
Main/Common/Jace/Util/EngineUtil.cs.meta | 2
Main/Common/Jace/Operations/Modulo.cs | 20
Main/Common/Jace/Tokenizer/TokenReader.cs | 255 ++
Main/System/Hero/HeroInfo.InheritPer.cs.meta | 2
Main/Common/Jace/JaceOptions.cs | 87
Main/Common/Jace/Operations/Variable.cs.meta | 2
Main/System/Tip/PowerAddWin.cs | 6
Main/Common/Jace/Operations/GreaterOrEqualThan.cs.meta | 2
Main/Common/Jace/Operations/And.cs | 19
Main/Common/Jace/Operations/Subtraction.cs | 20
Main/System/Hero/HeroInfo.Lineup.cs | 3
Main/Config/Configs/FightPowerRatioConfig.cs | 107 +
Main/Common/Jace/Operations/Multiplication.cs | 20
Main/Common/Jace/Execution/IConstantRegistry.cs.meta | 2
Main/Common/Jace/Execution/ParameterInfo.cs | 14
Main/Common/Jace/Operations/NotEqual.cs | 20
Main/Common/Jace/Util/TypeExtensions.cs | 43
Main/Core/NetworkPackage/DTCFile/ServerPack/HB1_Role/DTCB122_tagSCHeroInfo.cs | 4
Main/Common/Jace/Operations/LessOrEqualThan.cs | 20
Main/Common/Jace/Execution/IFunctionRegistry.cs | 13
Main/Common/Jace/AstBuilder.cs.meta | 2
Main/Config/PartialConfigs/HeroTalentConfig.cs | 4
Main/Common/Jace/Execution/ConstantRegistry.cs.meta | 2
Main/Common/Jace/Execution/DynamicCompiler.cs.meta | 2
Main/Utility/JaceCalculator.cs | 36
Main/System/Hero/HeroInfo.InheritPer.cs | 24
Main/Common/Jace/Operations/Division.cs.meta | 2
Main/Core/NetworkPackage/DTCFile/ServerPack/H04_Scene/DTC0403_tagPlayerLoginLoadOK.cs | 6
Main/Common/Jace/Operations/Exponentiation.cs | 20
Main/Common/Jace/Execution/FunctionInfo.cs.meta | 2
Main/Common/Jace/Operations/LessThan.cs.meta | 2
Main/System/OpenServerActivity/OperationTimeHepler.cs | 72
Main/Common/Jace/Operations/Multiplication.cs.meta | 2
Main/Common/Jace/Operations/NotEqual.cs.meta | 2
Main/System/Equip/EquipModel.cs | 18
Main/Common/Jace/Tokenizer/TokenType.cs.meta | 2
Main/Common/Jace/Operations.meta | 2
Main/Common/Jace/Execution/FunctionInfo.cs | 32
Main/System/Equip/EquipExchangeCell.cs | 5
Main/Common/Jace/Operations/Division.cs | 20
Main/Common/Jace/Operations/Operation.cs.meta | 2
Main/Common/Jace/Tokenizer/TokenType.cs | 18
Main/System/Hero/HeroManager.cs | 4
Main/Common/Jace/Execution/ExecutionMode.cs.meta | 2
Main/Common/Jace/Execution/DynamicCompiler.cs | 327 +++
Main/Common/Jace/VariableNotDefinedException.cs.meta | 2
Main/Common/Jace/ParseException.cs | 19
Main/Common/Jace/Util/TypeExtensions.cs.meta | 2
Main/System/Equip/EquipExchangeWin.cs | 2
Main/Common/Jace/Execution/FormulaBuilder.cs | 131 +
Main/System/HeroUI/HeroTrainWin.cs | 6
Main/Common/Jace/FormulaContext.cs.meta | 2
Main/Common/Jace/Tokenizer/Token.cs.meta | 2
Main/Common/Jace/Operations/Exponentiation.cs.meta | 2
Main/Common/Jace/Operations/GreaterThan.cs.meta | 2
Main/Common/Jace/Execution/ConstantRegistry.cs | 79
Main/Common/Jace/Execution/FunctionRegistry.cs | 119 +
Main/System/HeroUI/HeroUIManager.Reborn.cs | 83
Main/Common/Jace/Tokenizer.meta | 2
Main/Common/Jace/Util/MemoryCache.cs.meta | 2
Main/Common/Jace/Util/MathExtended.cs.meta | 2
Main/System/HeroUI/HeroPosWin.cs | 30
Main/Common/Jace/Operations/Equal.cs | 20
Main/Common/Jace/Execution/FunctionRegistry.cs.meta | 2
Main/System/Hero/HeroAttrType.cs | 8
Main/System/Team/TeamHero.cs | 2
Main/Common/Jace/Execution/IConstantRegistry.cs | 15
Main/Common/Jace/Util/MathExtended.cs | 81
Main/System/HeroUI/HeroUIManager.cs | 295 --
Main/Common/Jace/Execution/IExecutor.cs | 16
Main/Common/Jace/Operations/Constant.cs.meta | 2
Main/Common/Jace/CalculationEngine.cs | 483 ++++
Main/Common/Jace/Operations/GreaterOrEqualThan.cs | 20
Main/Common/Jace/VariableNotDefinedException.cs | 23
Main/Common/Jace/Operations/Modulo.cs.meta | 2
Main/Common/Jace/Operations/And.cs.meta | 2
Main/Common/Jace/Operations/GreaterThan.cs | 20
Main/Common/Jace/Util.meta | 2
Main/System/Hero/HeroInfo.Talent.cs | 71
Main/Common/Jace/Optimizer.cs | 76
Main/Common/Jace/Execution/ConstantInfo.cs | 23
Main/System/Hero/HeroInfo.Properties.cs | 141
Main/Common/Jace/Operations/Equal.cs.meta | 2
Main/Common/Jace/DataType.cs | 13
Main/Config/PartialConfigs/PlayerPropertyConfig.cs | 52
Main/Common/Jace/Operations/Function.cs | 33
Main/Config/Configs/HeroConfig.cs | 6
Main/System/Store/StoreModel.cs | 2
Main/Common/Jace/Optimizer.cs.meta | 2
Main/Common/Jace/Execution/ConstantInfo.cs.meta | 2
Main/System/Main/FightPowerManager.cs | 627 ++++-
Main/Common/Jace/Execution/Interpreter.cs.meta | 2
Main/Common/Jace/Util/FuncAdapter.cs | 126 +
Main/Common/Jace/Operations/LessOrEqualThan.cs.meta | 2
Main/Config/Configs/PlayerLVConfig.cs | 11
Main/System/Hero/HeroInfo.cs | 96
Main/System/UIBase/UIBase.cs | 22
Main/Common/Jace/Tokenizer/TokenReader.cs.meta | 2
Main/Common/Jace/Util/MathUtil.cs.meta | 2
Main/Common/Jace/Execution/ParameterInfo.cs.meta | 2
Main/Common/Jace/Execution/Interpreter.cs | 252 ++
Main/Common/Jace/Util/MathUtil.cs | 30
Main/Common/Jace/Util/EngineUtil.cs | 46
Main/Common/Jace/Operations/Addition.cs.meta | 2
Main/Common/Jace/Operations/Operation.cs | 23
Main/Common/Jace/Execution/ExecutionMode.cs | 13
Main/System/HeroUI/HeroUIManager.OnTeam.cs | 311 +++
Main/Common/Jace/Operations/UnaryMinus.cs.meta | 2
Main/Config/ConfigManager.cs | 3
Main/System/HeroUI/HeroUIManager.Reborn.cs.meta | 2
Main/Component/UI/Effect/UIEffectPlayer.cs | 4
Main/System/CustomizedGift/CustomizedGiftModel.cs | 8
Main/System/KnapSack/Logic/ItemLogicUtility.cs | 19
Main/Common/Jace/Operations/Subtraction.cs.meta | 2
Main/System/HeroUI/HeroUIManager.Collect.cs | 46
Main/Common/Jace.meta | 2
Main/Common/Jace/JaceOptions.cs.meta | 2
Main/Common/Jace/Execution/IExecutor.cs.meta | 2
Main/System/HeroUI/HeroFormationCell.cs | 2
Main/System/Team/TeamBase.cs | 24
Main/Common/Jace/Operations/Function.cs.meta | 2
Main/Common/Jace/Tokenizer/Token.cs | 33
Main/Common/Jace/Execution/FormulaBuilder.cs.meta | 2
Main/Common/Jace/AstBuilder.cs | 372 +++
Main/Common/Jace/Operations/Variable.cs | 37
Main/Config/Configs/FightPowerRatioConfig.cs.meta | 2
Main/Common/Jace/Execution/IFunctionRegistry.cs.meta | 2
Main/System/Hero/HeroInfo.Awake.cs | 83
Main/Common/Jace/FormulaContext.cs | 25
Main/Common/Jace/Execution.meta | 2
Main/Common/Jace/DataType.cs.meta | 2
Main/System/HeroUI/HeroFormationWin.cs | 2
Main/Common/Jace/ParseException.cs.meta | 2
Main/System/HeroUI/HeroLVBreakWin.cs | 2
/dev/null | 11
Main/Common/Jace/Util/FuncAdapter.cs.meta | 2
Main/System/Hero/HeroInfo.Break.cs | 81
Main/Common/Jace/Operations/Or.cs | 19
Main/Common/Jace/Operations/Addition.cs | 20
Main/Common/Jace/Operations/Constant.cs | 48
Main/Common/Jace/Operations/LessThan.cs | 20
Main/Utility/JaceCalculator.cs.meta | 2
Main/Common/Jace/Operations/Or.cs.meta | 2
Main/Common/Jace/Operations/UnaryMinus.cs | 18
Main/System/HeroUI/HeroUIManager.Collect.cs.meta | 2
Main/System/HeroUI/HeroUIManager.OnTeam.cs.meta | 2
149 files changed, 4,982 insertions(+), 892 deletions(-)
diff --git a/Main/Core/GameEngine/Common.meta b/Main/Common/Jace.meta
similarity index 76%
copy from Main/Core/GameEngine/Common.meta
copy to Main/Common/Jace.meta
index 29b34bc..df34b7a 100644
--- a/Main/Core/GameEngine/Common.meta
+++ b/Main/Common/Jace.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 6b68b2e87cfa2fc48aff8e7f40a5c555
+guid: ca353b9337f7a0749a543c104493ccc5
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Main/Common/Jace/AstBuilder.cs b/Main/Common/Jace/AstBuilder.cs
new file mode 100644
index 0000000..713eb25
--- /dev/null
+++ b/Main/Common/Jace/AstBuilder.cs
@@ -0,0 +1,372 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Jace.Execution;
+using Jace.Operations;
+using Jace.Tokenizer;
+using Jace.Util;
+
+namespace Jace
+{
+ public class AstBuilder
+ {
+ private readonly IFunctionRegistry functionRegistry;
+ private readonly IConstantRegistry localConstantRegistry;
+ private readonly bool caseSensitive;
+ private Dictionary<char, int> operationPrecedence = new Dictionary<char, int>();
+ private Stack<Operation> resultStack = new Stack<Operation>();
+ private Stack<Token> operatorStack = new Stack<Token>();
+ private Stack<int> parameterCount = new Stack<int>();
+
+ public AstBuilder(IFunctionRegistry functionRegistry, bool caseSensitive, IConstantRegistry compiledConstants = null)
+ {
+ if (functionRegistry == null)
+ throw new ArgumentNullException("functionRegistry");
+
+ this.functionRegistry = functionRegistry;
+ this.localConstantRegistry = compiledConstants ?? new ConstantRegistry(caseSensitive);
+ this.caseSensitive = caseSensitive;
+
+ operationPrecedence.Add('(', 0);
+ operationPrecedence.Add('&', 1);
+ operationPrecedence.Add('|', 1);
+ operationPrecedence.Add('<', 2);
+ operationPrecedence.Add('>', 2);
+ operationPrecedence.Add('鈮�', 2);
+ operationPrecedence.Add('鈮�', 2);
+ operationPrecedence.Add('鈮�', 2);
+ operationPrecedence.Add('=', 2);
+ operationPrecedence.Add('+', 3);
+ operationPrecedence.Add('-', 3);
+ operationPrecedence.Add('*', 4);
+ operationPrecedence.Add('/', 4);
+ operationPrecedence.Add('%', 4);
+ operationPrecedence.Add('_', 6);
+ operationPrecedence.Add('^', 5);
+ }
+
+ public Operation Build(IList<Token> tokens)
+ {
+ resultStack.Clear();
+ operatorStack.Clear();
+
+ parameterCount.Clear();
+
+ foreach (Token token in tokens)
+ {
+ object value = token.Value;
+
+ switch (token.TokenType)
+ {
+ case TokenType.Integer:
+ resultStack.Push(new IntegerConstant((int)token.Value));
+ break;
+ case TokenType.FloatingPoint:
+ resultStack.Push(new FloatingPointConstant((double)token.Value));
+ break;
+ case TokenType.Text:
+ if (functionRegistry.IsFunctionName((string)token.Value))
+ {
+ operatorStack.Push(token);
+ parameterCount.Push(1);
+ }
+ else
+ {
+ string tokenValue = (string)token.Value;
+ if (localConstantRegistry.IsConstantName(tokenValue))
+ {
+ resultStack.Push(new FloatingPointConstant(localConstantRegistry.GetConstantInfo(tokenValue).Value));
+ }
+ else
+ {
+ if (!caseSensitive)
+ {
+ tokenValue = tokenValue.ToLowerFast();
+ }
+ resultStack.Push(new Variable(tokenValue));
+ }
+ }
+ break;
+ case TokenType.LeftBracket:
+ operatorStack.Push(token);
+ break;
+ case TokenType.RightBracket:
+ PopOperations(true, token);
+ //parameterCount.Pop();
+ break;
+ case TokenType.ArgumentSeparator:
+ PopOperations(false, token);
+ parameterCount.Push(parameterCount.Pop() + 1);
+ break;
+ case TokenType.Operation:
+ Token operation1Token = token;
+ char operation1 = (char)operation1Token.Value;
+
+ while (operatorStack.Count > 0 && (operatorStack.Peek().TokenType == TokenType.Operation ||
+ operatorStack.Peek().TokenType == TokenType.Text))
+ {
+ Token operation2Token = operatorStack.Peek();
+ bool isFunctionOnTopOfStack = operation2Token.TokenType == TokenType.Text;
+
+ if (!isFunctionOnTopOfStack)
+ {
+ char operation2 = (char)operation2Token.Value;
+
+ if ((IsLeftAssociativeOperation(operation1) &&
+ operationPrecedence[operation1] <= operationPrecedence[operation2]) ||
+ (operationPrecedence[operation1] < operationPrecedence[operation2]))
+ {
+ operatorStack.Pop();
+ resultStack.Push(ConvertOperation(operation2Token));
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ operatorStack.Pop();
+ resultStack.Push(ConvertFunction(operation2Token));
+ }
+ }
+
+ operatorStack.Push(operation1Token);
+ break;
+ }
+ }
+
+ PopOperations(false, null);
+
+ VerifyResultStack();
+
+ return resultStack.First();
+ }
+
+ private void PopOperations(bool untillLeftBracket, Token? currentToken)
+ {
+ if (untillLeftBracket && !currentToken.HasValue)
+ throw new ArgumentNullException("currentToken", "If the parameter \"untillLeftBracket\" is set to true, " +
+ "the parameter \"currentToken\" cannot be null.");
+
+ while (operatorStack.Count > 0 && operatorStack.Peek().TokenType != TokenType.LeftBracket)
+ {
+ Token token = operatorStack.Pop();
+
+ switch (token.TokenType)
+ {
+ case TokenType.Operation:
+ resultStack.Push(ConvertOperation(token));
+ break;
+ case TokenType.Text:
+ resultStack.Push(ConvertFunction(token));
+ break;
+ }
+ }
+
+ if (untillLeftBracket)
+ {
+ if (operatorStack.Count > 0 && operatorStack.Peek().TokenType == TokenType.LeftBracket)
+ operatorStack.Pop();
+ else
+ throw new ParseException(string.Format("No matching left bracket found for the right " +
+ "bracket at position {0}.", currentToken.Value.StartPosition));
+ }
+ else
+ {
+ if (operatorStack.Count > 0 && operatorStack.Peek().TokenType == TokenType.LeftBracket
+ && !(currentToken.HasValue && currentToken.Value.TokenType == TokenType.ArgumentSeparator))
+ throw new ParseException(string.Format("No matching right bracket found for the left " +
+ "bracket at position {0}.", operatorStack.Peek().StartPosition));
+ }
+ }
+
+ private Operation ConvertOperation(Token operationToken)
+ {
+ try
+ {
+ DataType dataType;
+ Operation argument1;
+ Operation argument2;
+ Operation divisor;
+ Operation divident;
+
+ switch ((char)operationToken.Value)
+ {
+ case '+':
+ argument2 = resultStack.Pop();
+ argument1 = resultStack.Pop();
+ dataType = RequiredDataType(argument1, argument2);
+
+ return new Addition(dataType, argument1, argument2);
+ case '-':
+ argument2 = resultStack.Pop();
+ argument1 = resultStack.Pop();
+ dataType = RequiredDataType(argument1, argument2);
+
+ return new Subtraction(dataType, argument1, argument2);
+ case '*':
+ argument2 = resultStack.Pop();
+ argument1 = resultStack.Pop();
+ dataType = RequiredDataType(argument1, argument2);
+
+ return new Multiplication(dataType, argument1, argument2);
+ case '/':
+ divisor = resultStack.Pop();
+ divident = resultStack.Pop();
+
+ return new Division(DataType.FloatingPoint, divident, divisor);
+ case '%':
+ divisor = resultStack.Pop();
+ divident = resultStack.Pop();
+
+ return new Modulo(DataType.FloatingPoint, divident, divisor);
+ case '_':
+ argument1 = resultStack.Pop();
+
+ return new UnaryMinus(argument1.DataType, argument1);
+ case '^':
+ Operation exponent = resultStack.Pop();
+ Operation @base = resultStack.Pop();
+
+ return new Exponentiation(DataType.FloatingPoint, @base, exponent);
+ case '&':
+ argument2 = resultStack.Pop();
+ argument1 = resultStack.Pop();
+ dataType = RequiredDataType(argument1, argument2);
+
+ return new And(dataType, argument1, argument2);
+ case '|':
+ argument2 = resultStack.Pop();
+ argument1 = resultStack.Pop();
+ dataType = RequiredDataType(argument1, argument2);
+
+ return new Or(dataType, argument1, argument2);
+ case '<':
+ argument2 = resultStack.Pop();
+ argument1 = resultStack.Pop();
+ dataType = RequiredDataType(argument1, argument2);
+
+ return new LessThan(dataType, argument1, argument2);
+ case '鈮�':
+ argument2 = resultStack.Pop();
+ argument1 = resultStack.Pop();
+ dataType = RequiredDataType(argument1, argument2);
+
+ return new LessOrEqualThan(dataType, argument1, argument2);
+ case '>':
+ argument2 = resultStack.Pop();
+ argument1 = resultStack.Pop();
+ dataType = RequiredDataType(argument1, argument2);
+
+ return new GreaterThan(dataType, argument1, argument2);
+ case '鈮�':
+ argument2 = resultStack.Pop();
+ argument1 = resultStack.Pop();
+ dataType = RequiredDataType(argument1, argument2);
+
+ return new GreaterOrEqualThan(dataType, argument1, argument2);
+ case '=':
+ argument2 = resultStack.Pop();
+ argument1 = resultStack.Pop();
+ dataType = RequiredDataType(argument1, argument2);
+
+ return new Equal(dataType, argument1, argument2);
+ case '鈮�':
+ argument2 = resultStack.Pop();
+ argument1 = resultStack.Pop();
+ dataType = RequiredDataType(argument1, argument2);
+
+ return new NotEqual(dataType, argument1, argument2);
+ default:
+ throw new ArgumentException(string.Format("Unknown operation \"{0}\".", operationToken), "operation");
+ }
+ }
+ catch (InvalidOperationException)
+ {
+ // If we encounter a Stack empty issue this means there is a syntax issue in
+ // the mathematical formula
+ throw new ParseException(string.Format("There is a syntax issue for the operation \"{0}\" at position {1}. " +
+ "The number of arguments does not match with what is expected.", operationToken.Value, operationToken.StartPosition));
+ }
+ }
+
+ private Operation ConvertFunction(Token functionToken)
+ {
+ try
+ {
+ string functionName = ((string)functionToken.Value).ToLowerInvariant();
+
+ if (functionRegistry.IsFunctionName(functionName))
+ {
+ FunctionInfo functionInfo = functionRegistry.GetFunctionInfo(functionName);
+
+ int numberOfParameters;
+
+ if (functionInfo.IsDynamicFunc) {
+ numberOfParameters = parameterCount.Pop();
+ }
+ else {
+ parameterCount.Pop();
+ numberOfParameters = functionInfo.NumberOfParameters;
+ }
+
+ List<Operation> operations = new List<Operation>();
+ for (int i = 0; i < numberOfParameters; i++)
+ operations.Add(resultStack.Pop());
+ operations.Reverse();
+
+ return new Function(DataType.FloatingPoint, functionName, operations, functionInfo.IsIdempotent);
+ }
+ else
+ {
+ throw new ArgumentException(string.Format("Unknown function \"{0}\".", functionToken.Value), "function");
+ }
+ }
+ catch (InvalidOperationException)
+ {
+ // If we encounter a Stack empty issue this means there is a syntax issue in
+ // the mathematical formula
+ throw new ParseException(string.Format("There is a syntax issue for the function \"{0}\" at position {1}. " +
+ "The number of arguments does not match with what is expected.", functionToken.Value, functionToken.StartPosition));
+ }
+ }
+
+ private void VerifyResultStack()
+ {
+ if(resultStack.Count > 1)
+ {
+ Operation[] operations = resultStack.ToArray();
+
+ for (int i = 1; i < operations.Length; i++)
+ {
+ Operation operation = operations[i];
+
+ if (operation.GetType() == typeof(IntegerConstant))
+ {
+ IntegerConstant constant = (IntegerConstant)operation;
+ throw new ParseException(string.Format("Unexpected integer constant \"{0}\" found.", constant.Value));
+ }
+ else if (operation.GetType() == typeof(FloatingPointConstant))
+ {
+ FloatingPointConstant constant = (FloatingPointConstant)operation;
+ throw new ParseException(string.Format("Unexpected floating point constant \"{0}\" found.", constant.Value));
+ }
+ }
+
+ throw new ParseException("The syntax of the provided formula is not valid.");
+ }
+ }
+
+ private bool IsLeftAssociativeOperation(char character)
+ {
+ return character == '*' || character == '+' || character == '-' || character == '/';
+ }
+
+ private DataType RequiredDataType(Operation argument1, Operation argument2)
+ {
+ return (argument1.DataType == DataType.FloatingPoint || argument2.DataType == DataType.FloatingPoint) ? DataType.FloatingPoint : DataType.Integer;
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/AstBuilder.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/AstBuilder.cs.meta
index e37f87e..2b31c6d 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/AstBuilder.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: de824ec81c42eae4888376c8a458a540
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/CalculationEngine.cs b/Main/Common/Jace/CalculationEngine.cs
new file mode 100644
index 0000000..2502c90
--- /dev/null
+++ b/Main/Common/Jace/CalculationEngine.cs
@@ -0,0 +1,483 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Jace.Execution;
+using Jace.Operations;
+using Jace.Tokenizer;
+using Jace.Util;
+
+namespace Jace
+{
+ public delegate TResult DynamicFunc<T, TResult>(params T[] values);
+
+ /// <summary>
+ /// The CalculationEngine class is the main class of Jace.NET to convert strings containing
+ /// mathematical formulas into .NET Delegates and to calculate the result.
+ /// It can be configured to run in a number of modes based on the constructor parameters choosen.
+ /// </summary>
+ public class CalculationEngine
+ {
+ private readonly IExecutor executor;
+ private readonly Optimizer optimizer;
+ private readonly CultureInfo cultureInfo;
+ private readonly MemoryCache<string, Func<IDictionary<string, double>, double>> executionFormulaCache;
+ private readonly bool cacheEnabled;
+ private readonly bool optimizerEnabled;
+ private readonly bool caseSensitive;
+
+ private readonly Random random;
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="CalculationEngine"/> class with
+ /// default parameters.
+ /// </summary>
+ public CalculationEngine()
+ : this(new JaceOptions())
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="CalculationEngine"/> class. The dynamic compiler
+ /// is used for formula execution and the optimizer and cache are enabled.
+ /// </summary>
+ /// <param name="cultureInfo">
+ /// The <see cref="CultureInfo"/> required for correctly reading floating poin numbers.
+ /// </param>
+ public CalculationEngine(CultureInfo cultureInfo)
+ : this(new JaceOptions() { CultureInfo = cultureInfo })
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="CalculationEngine"/> class. The optimizer and
+ /// cache are enabled.
+ /// </summary>
+ /// <param name="cultureInfo">
+ /// The <see cref="CultureInfo"/> required for correctly reading floating poin numbers.
+ /// </param>
+ /// <param name="executionMode">The execution mode that must be used for formula execution.</param>
+ public CalculationEngine(CultureInfo cultureInfo, ExecutionMode executionMode)
+ : this (new JaceOptions() { CultureInfo = cultureInfo, ExecutionMode = executionMode })
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="CalculationEngine"/> class.
+ /// </summary>
+ /// <param name="cultureInfo">
+ /// The <see cref="CultureInfo"/> required for correctly reading floating poin numbers.
+ /// </param>
+ /// <param name="executionMode">The execution mode that must be used for formula execution.</param>
+ /// <param name="cacheEnabled">Enable or disable caching of mathematical formulas.</param>
+ /// <param name="optimizerEnabled">Enable or disable optimizing of formulas.</param>
+ /// <param name="adjustVariableCaseEnabled">Enable or disable auto lowercasing of variables.</param>
+ [Obsolete]
+ public CalculationEngine(CultureInfo cultureInfo, ExecutionMode executionMode, bool cacheEnabled, bool optimizerEnabled, bool adjustVariableCaseEnabled)
+ : this(new JaceOptions() { CultureInfo = cultureInfo, ExecutionMode = executionMode, CacheEnabled = cacheEnabled, OptimizerEnabled = optimizerEnabled, CaseSensitive = !adjustVariableCaseEnabled })
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="CalculationEngine"/> class.
+ /// </summary>
+ /// <param name="cultureInfo">
+ /// The <see cref="CultureInfo"/> required for correctly reading floating poin numbers.
+ /// </param>
+ /// <param name="executionMode">The execution mode that must be used for formula execution.</param>
+ /// <param name="cacheEnabled">Enable or disable caching of mathematical formulas.</param>
+ /// <param name="optimizerEnabled">Enable or disable optimizing of formulas.</param>
+ /// <param name="adjustVariableCaseEnabled">Enable or disable converting to lower case.</param>
+ /// <param name="defaultFunctions">Enable or disable the default functions.</param>
+ /// <param name="defaultConstants">Enable or disable the default constants.</param>
+ /// <param name="cacheMaximumSize">Configure the maximum cache size for mathematical formulas.</param>
+ /// <param name="cacheReductionSize">Configure the cache reduction size for mathematical formulas.</param>
+ [Obsolete]
+ public CalculationEngine(CultureInfo cultureInfo, ExecutionMode executionMode, bool cacheEnabled,
+ bool optimizerEnabled, bool adjustVariableCaseEnabled, bool defaultFunctions, bool defaultConstants, int cacheMaximumSize, int cacheReductionSize)
+ : this(new JaceOptions() { CultureInfo = cultureInfo, ExecutionMode = executionMode, CacheEnabled = cacheEnabled, OptimizerEnabled = optimizerEnabled,
+ CaseSensitive = !adjustVariableCaseEnabled, DefaultFunctions = defaultFunctions, DefaultConstants = defaultConstants,
+ CacheMaximumSize = cacheMaximumSize, CacheReductionSize = cacheReductionSize })
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="CalculationEngine"/> class.
+ /// </summary>
+ /// <param name="options">The <see cref="JaceOptions"/> to configure the behaviour of the engine.</param>
+ public CalculationEngine(JaceOptions options)
+ {
+ this.executionFormulaCache = new MemoryCache<string, Func<IDictionary<string, double>, double>>(options.CacheMaximumSize, options.CacheReductionSize);
+ this.FunctionRegistry = new FunctionRegistry(false);
+ this.ConstantRegistry = new ConstantRegistry(false);
+ this.cultureInfo = options.CultureInfo;
+ this.cacheEnabled = options.CacheEnabled;
+ this.optimizerEnabled = options.OptimizerEnabled;
+ this.caseSensitive = options.CaseSensitive;
+
+ this.random = new Random();
+
+ if (options.ExecutionMode == ExecutionMode.Interpreted)
+ executor = new Interpreter(caseSensitive);
+ else if (options.ExecutionMode == ExecutionMode.Compiled)
+ executor = new DynamicCompiler(caseSensitive);
+ else
+ throw new ArgumentException(string.Format("Unsupported execution mode \"{0}\".", options.ExecutionMode),
+ "executionMode");
+
+ optimizer = new Optimizer(new Interpreter()); // We run the optimizer with the interpreter
+
+ // Register the default constants of Jace.NET into the constant registry
+ if (options.DefaultConstants)
+ RegisterDefaultConstants();
+
+ // Register the default functions of Jace.NET into the function registry
+ if (options.DefaultFunctions)
+ RegisterDefaultFunctions();
+ }
+
+ internal IFunctionRegistry FunctionRegistry { get; private set; }
+
+ internal IConstantRegistry ConstantRegistry { get; private set; }
+
+ public IEnumerable<FunctionInfo> Functions { get { return FunctionRegistry; } }
+
+ public IEnumerable<ConstantInfo> Constants { get { return ConstantRegistry; } }
+
+ public double Calculate(string formulaText)
+ {
+ return Calculate(formulaText, new Dictionary<string, double>());
+ }
+
+ public double Calculate(string formulaText, IDictionary<string, double> variables)
+ {
+ if (string.IsNullOrEmpty(formulaText))
+ throw new ArgumentNullException("formulaText");
+
+ if (variables == null)
+ throw new ArgumentNullException("variables");
+
+ if (!caseSensitive)
+ {
+ variables = EngineUtil.ConvertVariableNamesToLowerCase(variables);
+ }
+ VerifyVariableNames(variables);
+
+ // Add the reserved variables to the dictionary
+ foreach (ConstantInfo constant in ConstantRegistry)
+ variables.Add(constant.ConstantName, constant.Value);
+
+ if (IsInFormulaCache(formulaText, null, out var function))
+ {
+ return function(variables);
+ }
+ else
+ {
+ Operation operation = BuildAbstractSyntaxTree(formulaText, new ConstantRegistry(caseSensitive));
+ function = BuildFormula(formulaText, null, operation);
+ return function(variables);
+ }
+ }
+
+ public FormulaBuilder Formula(string formulaText)
+ {
+ if (string.IsNullOrEmpty(formulaText))
+ throw new ArgumentNullException("formulaText");
+
+ return new FormulaBuilder(formulaText, caseSensitive, this);
+ }
+
+ /// <summary>
+ /// Build a .NET func for the provided formula.
+ /// </summary>
+ /// <param name="formulaText">The formula that must be converted into a .NET func.</param>
+ /// <returns>A .NET func for the provided formula.</returns>
+ public Func<IDictionary<string, double>, double> Build(string formulaText)
+ {
+ if (string.IsNullOrEmpty(formulaText))
+ throw new ArgumentNullException("formulaText");
+
+ if (IsInFormulaCache(formulaText, null, out var result))
+ {
+ return result;
+ }
+ else
+ {
+ Operation operation = BuildAbstractSyntaxTree(formulaText, new ConstantRegistry(caseSensitive));
+ return BuildFormula(formulaText, null, operation);
+ }
+ }
+
+ /// <summary>
+ /// Build a .NET func for the provided formula.
+ /// </summary>
+ /// <param name="formulaText">The formula that must be converted into a .NET func.</param>
+ /// <param name="constants">Constant values for variables defined into the formula. They variables will be replaced by the constant value at pre-compilation time.</param>
+ /// <returns>A .NET func for the provided formula.</returns>
+ public Func<IDictionary<string, double>, double> Build(string formulaText, IDictionary<string, double> constants)
+ {
+ if (string.IsNullOrEmpty(formulaText))
+ throw new ArgumentNullException("formulaText");
+
+
+ ConstantRegistry compiledConstants = new ConstantRegistry(caseSensitive);
+ if (constants != null)
+ {
+ foreach (var constant in constants)
+ {
+ compiledConstants.RegisterConstant(constant.Key, constant.Value);
+ }
+ }
+
+ if (IsInFormulaCache(formulaText, compiledConstants, out var result))
+ {
+ return result;
+ }
+ else
+ {
+ Operation operation = BuildAbstractSyntaxTree(formulaText, compiledConstants);
+ return BuildFormula(formulaText, compiledConstants, operation);
+ }
+ }
+
+ /// <summary>
+ /// Add a function to the calculation engine.
+ /// </summary>
+ /// <param name="functionName">The name of the function. This name can be used in mathematical formulas.</param>
+ /// <param name="function">The implemenation of the function.</param>
+ /// <param name="isIdempotent">Does the function provide the same result when it is executed multiple times.</param>
+ public void AddFunction(string functionName, Func<double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ /// <summary>
+ /// Add a function to the calculation engine.
+ /// </summary>
+ /// <param name="functionName">The name of the function. This name can be used in mathematical formulas.</param>
+ /// <param name="function">The implemenation of the function.</param>
+ /// <param name="isIdempotent">Does the function provide the same result when it is executed multiple times.</param>
+ public void AddFunction(string functionName, Func<double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ /// <summary>
+ /// Add a function to the calculation engine.
+ /// </summary>
+ /// <param name="functionName">The name of the function. This name can be used in mathematical formulas.</param>
+ /// <param name="function">The implemenation of the function.</param>
+ /// <param name="isIdempotent">Does the function provide the same result when it is executed multiple times.</param>
+ public void AddFunction(string functionName, Func<double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ /// <summary>
+ /// Add a function to the calculation engine.
+ /// </summary>
+ /// <param name="functionName">The name of the function. This name can be used in mathematical formulas.</param>
+ /// <param name="function">The implemenation of the function.</param>
+ /// <param name="isIdempotent">Does the function provide the same result when it is executed multiple times.</param>
+ public void AddFunction(string functionName, Func<double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ /// <summary>
+ /// Add a function to the calculation engine.
+ /// </summary>
+ /// <param name="functionName">The name of the function. This name can be used in mathematical formulas.</param>
+ /// <param name="function">The implemenation of the function.</param>
+ /// <param name="isIdempotent">Does the function provide the same result when it is executed multiple times.</param>
+ public void AddFunction(string functionName, Func<double, double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ /// <summary>
+ /// Add a function to the calculation engine.
+ /// </summary>
+ /// <param name="functionName">The name of the function. This name can be used in mathematical formulas.</param>
+ /// <param name="function">The implemenation of the function.</param>
+ /// <param name="isIdempotent">Does the function provide the same result when it is executed multiple times.</param>
+ public void AddFunction(string functionName, Func<double, double, double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ /// <summary>
+ /// Add a function to the calculation engine.
+ /// </summary>
+ /// <param name="functionName">The name of the function. This name can be used in mathematical formulas.</param>
+ /// <param name="function">The implemenation of the function.</param>
+ /// <param name="isIdempotent">Does the function provide the same result when it is executed multiple times.</param>
+ public void AddFunction(string functionName, Func<double, double, double, double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ public void AddFunction(string functionName, Func<double, double, double, double, double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ public void AddFunction(string functionName, Func<double, double, double, double, double, double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ public void AddFunction(string functionName, Func<double, double, double, double, double, double, double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ public void AddFunction(string functionName, Func<double, double, double, double, double, double, double, double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ public void AddFunction(string functionName, Func<double, double, double, double, double, double, double, double, double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ public void AddFunction(string functionName, Func<double, double, double, double, double, double, double, double, double, double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ public void AddFunction(string functionName, Func<double, double, double, double, double, double, double, double, double, double, double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ public void AddFunction(string functionName, Func<double, double, double, double, double, double, double, double, double, double, double, double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ public void AddFunction(string functionName, Func<double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ public void AddFunction(string functionName, Func<double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double> function, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, function, isIdempotent, true);
+ }
+
+ public void AddFunction(string functionName, DynamicFunc<double, double> functionDelegate, bool isIdempotent = true)
+ {
+ FunctionRegistry.RegisterFunction(functionName, functionDelegate, isIdempotent, true);
+ }
+
+ /// <summary>
+ /// Add a constant to the calculation engine.
+ /// </summary>
+ /// <param name="constantName">The name of the constant. This name can be used in mathematical formulas.</param>
+ /// <param name="value">The value of the constant.</param>
+ public void AddConstant(string constantName, double value)
+ {
+ ConstantRegistry.RegisterConstant(constantName, value);
+ }
+
+ private void RegisterDefaultFunctions()
+ {
+ FunctionRegistry.RegisterFunction("sin", (Func<double, double>)Math.Sin, true, false);
+ FunctionRegistry.RegisterFunction("cos", (Func<double, double>)Math.Cos, true, false);
+ FunctionRegistry.RegisterFunction("csc", (Func<double, double>)MathUtil.Csc, true, false);
+ FunctionRegistry.RegisterFunction("sec", (Func<double, double>)MathUtil.Sec, true, false);
+ FunctionRegistry.RegisterFunction("asin", (Func<double, double>)Math.Asin, true, false);
+ FunctionRegistry.RegisterFunction("acos", (Func<double, double>)Math.Acos, true, false);
+ FunctionRegistry.RegisterFunction("tan", (Func<double, double>)Math.Tan, true, false);
+ FunctionRegistry.RegisterFunction("cot", (Func<double, double>)MathUtil.Cot, true, false);
+ FunctionRegistry.RegisterFunction("atan", (Func<double, double>)Math.Atan, true, false);
+ FunctionRegistry.RegisterFunction("acot", (Func<double, double>)MathUtil.Acot, true, false);
+ FunctionRegistry.RegisterFunction("loge", (Func<double, double>)Math.Log, true, false);
+ FunctionRegistry.RegisterFunction("log10", (Func<double, double>)Math.Log10, true, false);
+ FunctionRegistry.RegisterFunction("logn", (Func<double, double, double>)((a, b) => Math.Log(a, b)), true, false);
+ FunctionRegistry.RegisterFunction("sqrt", (Func<double, double>)Math.Sqrt, true, false);
+ FunctionRegistry.RegisterFunction("abs", (Func<double, double>)Math.Abs, true, false);
+ FunctionRegistry.RegisterFunction("if", (Func<double, double, double, double>)((a, b, c) => (a != 0.0 ? b : c)), true, false);
+ FunctionRegistry.RegisterFunction("ifless", (Func<double, double, double, double, double>)((a, b, c, d) => (a < b ? c : d)), true, false);
+ FunctionRegistry.RegisterFunction("ifmore", (Func<double, double, double, double, double>)((a, b, c, d) => (a > b ? c : d)), true, false);
+ FunctionRegistry.RegisterFunction("ifequal", (Func<double, double, double, double, double>)((a, b, c, d) => (a == b ? c : d)), true, false);
+ FunctionRegistry.RegisterFunction("ceiling", (Func<double, double>)Math.Ceiling, true, false);
+ FunctionRegistry.RegisterFunction("floor", (Func<double, double>)Math.Floor, true, false);
+ FunctionRegistry.RegisterFunction("truncate", (Func<double, double>)Math.Truncate, true, false);
+ FunctionRegistry.RegisterFunction("round", (Func<double, double>)Math.Round, true, false);
+
+ // Dynamic based arguments Functions
+ FunctionRegistry.RegisterFunction("max", (DynamicFunc<double, double>)((a) => a.Max()), true, false);
+ FunctionRegistry.RegisterFunction("min", (DynamicFunc<double, double>)((a) => a.Min()), true, false);
+ FunctionRegistry.RegisterFunction("avg", (DynamicFunc<double, double>)((a) => a.Average()), true, false);
+ FunctionRegistry.RegisterFunction("median", (DynamicFunc<double, double>)((a) => MathExtended.Median(a)), true, false);
+
+ // Non Idempotent Functions
+ FunctionRegistry.RegisterFunction("random", (Func<double>)random.NextDouble, false, false);
+ }
+
+ private void RegisterDefaultConstants()
+ {
+ ConstantRegistry.RegisterConstant("e", Math.E, false);
+ ConstantRegistry.RegisterConstant("pi", Math.PI, false);
+ }
+
+ /// <summary>
+ /// Build the abstract syntax tree for a given formula. The formula string will
+ /// be first tokenized.
+ /// </summary>
+ /// <param name="formulaText">A string containing the mathematical formula that must be converted
+ /// into an abstract syntax tree.</param>
+ /// <returns>The abstract syntax tree of the formula.</returns>
+ private Operation BuildAbstractSyntaxTree(string formulaText, ConstantRegistry compiledConstants)
+ {
+ TokenReader tokenReader = new TokenReader(cultureInfo);
+ List<Token> tokens = tokenReader.Read(formulaText);
+
+ AstBuilder astBuilder = new AstBuilder(FunctionRegistry, caseSensitive, compiledConstants);
+ Operation operation = astBuilder.Build(tokens);
+
+ if (optimizerEnabled)
+ return optimizer.Optimize(operation, this.FunctionRegistry, this.ConstantRegistry);
+ else
+ return operation;
+ }
+
+ private Func<IDictionary<string, double>, double> BuildFormula(string formulaText, ConstantRegistry compiledConstants, Operation operation)
+ {
+ return executionFormulaCache.GetOrAdd(GenerateFormulaCacheKey(formulaText, compiledConstants), v => executor.BuildFormula(operation, this.FunctionRegistry, this.ConstantRegistry));
+ }
+
+ private bool IsInFormulaCache(string formulaText, ConstantRegistry compiledConstants, out Func<IDictionary<string, double>, double> function)
+ {
+ function = null;
+ return cacheEnabled && executionFormulaCache.TryGetValue(GenerateFormulaCacheKey(formulaText, compiledConstants), out function);
+ }
+
+ private string GenerateFormulaCacheKey(string formulaText, ConstantRegistry compiledConstants)
+ {
+ return (compiledConstants != null && compiledConstants.Any()) ? $"{formulaText}@{String.Join(",", compiledConstants?.Select(x => $"{x.ConstantName}:{x.Value}"))}" : formulaText;
+ }
+
+ /// <summary>
+ /// Verify a collection of variables to ensure that all the variable names are valid.
+ /// Users are not allowed to overwrite reserved variables or use function names as variables.
+ /// If an invalid variable is detected an exception is thrown.
+ /// </summary>
+ /// <param name="variables">The colletion of variables that must be verified.</param>
+ internal void VerifyVariableNames(IDictionary<string, double> variables)
+ {
+ foreach (string variableName in variables.Keys)
+ {
+ if(ConstantRegistry.IsConstantName(variableName) && !ConstantRegistry.GetConstantInfo(variableName).IsOverWritable)
+ throw new ArgumentException(string.Format("The name \"{0}\" is a reservered variable name that cannot be overwritten.", variableName), "variables");
+
+ if (FunctionRegistry.IsFunctionName(variableName))
+ throw new ArgumentException(string.Format("The name \"{0}\" is a function name. Parameters cannot have this name.", variableName), "variables");
+ }
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/CalculationEngine.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/CalculationEngine.cs.meta
index e37f87e..0304ee1 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/CalculationEngine.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 7605496412e5ed546a6ab8ccba648580
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/DataType.cs b/Main/Common/Jace/DataType.cs
new file mode 100644
index 0000000..33a7a56
--- /dev/null
+++ b/Main/Common/Jace/DataType.cs
@@ -0,0 +1,13 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace
+{
+ public enum DataType
+ {
+ Integer,
+ FloatingPoint
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/DataType.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/DataType.cs.meta
index e37f87e..0f3254c 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/DataType.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: f30cb87ce5accbe4ebcbc950c4eaae28
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Core/GameEngine/Common.meta b/Main/Common/Jace/Execution.meta
similarity index 76%
rename from Main/Core/GameEngine/Common.meta
rename to Main/Common/Jace/Execution.meta
index 29b34bc..e4ad765 100644
--- a/Main/Core/GameEngine/Common.meta
+++ b/Main/Common/Jace/Execution.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 6b68b2e87cfa2fc48aff8e7f40a5c555
+guid: 9d45a5ae0f6671f4783425dac0689ce4
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Main/Common/Jace/Execution/ConstantInfo.cs b/Main/Common/Jace/Execution/ConstantInfo.cs
new file mode 100644
index 0000000..f9fb700
--- /dev/null
+++ b/Main/Common/Jace/Execution/ConstantInfo.cs
@@ -0,0 +1,23 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Execution
+{
+ public class ConstantInfo
+ {
+ public ConstantInfo(string constantName, double value, bool isOverWritable)
+ {
+ this.ConstantName = constantName;
+ this.Value = value;
+ this.IsOverWritable = isOverWritable;
+ }
+
+ public string ConstantName { get; private set; }
+
+ public double Value { get; private set; }
+
+ public bool IsOverWritable { get; set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Execution/ConstantInfo.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Execution/ConstantInfo.cs.meta
index e37f87e..08c5741 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Execution/ConstantInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 80e7b1aba7b9c2245b2b872f018c07d6
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Execution/ConstantRegistry.cs b/Main/Common/Jace/Execution/ConstantRegistry.cs
new file mode 100644
index 0000000..f934105
--- /dev/null
+++ b/Main/Common/Jace/Execution/ConstantRegistry.cs
@@ -0,0 +1,79 @@
+锘縰sing System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Jace.Util;
+
+namespace Jace.Execution
+{
+ public class ConstantRegistry : IConstantRegistry
+ {
+ private readonly bool caseSensitive;
+ private readonly Dictionary<string, ConstantInfo> constants;
+
+ public ConstantRegistry(bool caseSensitive)
+ {
+ this.caseSensitive = caseSensitive;
+ this.constants = new Dictionary<string, ConstantInfo>();
+ }
+
+ public IEnumerator<ConstantInfo> GetEnumerator()
+ {
+ return constants.Values.GetEnumerator();
+ }
+
+ IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return this.GetEnumerator();
+ }
+
+ public ConstantInfo GetConstantInfo(string constantName)
+ {
+ if (string.IsNullOrEmpty(constantName))
+ throw new ArgumentNullException("constantName");
+
+ ConstantInfo constantInfo = null;
+ return constants.TryGetValue(ConvertConstantName(constantName), out constantInfo) ? constantInfo : null;
+ }
+
+ public bool IsConstantName(string constantName)
+ {
+ if (string.IsNullOrEmpty(constantName))
+ throw new ArgumentNullException("constantName");
+
+ return constants.ContainsKey(ConvertConstantName(constantName));
+ }
+
+ public void RegisterConstant(string constantName, double value)
+ {
+ RegisterConstant(constantName, value, true);
+ }
+
+ public void RegisterConstant(string constantName, double value, bool isOverWritable)
+ {
+ if(string.IsNullOrEmpty(constantName))
+ throw new ArgumentNullException("constantName");
+
+ constantName = ConvertConstantName(constantName);
+
+ if (constants.ContainsKey(constantName) && !constants[constantName].IsOverWritable)
+ {
+ string message = string.Format("The constant \"{0}\" cannot be overwriten.", constantName);
+ throw new Exception(message);
+ }
+
+ ConstantInfo constantInfo = new ConstantInfo(constantName, value, isOverWritable);
+
+ if (constants.ContainsKey(constantName))
+ constants[constantName] = constantInfo;
+ else
+ constants.Add(constantName, constantInfo);
+ }
+
+ private string ConvertConstantName(string constantName)
+ {
+ return caseSensitive ? constantName : constantName.ToLowerFast();
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Execution/ConstantRegistry.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Execution/ConstantRegistry.cs.meta
index e37f87e..7ca5785 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Execution/ConstantRegistry.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 4c5b0410c8fc58445a69f737f244707e
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Execution/DynamicCompiler.cs b/Main/Common/Jace/Execution/DynamicCompiler.cs
new file mode 100644
index 0000000..a45480a
--- /dev/null
+++ b/Main/Common/Jace/Execution/DynamicCompiler.cs
@@ -0,0 +1,327 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Text;
+using Jace.Operations;
+using Jace.Util;
+
+namespace Jace.Execution
+{
+ public class DynamicCompiler : IExecutor
+ {
+ private string FuncAssemblyQualifiedName;
+ private readonly bool caseSensitive;
+
+ public DynamicCompiler(): this(false) { }
+ public DynamicCompiler(bool caseSensitive)
+ {
+ this.caseSensitive = caseSensitive;
+ // The lower func reside in mscorelib, the higher ones in another assembly.
+ // This is an easy cross platform way to to have this AssemblyQualifiedName.
+ FuncAssemblyQualifiedName =
+ typeof(Func<double, double, double, double, double, double, double, double, double, double>).GetTypeInfo().Assembly.FullName;
+ }
+
+ public double Execute(Operation operation, IFunctionRegistry functionRegistry, IConstantRegistry constantRegistry)
+ {
+ return Execute(operation, functionRegistry, constantRegistry, new Dictionary<string, double>());
+ }
+
+ public double Execute(Operation operation, IFunctionRegistry functionRegistry, IConstantRegistry constantRegistry,
+ IDictionary<string, double> variables)
+ {
+ return BuildFormula(operation, functionRegistry, constantRegistry)(variables);
+ }
+
+ public Func<IDictionary<string, double>, double> BuildFormula(Operation operation,
+ IFunctionRegistry functionRegistry, IConstantRegistry constantRegistry)
+ {
+ Func<FormulaContext, double> func = BuildFormulaInternal(operation, functionRegistry);
+ return caseSensitive
+ ? (Func<IDictionary<string, double>, double>)(variables =>
+ {
+ return func(new FormulaContext(variables, functionRegistry, constantRegistry));
+ })
+ : (Func<IDictionary<string, double>, double>)(variables =>
+ {
+ variables = EngineUtil.ConvertVariableNamesToLowerCase(variables);
+ FormulaContext context = new FormulaContext(variables, functionRegistry, constantRegistry);
+ return func(context);
+ });
+ }
+
+ private Func<FormulaContext, double> BuildFormulaInternal(Operation operation,
+ IFunctionRegistry functionRegistry)
+ {
+ ParameterExpression contextParameter = Expression.Parameter(typeof(FormulaContext), "context");
+
+ LabelTarget returnLabel = Expression.Label(typeof(double));
+
+ Expression<Func<FormulaContext, double>> lambda = Expression.Lambda<Func<FormulaContext, double>>(
+ GenerateMethodBody(operation, contextParameter, functionRegistry),
+ contextParameter
+ );
+ return lambda.Compile();
+ }
+
+
+
+ private Expression GenerateMethodBody(Operation operation, ParameterExpression contextParameter,
+ IFunctionRegistry functionRegistry)
+ {
+ if (operation == null)
+ throw new ArgumentNullException("operation");
+
+ if (operation.GetType() == typeof(IntegerConstant))
+ {
+ IntegerConstant constant = (IntegerConstant)operation;
+
+ double value = constant.Value;
+ return Expression.Constant(value, typeof(double));
+ }
+ else if (operation.GetType() == typeof(FloatingPointConstant))
+ {
+ FloatingPointConstant constant = (FloatingPointConstant)operation;
+
+ return Expression.Constant(constant.Value, typeof(double));
+ }
+ else if (operation.GetType() == typeof(Variable))
+ {
+ Variable variable = (Variable)operation;
+
+ Func<string, FormulaContext, double> getVariableValueOrThrow = PrecompiledMethods.GetVariableValueOrThrow;
+ return Expression.Call(null,
+ getVariableValueOrThrow.GetMethodInfo(),
+ Expression.Constant(variable.Name),
+ contextParameter);
+ }
+ else if (operation.GetType() == typeof(Multiplication))
+ {
+ Multiplication multiplication = (Multiplication)operation;
+ Expression argument1 = GenerateMethodBody(multiplication.Argument1, contextParameter, functionRegistry);
+ Expression argument2 = GenerateMethodBody(multiplication.Argument2, contextParameter, functionRegistry);
+
+ return Expression.Multiply(argument1, argument2);
+ }
+ else if (operation.GetType() == typeof(Addition))
+ {
+ Addition addition = (Addition)operation;
+ Expression argument1 = GenerateMethodBody(addition.Argument1, contextParameter, functionRegistry);
+ Expression argument2 = GenerateMethodBody(addition.Argument2, contextParameter, functionRegistry);
+
+ return Expression.Add(argument1, argument2);
+ }
+ else if (operation.GetType() == typeof(Subtraction))
+ {
+ Subtraction addition = (Subtraction)operation;
+ Expression argument1 = GenerateMethodBody(addition.Argument1, contextParameter, functionRegistry);
+ Expression argument2 = GenerateMethodBody(addition.Argument2, contextParameter, functionRegistry);
+
+ return Expression.Subtract(argument1, argument2);
+ }
+ else if (operation.GetType() == typeof(Division))
+ {
+ Division division = (Division)operation;
+ Expression dividend = GenerateMethodBody(division.Dividend, contextParameter, functionRegistry);
+ Expression divisor = GenerateMethodBody(division.Divisor, contextParameter, functionRegistry);
+
+ return Expression.Divide(dividend, divisor);
+ }
+ else if (operation.GetType() == typeof(Modulo))
+ {
+ Modulo modulo = (Modulo)operation;
+ Expression dividend = GenerateMethodBody(modulo.Dividend, contextParameter, functionRegistry);
+ Expression divisor = GenerateMethodBody(modulo.Divisor, contextParameter, functionRegistry);
+
+ return Expression.Modulo(dividend, divisor);
+ }
+ else if (operation.GetType() == typeof(Exponentiation))
+ {
+ Exponentiation exponentation = (Exponentiation)operation;
+ Expression @base = GenerateMethodBody(exponentation.Base, contextParameter, functionRegistry);
+ Expression exponent = GenerateMethodBody(exponentation.Exponent, contextParameter, functionRegistry);
+
+ return Expression.Call(null, typeof(Math).GetRuntimeMethod("Pow", new Type[] { typeof(double), typeof(double) }), @base, exponent);
+ }
+ else if (operation.GetType() == typeof(UnaryMinus))
+ {
+ UnaryMinus unaryMinus = (UnaryMinus)operation;
+ Expression argument = GenerateMethodBody(unaryMinus.Argument, contextParameter, functionRegistry);
+ return Expression.Negate(argument);
+ }
+ else if (operation.GetType() == typeof(And))
+ {
+ And and = (And)operation;
+ Expression argument1 = Expression.NotEqual(GenerateMethodBody(and.Argument1, contextParameter, functionRegistry), Expression.Constant(0.0));
+ Expression argument2 = Expression.NotEqual(GenerateMethodBody(and.Argument2, contextParameter, functionRegistry), Expression.Constant(0.0));
+
+ return Expression.Condition(Expression.And(argument1, argument2),
+ Expression.Constant(1.0),
+ Expression.Constant(0.0));
+ }
+ else if (operation.GetType() == typeof(Or))
+ {
+ Or and = (Or)operation;
+ Expression argument1 = Expression.NotEqual(GenerateMethodBody(and.Argument1, contextParameter, functionRegistry), Expression.Constant(0.0));
+ Expression argument2 = Expression.NotEqual(GenerateMethodBody(and.Argument2, contextParameter, functionRegistry), Expression.Constant(0.0));
+
+ return Expression.Condition(Expression.Or(argument1, argument2),
+ Expression.Constant(1.0),
+ Expression.Constant(0.0));
+ }
+ else if (operation.GetType() == typeof(LessThan))
+ {
+ LessThan lessThan = (LessThan)operation;
+ Expression argument1 = GenerateMethodBody(lessThan.Argument1, contextParameter, functionRegistry);
+ Expression argument2 = GenerateMethodBody(lessThan.Argument2, contextParameter, functionRegistry);
+
+ return Expression.Condition(Expression.LessThan(argument1, argument2),
+ Expression.Constant(1.0),
+ Expression.Constant(0.0));
+ }
+ else if (operation.GetType() == typeof(LessOrEqualThan))
+ {
+ LessOrEqualThan lessOrEqualThan = (LessOrEqualThan)operation;
+ Expression argument1 = GenerateMethodBody(lessOrEqualThan.Argument1, contextParameter, functionRegistry);
+ Expression argument2 = GenerateMethodBody(lessOrEqualThan.Argument2, contextParameter, functionRegistry);
+
+ return Expression.Condition(Expression.LessThanOrEqual(argument1, argument2),
+ Expression.Constant(1.0),
+ Expression.Constant(0.0));
+ }
+ else if (operation.GetType() == typeof(GreaterThan))
+ {
+ GreaterThan greaterThan = (GreaterThan)operation;
+ Expression argument1 = GenerateMethodBody(greaterThan.Argument1, contextParameter, functionRegistry);
+ Expression argument2 = GenerateMethodBody(greaterThan.Argument2, contextParameter, functionRegistry);
+
+ return Expression.Condition(Expression.GreaterThan(argument1, argument2),
+ Expression.Constant(1.0),
+ Expression.Constant(0.0));
+ }
+ else if (operation.GetType() == typeof(GreaterOrEqualThan))
+ {
+ GreaterOrEqualThan greaterOrEqualThan = (GreaterOrEqualThan)operation;
+ Expression argument1 = GenerateMethodBody(greaterOrEqualThan.Argument1, contextParameter, functionRegistry);
+ Expression argument2 = GenerateMethodBody(greaterOrEqualThan.Argument2, contextParameter, functionRegistry);
+
+ return Expression.Condition(Expression.GreaterThanOrEqual(argument1, argument2),
+ Expression.Constant(1.0),
+ Expression.Constant(0.0));
+ }
+ else if (operation.GetType() == typeof(Equal))
+ {
+ Equal equal = (Equal)operation;
+ Expression argument1 = GenerateMethodBody(equal.Argument1, contextParameter, functionRegistry);
+ Expression argument2 = GenerateMethodBody(equal.Argument2, contextParameter, functionRegistry);
+
+ return Expression.Condition(Expression.Equal(argument1, argument2),
+ Expression.Constant(1.0),
+ Expression.Constant(0.0));
+ }
+ else if (operation.GetType() == typeof(NotEqual))
+ {
+ NotEqual notEqual = (NotEqual)operation;
+ Expression argument1 = GenerateMethodBody(notEqual.Argument1, contextParameter, functionRegistry);
+ Expression argument2 = GenerateMethodBody(notEqual.Argument2, contextParameter, functionRegistry);
+
+ return Expression.Condition(Expression.NotEqual(argument1, argument2),
+ Expression.Constant(1.0),
+ Expression.Constant(0.0));
+ }
+ else if (operation.GetType() == typeof(Function))
+ {
+ Function function = (Function)operation;
+
+ FunctionInfo functionInfo = functionRegistry.GetFunctionInfo(function.FunctionName);
+ Type funcType;
+ Type[] parameterTypes;
+ Expression[] arguments;
+
+ if (functionInfo.IsDynamicFunc)
+ {
+ funcType = typeof(DynamicFunc<double, double>);
+ parameterTypes = new Type[] { typeof(double[]) };
+
+
+ Expression[] arrayArguments = new Expression[function.Arguments.Count];
+ for (int i = 0; i < function.Arguments.Count; i++)
+ arrayArguments[i] = GenerateMethodBody(function.Arguments[i], contextParameter, functionRegistry);
+
+ arguments = new Expression[1];
+ arguments[0] = NewArrayExpression.NewArrayInit(typeof(double), arrayArguments);
+ }
+ else
+ {
+ funcType = GetFuncType(functionInfo.NumberOfParameters);
+ parameterTypes = (from i in Enumerable.Range(0, functionInfo.NumberOfParameters)
+ select typeof(double)).ToArray();
+
+ arguments = new Expression[functionInfo.NumberOfParameters];
+ for (int i = 0; i < functionInfo.NumberOfParameters; i++)
+ arguments[i] = GenerateMethodBody(function.Arguments[i], contextParameter, functionRegistry);
+ }
+
+ Expression getFunctionRegistry = Expression.Property(contextParameter, "FunctionRegistry");
+
+ ParameterExpression functionInfoVariable = Expression.Variable(typeof(FunctionInfo));
+
+ Expression funcInstance;
+ if (!functionInfo.IsOverWritable)
+ {
+ funcInstance = Expression.Convert(
+ Expression.Property(
+ Expression.Call(
+ getFunctionRegistry,
+ typeof(IFunctionRegistry).GetRuntimeMethod("GetFunctionInfo", new Type[] { typeof(string) }),
+ Expression.Constant(function.FunctionName)),
+ "Function"),
+ funcType);
+ }
+ else
+ funcInstance = Expression.Constant(functionInfo.Function, funcType);
+
+ return Expression.Call(
+ funcInstance,
+ funcType.GetRuntimeMethod("Invoke", parameterTypes),
+ arguments);
+ }
+ else
+ {
+ throw new ArgumentException(string.Format("Unsupported operation \"{0}\".", operation.GetType().FullName), "operation");
+ }
+ }
+
+ private Type GetFuncType(int numberOfParameters)
+ {
+ string funcTypeName;
+ if (numberOfParameters < 9)
+ funcTypeName = string.Format("System.Func`{0}", numberOfParameters + 1);
+ else
+ funcTypeName = string.Format("System.Func`{0}, {1}", numberOfParameters + 1, FuncAssemblyQualifiedName);
+ Type funcType = Type.GetType(funcTypeName);
+
+ Type[] typeArguments = new Type[numberOfParameters + 1];
+ for (int i = 0; i < typeArguments.Length; i++)
+ typeArguments[i] = typeof(double);
+
+ return funcType.MakeGenericType(typeArguments);
+ }
+
+ private static class PrecompiledMethods
+ {
+ public static double GetVariableValueOrThrow(string variableName, FormulaContext context)
+ {
+ if (context.Variables.TryGetValue(variableName, out double result))
+ return result;
+ else if (context.ConstantRegistry.IsConstantName(variableName))
+ return context.ConstantRegistry.GetConstantInfo(variableName).Value;
+ else
+ throw new VariableNotDefinedException($"The variable \"{variableName}\" used is not defined.");
+ }
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Execution/DynamicCompiler.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Execution/DynamicCompiler.cs.meta
index e37f87e..3cb36e7 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Execution/DynamicCompiler.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: c058c0ded31899643b05723eafcafc40
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Execution/ExecutionMode.cs b/Main/Common/Jace/Execution/ExecutionMode.cs
new file mode 100644
index 0000000..d498740
--- /dev/null
+++ b/Main/Common/Jace/Execution/ExecutionMode.cs
@@ -0,0 +1,13 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Execution
+{
+ public enum ExecutionMode
+ {
+ Interpreted,
+ Compiled
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Execution/ExecutionMode.cs.meta
similarity index 83%
rename from Main/System/Hero/HeroInfo.Quality.cs.meta
rename to Main/Common/Jace/Execution/ExecutionMode.cs.meta
index e37f87e..52335f6 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Execution/ExecutionMode.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 0d9522fc6bc25a644b4074177b045fc6
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Execution/FormulaBuilder.cs b/Main/Common/Jace/Execution/FormulaBuilder.cs
new file mode 100644
index 0000000..63945d9
--- /dev/null
+++ b/Main/Common/Jace/Execution/FormulaBuilder.cs
@@ -0,0 +1,131 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Text;
+using Jace.Operations;
+using Jace.Util;
+
+namespace Jace.Execution
+{
+ public class FormulaBuilder
+ {
+ private readonly CalculationEngine engine;
+
+ private string formulaText;
+ private bool caseSensitive;
+ private DataType? resultDataType;
+ private List<ParameterInfo> parameters;
+ private IDictionary<string, double> constants;
+
+ /// <summary>
+ /// Creates a new instance of the FormulaBuilder class.
+ /// </summary>
+ /// <param name="formulaText">
+ /// A calculation engine instance that can be used for interpreting and executing
+ /// the formula.
+ /// </param>
+ internal FormulaBuilder(string formulaText, bool caseSensitive, CalculationEngine engine)
+ {
+ this.parameters = new List<ParameterInfo>();
+ this.constants = new Dictionary<string, double>();
+ this.formulaText = formulaText;
+ this.engine = engine;
+ this.caseSensitive = caseSensitive;
+ }
+
+ /// <summary>
+ /// Add a new parameter to the formula being constructed. Parameters are
+ /// added in the order of which they are defined.
+ /// </summary>
+ /// <param name="name">The name of the parameter.</param>
+ /// <param name="dataType">The date type of the parameter.</param>
+ /// <returns>The <see cref="FormulaBuilder"/> instance.</returns>
+ public FormulaBuilder Parameter(string name, DataType dataType)
+ {
+ if (string.IsNullOrEmpty(name))
+ throw new ArgumentNullException("name");
+
+ if (engine.FunctionRegistry.IsFunctionName(name))
+ throw new ArgumentException(string.Format("The name \"{0}\" is a function name. Parameters cannot have this name.", name), "name");
+
+ if (parameters.Any(p => p.Name == name))
+ throw new ArgumentException(string.Format("A parameter with the name \"{0}\" was already defined.", name), "name");
+
+ parameters.Add(new ParameterInfo() {Name = name, DataType = dataType});
+ return this;
+ }
+
+ /// <summary>
+ /// Add a new constant to the formula being constructed.
+ /// </summary>
+ /// <param name="name">The name of the constant.</param>
+ /// <param name="constantValue">The value of the constant. Variables for which a constant value is defined will be replaced at pre-compilation time.</param>
+ /// <returns>The <see cref="FormulaBuilder"/> instance.</returns>
+ public FormulaBuilder Constant(string name, int constantValue)
+ {
+ return Constant(name, (double)constantValue);
+ }
+
+ /// <summary>
+ /// Add a new constant to the formula being constructed. The
+ /// </summary>
+ /// <param name="name">The name of the constant.</param>
+ /// <param name="constantValue">The value of the constant.</param>
+ /// <returns>The <see cref="FormulaBuilder"/> instance.</returns>
+ public FormulaBuilder Constant(string name, double constantValue)
+ {
+ if (string.IsNullOrEmpty(name))
+ throw new ArgumentNullException("name");
+
+ if (constants.Any(p => p.Key == name))
+ throw new ArgumentException(string.Format("A constant with the name \"{0}\" was already defined.", name), "name");
+
+ constants[name] = constantValue;
+ return this;
+ }
+
+ /// <summary>
+ /// Define the result data type for the formula.
+ /// </summary>
+ /// <param name="dataType">The result data type for the formula.</param>
+ /// <returns>The <see cref="FormulaBuilder"/> instance.</returns>
+ public FormulaBuilder Result(DataType dataType)
+ {
+ if (resultDataType.HasValue)
+ throw new InvalidOperationException("The result can only be defined once for a given formula.");
+
+ resultDataType = dataType;
+ return this;
+ }
+
+ /// <summary>
+ /// Build the formula defined. This will create a func delegate matching with the parameters
+ /// and the return type specified.
+ /// </summary>
+ /// <returns>The func delegate for the defined formula.</returns>
+ public Delegate Build()
+ {
+ if (!resultDataType.HasValue)
+ throw new Exception("Please define a result data type for the formula.");
+
+ Func<IDictionary<string, double>, double> formula = engine.Build(formulaText, constants);
+
+ FuncAdapter adapter = new FuncAdapter();
+ return adapter.Wrap(parameters, variables => {
+
+ if(!caseSensitive)
+ variables = EngineUtil.ConvertVariableNamesToLowerCase(variables);
+
+ engine.VerifyVariableNames(variables);
+
+ // Add the reserved variables to the dictionary
+ foreach (ConstantInfo constant in engine.ConstantRegistry)
+ variables.Add(constant.ConstantName, constant.Value);
+
+ return formula(variables);
+ });
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Execution/FormulaBuilder.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Execution/FormulaBuilder.cs.meta
index e37f87e..0a021cd 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Execution/FormulaBuilder.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: b422f2fc8278c544db048c826ec43f40
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Execution/FunctionInfo.cs b/Main/Common/Jace/Execution/FunctionInfo.cs
new file mode 100644
index 0000000..6451ef6
--- /dev/null
+++ b/Main/Common/Jace/Execution/FunctionInfo.cs
@@ -0,0 +1,32 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Execution
+{
+ public class FunctionInfo
+ {
+ public FunctionInfo(string functionName, int numberOfParameters, bool isIdempotent, bool isOverWritable, bool isDynamicFunc, Delegate function)
+ {
+ this.FunctionName = functionName;
+ this.NumberOfParameters = numberOfParameters;
+ this.IsIdempotent = isIdempotent;
+ this.IsOverWritable = isOverWritable;
+ this.IsDynamicFunc = isDynamicFunc;
+ this.Function = function;
+ }
+
+ public string FunctionName { get; private set; }
+
+ public int NumberOfParameters { get; private set; }
+
+ public bool IsOverWritable { get; set; }
+
+ public bool IsIdempotent { get; set; }
+
+ public bool IsDynamicFunc { get; private set; }
+
+ public Delegate Function { get; private set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Execution/FunctionInfo.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Execution/FunctionInfo.cs.meta
index e37f87e..3126408 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Execution/FunctionInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 68afcf59c23204e4f83b55a9555fa566
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Execution/FunctionRegistry.cs b/Main/Common/Jace/Execution/FunctionRegistry.cs
new file mode 100644
index 0000000..721bf3b
--- /dev/null
+++ b/Main/Common/Jace/Execution/FunctionRegistry.cs
@@ -0,0 +1,119 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using System.Collections;
+using Jace.Util;
+
+namespace Jace.Execution
+{
+ public class FunctionRegistry : IFunctionRegistry
+ {
+ private const string DynamicFuncName = "Jace.DynamicFunc";
+
+ private readonly bool caseSensitive;
+ private readonly Dictionary<string, FunctionInfo> functions;
+
+ public FunctionRegistry(bool caseSensitive)
+ {
+ this.caseSensitive = caseSensitive;
+ this.functions = new Dictionary<string, FunctionInfo>();
+ }
+
+ public IEnumerator<FunctionInfo> GetEnumerator()
+ {
+ return functions.Values.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return this.GetEnumerator();
+ }
+
+ public FunctionInfo GetFunctionInfo(string functionName)
+ {
+ if (string.IsNullOrEmpty(functionName))
+ throw new ArgumentNullException("functionName");
+
+ FunctionInfo functionInfo = null;
+ return functions.TryGetValue(ConvertFunctionName(functionName), out functionInfo) ? functionInfo : null;
+ }
+
+ public void RegisterFunction(string functionName, Delegate function)
+ {
+ RegisterFunction(functionName, function, true, true);
+ }
+
+ public void RegisterFunction(string functionName, Delegate function, bool isIdempotent, bool isOverWritable)
+ {
+ if (string.IsNullOrEmpty(functionName))
+ throw new ArgumentNullException("functionName");
+
+ if (function == null)
+ throw new ArgumentNullException("function");
+
+ Type funcType = function.GetType();
+ bool isDynamicFunc = false;
+ int numberOfParameters = -1;
+
+ if (funcType.FullName.StartsWith("System.Func"))
+ {
+ foreach (Type genericArgument in funcType.GenericTypeArguments)
+ if (genericArgument != typeof(double))
+ throw new ArgumentException("Only doubles are supported as function arguments.", "function");
+
+ numberOfParameters = function
+ .GetMethodInfo()
+ .GetParameters()
+ .Count(p => p.ParameterType == typeof(double));
+ }
+ else if (funcType.FullName.StartsWith(DynamicFuncName))
+ {
+ isDynamicFunc = true;
+ }
+ else
+ throw new ArgumentException("Only System.Func and " + DynamicFuncName + " delegates are permitted.", "function");
+
+ functionName = ConvertFunctionName(functionName);
+
+ if (functions.ContainsKey(functionName) && !functions[functionName].IsOverWritable)
+ {
+ string message = string.Format("The function \"{0}\" cannot be overwriten.", functionName);
+ throw new Exception(message);
+ }
+
+ if (functions.ContainsKey(functionName) && functions[functionName].NumberOfParameters != numberOfParameters)
+ {
+ string message = string.Format("The number of parameters cannot be changed when overwriting a method.");
+ throw new Exception(message);
+ }
+
+ if (functions.ContainsKey(functionName) && functions[functionName].IsDynamicFunc != isDynamicFunc)
+ {
+ string message = string.Format("A Func can only be overwritten by another Func and a DynamicFunc can only be overwritten by another DynamicFunc.");
+ throw new Exception(message);
+ }
+
+ FunctionInfo functionInfo = new FunctionInfo(functionName, numberOfParameters, isIdempotent, isOverWritable, isDynamicFunc, function);
+
+ if (functions.ContainsKey(functionName))
+ functions[functionName] = functionInfo;
+ else
+ functions.Add(functionName, functionInfo);
+ }
+
+ public bool IsFunctionName(string functionName)
+ {
+ if (string.IsNullOrEmpty(functionName))
+ throw new ArgumentNullException("functionName");
+
+ return functions.ContainsKey(ConvertFunctionName(functionName));
+ }
+
+ private string ConvertFunctionName(string functionName)
+ {
+ return caseSensitive ? functionName : functionName.ToLowerFast();
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Execution/FunctionRegistry.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Execution/FunctionRegistry.cs.meta
index e37f87e..94a6a38 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Execution/FunctionRegistry.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: a23e9d8bb99397f4b932d1802e5e1a30
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Execution/IConstantRegistry.cs b/Main/Common/Jace/Execution/IConstantRegistry.cs
new file mode 100644
index 0000000..88823c1
--- /dev/null
+++ b/Main/Common/Jace/Execution/IConstantRegistry.cs
@@ -0,0 +1,15 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Execution
+{
+ public interface IConstantRegistry : IEnumerable<ConstantInfo>
+ {
+ ConstantInfo GetConstantInfo(string constantName);
+ bool IsConstantName(string constantName);
+ void RegisterConstant(string constantName, double value);
+ void RegisterConstant(string constantName, double value, bool isOverWritable);
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Execution/IConstantRegistry.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Execution/IConstantRegistry.cs.meta
index e37f87e..b72ea7d 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Execution/IConstantRegistry.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: ac1d9141e70689a4ea802b6b9d653707
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Execution/IExecutor.cs b/Main/Common/Jace/Execution/IExecutor.cs
new file mode 100644
index 0000000..2d29143
--- /dev/null
+++ b/Main/Common/Jace/Execution/IExecutor.cs
@@ -0,0 +1,16 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Jace.Operations;
+
+namespace Jace.Execution
+{
+ public interface IExecutor
+ {
+ double Execute(Operation operation, IFunctionRegistry functionRegistry, IConstantRegistry constantRegistry);
+ double Execute(Operation operation, IFunctionRegistry functionRegistry, IConstantRegistry constantRegistry, IDictionary<string, double> variables);
+
+ Func<IDictionary<string, double>, double> BuildFormula(Operation operation, IFunctionRegistry functionRegistry, IConstantRegistry constantRegistry);
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Execution/IExecutor.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Execution/IExecutor.cs.meta
index e37f87e..e2246b5 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Execution/IExecutor.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 5cc438b6f6efc8143b63e3107ce1eb9c
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Execution/IFunctionRegistry.cs b/Main/Common/Jace/Execution/IFunctionRegistry.cs
new file mode 100644
index 0000000..35cc2dd
--- /dev/null
+++ b/Main/Common/Jace/Execution/IFunctionRegistry.cs
@@ -0,0 +1,13 @@
+锘縰sing System;
+using System.Collections.Generic;
+
+namespace Jace.Execution
+{
+ public interface IFunctionRegistry : IEnumerable<FunctionInfo>
+ {
+ FunctionInfo GetFunctionInfo(string functionName);
+ bool IsFunctionName(string functionName);
+ void RegisterFunction(string functionName, Delegate function);
+ void RegisterFunction(string functionName, Delegate function, bool isIdempotent, bool isOverWritable);
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Execution/IFunctionRegistry.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Execution/IFunctionRegistry.cs.meta
index e37f87e..d2c110a 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Execution/IFunctionRegistry.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 5c0e119822c96154a90ac4a9e37de0d9
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Execution/Interpreter.cs b/Main/Common/Jace/Execution/Interpreter.cs
new file mode 100644
index 0000000..1b89e73
--- /dev/null
+++ b/Main/Common/Jace/Execution/Interpreter.cs
@@ -0,0 +1,252 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Jace.Operations;
+using Jace.Util;
+
+namespace Jace.Execution
+{
+ public class Interpreter : IExecutor
+ {
+ private readonly bool caseSensitive;
+
+ public Interpreter(): this(false) { }
+
+ public Interpreter(bool caseSensitive)
+ {
+ this.caseSensitive = caseSensitive;
+ }
+ public Func<IDictionary<string, double>, double> BuildFormula(Operation operation,
+ IFunctionRegistry functionRegistry,
+ IConstantRegistry constantRegistry)
+ {
+ return caseSensitive
+ ? (Func<IDictionary<string, double>, double>)(variables =>
+ {
+ return Execute(operation, functionRegistry, constantRegistry, variables);
+ })
+ : (Func<IDictionary<string, double>, double>)(variables =>
+ {
+ variables = EngineUtil.ConvertVariableNamesToLowerCase(variables);
+ return Execute(operation, functionRegistry, constantRegistry, variables);
+ });
+ }
+
+ public double Execute(Operation operation, IFunctionRegistry functionRegistry, IConstantRegistry constantRegistry)
+ {
+ return Execute(operation, functionRegistry, constantRegistry, new Dictionary<string, double>());
+ }
+
+ public double Execute(Operation operation,
+ IFunctionRegistry functionRegistry,
+ IConstantRegistry constantRegistry,
+ IDictionary<string, double> variables)
+ {
+ if (operation == null)
+ throw new ArgumentNullException("operation");
+
+ if (operation.GetType() == typeof(IntegerConstant))
+ {
+ IntegerConstant constant = (IntegerConstant)operation;
+ return constant.Value;
+ }
+ else if (operation.GetType() == typeof(FloatingPointConstant))
+ {
+ FloatingPointConstant constant = (FloatingPointConstant)operation;
+ return constant.Value;
+ }
+ else if (operation.GetType() == typeof(Variable))
+ {
+ Variable variable = (Variable)operation;
+
+ double value;
+ bool variableFound = variables.TryGetValue(variable.Name, out value);
+
+ if (variableFound)
+ return value;
+ else
+ throw new VariableNotDefinedException(string.Format("The variable \"{0}\" used is not defined.", variable.Name));
+ }
+ else if (operation.GetType() == typeof(Multiplication))
+ {
+ Multiplication multiplication = (Multiplication)operation;
+ return Execute(multiplication.Argument1, functionRegistry, constantRegistry, variables) * Execute(multiplication.Argument2, functionRegistry, constantRegistry, variables);
+ }
+ else if (operation.GetType() == typeof(Addition))
+ {
+ Addition addition = (Addition)operation;
+ return Execute(addition.Argument1, functionRegistry, constantRegistry, variables) + Execute(addition.Argument2, functionRegistry, constantRegistry, variables);
+ }
+ else if (operation.GetType() == typeof(Subtraction))
+ {
+ Subtraction addition = (Subtraction)operation;
+ return Execute(addition.Argument1, functionRegistry, constantRegistry, variables) - Execute(addition.Argument2, functionRegistry, constantRegistry, variables);
+ }
+ else if (operation.GetType() == typeof(Division))
+ {
+ Division division = (Division)operation;
+ return Execute(division.Dividend, functionRegistry, constantRegistry, variables) / Execute(division.Divisor, functionRegistry, constantRegistry, variables);
+ }
+ else if (operation.GetType() == typeof(Modulo))
+ {
+ Modulo division = (Modulo)operation;
+ return Execute(division.Dividend, functionRegistry, constantRegistry, variables) % Execute(division.Divisor, functionRegistry, constantRegistry, variables);
+ }
+ else if (operation.GetType() == typeof(Exponentiation))
+ {
+ Exponentiation exponentiation = (Exponentiation)operation;
+ return Math.Pow(Execute(exponentiation.Base, functionRegistry, constantRegistry, variables), Execute(exponentiation.Exponent, functionRegistry, constantRegistry, variables));
+ }
+ else if (operation.GetType() == typeof(UnaryMinus))
+ {
+ UnaryMinus unaryMinus = (UnaryMinus)operation;
+ return -Execute(unaryMinus.Argument, functionRegistry, constantRegistry, variables);
+ }
+ else if (operation.GetType() == typeof(And))
+ {
+ And and = (And)operation;
+ var operation1 = Execute(and.Argument1, functionRegistry, constantRegistry, variables) != 0;
+ var operation2 = Execute(and.Argument2, functionRegistry, constantRegistry, variables) != 0;
+
+ return (operation1 && operation2) ? 1.0 : 0.0;
+ }
+ else if (operation.GetType() == typeof(Or))
+ {
+ Or or = (Or)operation;
+ var operation1 = Execute(or.Argument1, functionRegistry, constantRegistry, variables) != 0;
+ var operation2 = Execute(or.Argument2, functionRegistry, constantRegistry, variables) != 0;
+
+ return (operation1 || operation2) ? 1.0 : 0.0;
+ }
+ else if(operation.GetType() == typeof(LessThan))
+ {
+ LessThan lessThan = (LessThan)operation;
+ return (Execute(lessThan.Argument1, functionRegistry, constantRegistry, variables) < Execute(lessThan.Argument2, functionRegistry, constantRegistry, variables)) ? 1.0 : 0.0;
+ }
+ else if (operation.GetType() == typeof(LessOrEqualThan))
+ {
+ LessOrEqualThan lessOrEqualThan = (LessOrEqualThan)operation;
+ return (Execute(lessOrEqualThan.Argument1, functionRegistry, constantRegistry, variables) <= Execute(lessOrEqualThan.Argument2, functionRegistry, constantRegistry, variables)) ? 1.0 : 0.0;
+ }
+ else if (operation.GetType() == typeof(GreaterThan))
+ {
+ GreaterThan greaterThan = (GreaterThan)operation;
+ return (Execute(greaterThan.Argument1, functionRegistry, constantRegistry, variables) > Execute(greaterThan.Argument2, functionRegistry, constantRegistry, variables)) ? 1.0 : 0.0;
+ }
+ else if (operation.GetType() == typeof(GreaterOrEqualThan))
+ {
+ GreaterOrEqualThan greaterOrEqualThan = (GreaterOrEqualThan)operation;
+ return (Execute(greaterOrEqualThan.Argument1, functionRegistry, constantRegistry, variables) >= Execute(greaterOrEqualThan.Argument2, functionRegistry, constantRegistry, variables)) ? 1.0 : 0.0;
+ }
+ else if (operation.GetType() == typeof(Equal))
+ {
+ Equal equal = (Equal)operation;
+ return (Execute(equal.Argument1, functionRegistry, constantRegistry, variables) == Execute(equal.Argument2, functionRegistry, constantRegistry, variables)) ? 1.0 : 0.0;
+ }
+ else if (operation.GetType() == typeof(NotEqual))
+ {
+ NotEqual notEqual = (NotEqual)operation;
+ return (Execute(notEqual.Argument1, functionRegistry, constantRegistry, variables) != Execute(notEqual.Argument2, functionRegistry, constantRegistry, variables)) ? 1.0 : 0.0;
+ }
+ else if (operation.GetType() == typeof(Function))
+ {
+ Function function = (Function)operation;
+
+ FunctionInfo functionInfo = functionRegistry.GetFunctionInfo(function.FunctionName);
+
+ double[] arguments = new double[functionInfo.IsDynamicFunc ? function.Arguments.Count : functionInfo.NumberOfParameters];
+ for (int i = 0; i < arguments.Length; i++)
+ arguments[i] = Execute(function.Arguments[i], functionRegistry, constantRegistry, variables);
+
+ return Invoke(functionInfo.Function, arguments);
+ }
+ else
+ {
+ throw new ArgumentException(string.Format("Unsupported operation \"{0}\".", operation.GetType().FullName), "operation");
+ }
+ }
+
+ private double Invoke(Delegate function, double[] arguments)
+ {
+ // DynamicInvoke is slow, so we first try to convert it to a Func
+ if (function is Func<double>)
+ {
+ return ((Func<double>)function).Invoke();
+ }
+ else if (function is Func<double, double>)
+ {
+ return ((Func<double, double>)function).Invoke(arguments[0]);
+ }
+ else if (function is Func<double, double, double>)
+ {
+ return ((Func<double, double, double>)function).Invoke(arguments[0], arguments[1]);
+ }
+ else if (function is Func<double, double, double, double>)
+ {
+ return ((Func<double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2]);
+ }
+ else if (function is Func<double, double, double, double, double>)
+ {
+ return ((Func<double, double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2], arguments[3]);
+ }
+ else if (function is Func<double, double, double, double, double, double>)
+ {
+ return ((Func<double, double, double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
+ }
+ else if (function is Func<double, double, double, double, double, double, double>)
+ {
+ return ((Func<double, double, double, double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
+ }
+ else if (function is Func<double, double, double, double, double, double, double, double>)
+ {
+ return ((Func<double, double, double, double, double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);
+ }
+ else if (function is Func<double, double, double, double, double, double, double, double, double>)
+ {
+ return ((Func<double, double, double, double, double, double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]);
+ }
+ else if (function is Func<double, double, double, double, double, double, double, double, double, double>)
+ {
+ return ((Func<double, double, double, double, double, double, double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8]);
+ }
+ else if (function is Func<double, double, double, double, double, double, double, double, double, double, double>)
+ {
+ return ((Func<double, double, double, double, double, double, double, double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9]);
+ }
+ else if (function is Func<double, double, double, double, double, double, double, double, double, double, double, double>)
+ {
+ return ((Func<double, double, double, double, double, double, double, double, double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10]);
+ }
+ else if (function is Func<double, double, double, double, double, double, double, double, double, double, double, double, double>)
+ {
+ return ((Func<double, double, double, double, double, double, double, double, double, double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]);
+ }
+ else if (function is Func<double, double, double, double, double, double, double, double, double, double, double, double, double, double>)
+ {
+ return ((Func<double, double, double, double, double, double, double, double, double, double, double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12]);
+ }
+ else if (function is Func<double, double, double, double, double, double, double, double, double, double, double, double, double, double, double>)
+ {
+ return ((Func<double, double, double, double, double, double, double, double, double, double, double, double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13]);
+ }
+ else if (function is Func<double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double>)
+ {
+ return ((Func<double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14]);
+ }
+ else if (function is Func<double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double>)
+ {
+ return ((Func<double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double>)function).Invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]);
+ }
+ else if (function is DynamicFunc<double, double>)
+ {
+ return ((DynamicFunc<double, double>)function).Invoke(arguments);
+ }
+ else
+ {
+ return (double)function.DynamicInvoke((from s in arguments select (object)s).ToArray());
+ }
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Execution/Interpreter.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Execution/Interpreter.cs.meta
index e37f87e..3a04dab 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Execution/Interpreter.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 880be476462899f4aa9a1e05d9b1e50f
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Execution/ParameterInfo.cs b/Main/Common/Jace/Execution/ParameterInfo.cs
new file mode 100644
index 0000000..1d4e811
--- /dev/null
+++ b/Main/Common/Jace/Execution/ParameterInfo.cs
@@ -0,0 +1,14 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Jace.Operations;
+
+namespace Jace.Execution
+{
+ public struct ParameterInfo
+ {
+ public string Name;
+ public DataType DataType;
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Execution/ParameterInfo.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Execution/ParameterInfo.cs.meta
index e37f87e..7cc3ee4 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Execution/ParameterInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: f118a37bdba42b8459abfd0f2cc2179b
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/FormulaContext.cs b/Main/Common/Jace/FormulaContext.cs
new file mode 100644
index 0000000..677366e
--- /dev/null
+++ b/Main/Common/Jace/FormulaContext.cs
@@ -0,0 +1,25 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Jace.Execution;
+
+namespace Jace
+{
+ public class FormulaContext
+ {
+ public FormulaContext(IDictionary<string, double> variables,
+ IFunctionRegistry functionRegistry,
+ IConstantRegistry constantRegistry)
+ {
+ this.Variables = variables;
+ this.FunctionRegistry = functionRegistry;
+ this.ConstantRegistry = constantRegistry;
+ }
+
+ public IDictionary<string, double> Variables { get; private set; }
+
+ public IFunctionRegistry FunctionRegistry { get; private set; }
+ public IConstantRegistry ConstantRegistry { get; private set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/FormulaContext.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/FormulaContext.cs.meta
index e37f87e..6845e47 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/FormulaContext.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 766328a00fcb8a545bd00380387bbc50
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/JaceOptions.cs b/Main/Common/Jace/JaceOptions.cs
new file mode 100644
index 0000000..a360e70
--- /dev/null
+++ b/Main/Common/Jace/JaceOptions.cs
@@ -0,0 +1,87 @@
+锘縰sing Jace.Execution;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+
+namespace Jace
+{
+ public class JaceOptions
+ {
+ internal const int DefaultCacheMaximumSize = 500;
+ internal const int DefaultCacheReductionSize = 50;
+
+ public JaceOptions()
+ {
+ CultureInfo = CultureInfo.CurrentCulture;
+ ExecutionMode = ExecutionMode.Compiled;
+ CacheEnabled = true;
+ OptimizerEnabled = true;
+ CaseSensitive = false;
+ DefaultFunctions = true;
+ DefaultConstants = true;
+ CacheMaximumSize = DefaultCacheMaximumSize;
+ CacheReductionSize = DefaultCacheReductionSize;
+ }
+
+ /// <summary>
+ /// The <see cref="CultureInfo"/> required for correctly reading floating poin numbers.
+ /// </summary>
+ public CultureInfo CultureInfo { get; set; }
+
+ /// <summary>
+ /// The execution mode that must be used for formula execution.
+ /// </summary>
+ public ExecutionMode ExecutionMode { get; set; }
+
+ /// <summary>
+ /// Enable or disable caching of mathematical formulas.
+ /// </summary>
+ public bool CacheEnabled { get; set; }
+
+ /// <summary>
+ /// Configure the maximum cache size for mathematical formulas.
+ /// </summary>
+ public int CacheMaximumSize { get; set; }
+
+ /// <summary>
+ /// Configure the cache reduction size for mathematical formulas.
+ /// </summary>
+ public int CacheReductionSize { get; set; }
+
+ /// <summary>
+ /// Enable or disable optimizing of formulas.
+ /// </summary>
+ public bool OptimizerEnabled { get; set; }
+
+ /// <summary>
+ /// Enable or disable converting to lower case. This parameter is the inverse of <see cref="CaseSensitive"/>.
+ /// </summary>
+ [Obsolete]
+ public bool AdjustVariableCase {
+ get
+ {
+ return !CaseSensitive;
+ }
+ set
+ {
+ CaseSensitive = !value;
+ }
+ }
+
+ /// <summary>
+ /// Enable case sensitive or case insensitive processing mode.
+ /// </summary>
+ public bool CaseSensitive { get; set; }
+
+ /// <summary>
+ /// Enable or disable the default functions.
+ /// </summary>
+ public bool DefaultFunctions { get; set; }
+
+ /// <summary>
+ /// Enable or disable the default constants.
+ /// </summary>
+ public bool DefaultConstants { get; set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/JaceOptions.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/JaceOptions.cs.meta
index e37f87e..7899e31 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/JaceOptions.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: da15a14f53646d442988e85bc2545dc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Core/GameEngine/Common.meta b/Main/Common/Jace/Operations.meta
similarity index 76%
copy from Main/Core/GameEngine/Common.meta
copy to Main/Common/Jace/Operations.meta
index 29b34bc..420fc54 100644
--- a/Main/Core/GameEngine/Common.meta
+++ b/Main/Common/Jace/Operations.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 6b68b2e87cfa2fc48aff8e7f40a5c555
+guid: d825ff71751c9124885a7751c284959d
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Main/Common/Jace/Operations/Addition.cs b/Main/Common/Jace/Operations/Addition.cs
new file mode 100644
index 0000000..36036d1
--- /dev/null
+++ b/Main/Common/Jace/Operations/Addition.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class Addition : Operation
+ {
+ public Addition(DataType dataType, Operation argument1, Operation argument2)
+ : base(dataType, argument1.DependsOnVariables || argument2.DependsOnVariables, argument1.IsIdempotent && argument2.IsIdempotent)
+ {
+ this.Argument1 = argument1;
+ this.Argument2 = argument2;
+ }
+
+ public Operation Argument1 { get; internal set; }
+ public Operation Argument2 { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/Addition.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/Addition.cs.meta
index e37f87e..5529d30 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/Addition.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 340301d5fb1dce54ab7dec7873ceea4d
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/And.cs b/Main/Common/Jace/Operations/And.cs
new file mode 100644
index 0000000..83e6d88
--- /dev/null
+++ b/Main/Common/Jace/Operations/And.cs
@@ -0,0 +1,19 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class And : Operation
+ {
+ public And(DataType dataType, Operation argument1, Operation argument2)
+ : base(dataType, argument1.DependsOnVariables || argument2.DependsOnVariables, argument1.IsIdempotent && argument2.IsIdempotent)
+ {
+ this.Argument1 = argument1;
+ this.Argument2 = argument2;
+ }
+
+ public Operation Argument1 { get; internal set; }
+ public Operation Argument2 { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/And.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/And.cs.meta
index e37f87e..eb33300 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/And.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: c88e04049f2269a498cfedbd3fc9576c
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/Constant.cs b/Main/Common/Jace/Operations/Constant.cs
new file mode 100644
index 0000000..02d7ae2
--- /dev/null
+++ b/Main/Common/Jace/Operations/Constant.cs
@@ -0,0 +1,48 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public abstract class Constant<T> : Operation
+ {
+ public Constant(DataType dataType, T value)
+ : base(dataType, false, true)
+ {
+ this.Value = value;
+ }
+
+ public T Value { get; private set; }
+
+ public override bool Equals(object obj)
+ {
+ Constant<T> other = obj as Constant<T>;
+ if (other != null)
+ return this.Value.Equals(other.Value);
+ else
+ return false;
+ }
+
+ public override int GetHashCode()
+ {
+ return this.Value.GetHashCode();
+ }
+ }
+
+ public class IntegerConstant : Constant<int>
+ {
+ public IntegerConstant(int value)
+ : base(DataType.Integer, value)
+ {
+ }
+ }
+
+ public class FloatingPointConstant : Constant<double>
+ {
+ public FloatingPointConstant(double value)
+ : base(DataType.FloatingPoint, value)
+ {
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/Constant.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/Constant.cs.meta
index e37f87e..884d3a1 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/Constant.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 65575909546ce144e83dd420135e0a01
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/Division.cs b/Main/Common/Jace/Operations/Division.cs
new file mode 100644
index 0000000..afe220a
--- /dev/null
+++ b/Main/Common/Jace/Operations/Division.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class Division : Operation
+ {
+ public Division(DataType dataType, Operation dividend, Operation divisor)
+ : base(dataType, dividend.DependsOnVariables || divisor.DependsOnVariables, dividend.IsIdempotent && divisor.IsIdempotent)
+ {
+ this.Dividend = dividend;
+ this.Divisor = divisor;
+ }
+
+ public Operation Dividend { get; internal set; }
+ public Operation Divisor { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/Division.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/Division.cs.meta
index e37f87e..92ceabb 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/Division.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 353c124902c7984429815571216959bf
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/Equal.cs b/Main/Common/Jace/Operations/Equal.cs
new file mode 100644
index 0000000..8c02a92
--- /dev/null
+++ b/Main/Common/Jace/Operations/Equal.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class Equal : Operation
+ {
+ public Equal(DataType dataType, Operation argument1, Operation argument2)
+ : base(dataType, argument1.DependsOnVariables || argument2.DependsOnVariables, argument1.IsIdempotent && argument2.IsIdempotent)
+ {
+ this.Argument1 = argument1;
+ this.Argument2 = argument2;
+ }
+
+ public Operation Argument1 { get; internal set; }
+ public Operation Argument2 { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/Equal.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/Equal.cs.meta
index e37f87e..1040a3e 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/Equal.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 87cffdc974ef87a4ab8c92b5321424c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/Exponentiation.cs b/Main/Common/Jace/Operations/Exponentiation.cs
new file mode 100644
index 0000000..08bf94f
--- /dev/null
+++ b/Main/Common/Jace/Operations/Exponentiation.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class Exponentiation : Operation
+ {
+ public Exponentiation(DataType dataType, Operation @base, Operation exponent)
+ : base(dataType, @base.DependsOnVariables || exponent.DependsOnVariables, @base.IsIdempotent && exponent.IsIdempotent)
+ {
+ Base = @base;
+ Exponent = exponent;
+ }
+
+ public Operation Base { get; internal set; }
+ public Operation Exponent { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/Exponentiation.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/Exponentiation.cs.meta
index e37f87e..d727984 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/Exponentiation.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 2491ad50c77e631489551371d36bab46
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/Function.cs b/Main/Common/Jace/Operations/Function.cs
new file mode 100644
index 0000000..b5dac27
--- /dev/null
+++ b/Main/Common/Jace/Operations/Function.cs
@@ -0,0 +1,33 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class Function : Operation
+ {
+ private IList<Operation> arguments;
+
+ public Function(DataType dataType, string functionName, IList<Operation> arguments, bool isIdempotent)
+ : base(dataType, arguments.FirstOrDefault(o => o.DependsOnVariables) != null, isIdempotent && arguments.All(o => o.IsIdempotent))
+ {
+ this.FunctionName = functionName;
+ this.arguments = arguments;
+ }
+
+ public string FunctionName { get; private set; }
+
+ public IList<Operation> Arguments {
+ get
+ {
+ return arguments;
+ }
+ internal set
+ {
+ this.arguments = value;
+ this.DependsOnVariables = arguments.FirstOrDefault(o => o.DependsOnVariables) != null;
+ }
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/Function.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/Function.cs.meta
index e37f87e..2d85b00 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/Function.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 8cea584356c80194eac8e7f5905d7764
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/GreaterOrEqualThan.cs b/Main/Common/Jace/Operations/GreaterOrEqualThan.cs
new file mode 100644
index 0000000..9513c64
--- /dev/null
+++ b/Main/Common/Jace/Operations/GreaterOrEqualThan.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class GreaterOrEqualThan : Operation
+ {
+ public GreaterOrEqualThan(DataType dataType, Operation argument1, Operation argument2)
+ : base(dataType, argument1.DependsOnVariables || argument2.DependsOnVariables, argument1.IsIdempotent && argument2.IsIdempotent)
+ {
+ this.Argument1 = argument1;
+ this.Argument2 = argument2;
+ }
+
+ public Operation Argument1 { get; internal set; }
+ public Operation Argument2 { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/GreaterOrEqualThan.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/GreaterOrEqualThan.cs.meta
index e37f87e..d74513f 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/GreaterOrEqualThan.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: a5f7058c1a38e5e4da81a637c5ca0fb8
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/GreaterThan.cs b/Main/Common/Jace/Operations/GreaterThan.cs
new file mode 100644
index 0000000..a720fac
--- /dev/null
+++ b/Main/Common/Jace/Operations/GreaterThan.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class GreaterThan : Operation
+ {
+ public GreaterThan(DataType dataType, Operation argument1, Operation argument2)
+ : base(dataType, argument1.DependsOnVariables || argument2.DependsOnVariables, argument1.IsIdempotent && argument2.IsIdempotent)
+ {
+ this.Argument1 = argument1;
+ this.Argument2 = argument2;
+ }
+
+ public Operation Argument1 { get; internal set; }
+ public Operation Argument2 { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/GreaterThan.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/GreaterThan.cs.meta
index e37f87e..451136d 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/GreaterThan.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: aa4d6a9b5c1549743bd305b4e87c56b8
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/LessOrEqualThan.cs b/Main/Common/Jace/Operations/LessOrEqualThan.cs
new file mode 100644
index 0000000..3574dcc
--- /dev/null
+++ b/Main/Common/Jace/Operations/LessOrEqualThan.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class LessOrEqualThan : Operation
+ {
+ public LessOrEqualThan(DataType dataType, Operation argument1, Operation argument2)
+ : base(dataType, argument1.DependsOnVariables || argument2.DependsOnVariables, argument1.IsIdempotent && argument2.IsIdempotent)
+ {
+ this.Argument1 = argument1;
+ this.Argument2 = argument2;
+ }
+
+ public Operation Argument1 { get; internal set; }
+ public Operation Argument2 { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/LessOrEqualThan.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/LessOrEqualThan.cs.meta
index e37f87e..da86a83 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/LessOrEqualThan.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 22813b990f9481c41b94640a98d29719
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/LessThan.cs b/Main/Common/Jace/Operations/LessThan.cs
new file mode 100644
index 0000000..132b1f4
--- /dev/null
+++ b/Main/Common/Jace/Operations/LessThan.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class LessThan : Operation
+ {
+ public LessThan(DataType dataType, Operation argument1, Operation argument2)
+ : base(dataType, argument1.DependsOnVariables || argument2.DependsOnVariables, argument1.IsIdempotent && argument2.IsIdempotent)
+ {
+ this.Argument1 = argument1;
+ this.Argument2 = argument2;
+ }
+
+ public Operation Argument1 { get; internal set; }
+ public Operation Argument2 { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/LessThan.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/LessThan.cs.meta
index e37f87e..36a5163 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/LessThan.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 259c10599a2e2a74b86a83682dc05cc1
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/Modulo.cs b/Main/Common/Jace/Operations/Modulo.cs
new file mode 100644
index 0000000..3271750
--- /dev/null
+++ b/Main/Common/Jace/Operations/Modulo.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class Modulo : Operation
+ {
+ public Modulo(DataType dataType, Operation dividend, Operation divisor)
+ : base(dataType, dividend.DependsOnVariables || divisor.DependsOnVariables, dividend.IsIdempotent && divisor.IsIdempotent)
+ {
+ this.Dividend = dividend;
+ this.Divisor = divisor;
+ }
+
+ public Operation Dividend { get; internal set; }
+ public Operation Divisor { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/Modulo.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/Modulo.cs.meta
index e37f87e..adee485 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/Modulo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 20b05091ee3aab546b21bcbde58b826c
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/Multiplication.cs b/Main/Common/Jace/Operations/Multiplication.cs
new file mode 100644
index 0000000..5a3587c
--- /dev/null
+++ b/Main/Common/Jace/Operations/Multiplication.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class Multiplication : Operation
+ {
+ public Multiplication(DataType dataType, Operation argument1, Operation argument2)
+ : base(dataType, argument1.DependsOnVariables || argument2.DependsOnVariables, argument1.IsIdempotent && argument2.IsIdempotent)
+ {
+ this.Argument1 = argument1;
+ this.Argument2 = argument2;
+ }
+
+ public Operation Argument1 { get; internal set; }
+ public Operation Argument2 { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/Multiplication.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/Multiplication.cs.meta
index e37f87e..6d3d06e 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/Multiplication.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 6156d0f899a0b484383f5a552a76e328
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/NotEqual.cs b/Main/Common/Jace/Operations/NotEqual.cs
new file mode 100644
index 0000000..905bbe4
--- /dev/null
+++ b/Main/Common/Jace/Operations/NotEqual.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class NotEqual : Operation
+ {
+ public NotEqual(DataType dataType, Operation argument1, Operation argument2)
+ : base(dataType, argument1.DependsOnVariables || argument2.DependsOnVariables, argument1.IsIdempotent && argument2.IsIdempotent)
+ {
+ this.Argument1 = argument1;
+ this.Argument2 = argument2;
+ }
+
+ public Operation Argument1 { get; internal set; }
+ public Operation Argument2 { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/NotEqual.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/NotEqual.cs.meta
index e37f87e..529d9e7 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/NotEqual.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: b52548570632a8a449c662af67df863b
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/Operation.cs b/Main/Common/Jace/Operations/Operation.cs
new file mode 100644
index 0000000..7bfc7b0
--- /dev/null
+++ b/Main/Common/Jace/Operations/Operation.cs
@@ -0,0 +1,23 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public abstract class Operation
+ {
+ public Operation(DataType dataType, bool dependsOnVariables, bool isIdempotent)
+ {
+ this.DataType = dataType;
+ this.DependsOnVariables = dependsOnVariables;
+ this.IsIdempotent = isIdempotent;
+ }
+
+ public DataType DataType { get; private set; }
+
+ public bool DependsOnVariables { get; internal set; }
+
+ public bool IsIdempotent { get; private set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/Operation.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/Operation.cs.meta
index e37f87e..87a8576 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/Operation.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: f31df8e25e70f36488d2dc2f14ba66d7
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/Or.cs b/Main/Common/Jace/Operations/Or.cs
new file mode 100644
index 0000000..f6095a2
--- /dev/null
+++ b/Main/Common/Jace/Operations/Or.cs
@@ -0,0 +1,19 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class Or : Operation
+ {
+ public Or(DataType dataType, Operation argument1, Operation argument2)
+ : base(dataType, argument1.DependsOnVariables || argument2.DependsOnVariables, argument1.IsIdempotent && argument2.IsIdempotent)
+ {
+ this.Argument1 = argument1;
+ this.Argument2 = argument2;
+ }
+
+ public Operation Argument1 { get; internal set; }
+ public Operation Argument2 { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/Or.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/Or.cs.meta
index e37f87e..42c3277 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/Or.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: c39d4b13c7751e34587665bc39443e2a
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/Subtraction.cs b/Main/Common/Jace/Operations/Subtraction.cs
new file mode 100644
index 0000000..933433f
--- /dev/null
+++ b/Main/Common/Jace/Operations/Subtraction.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class Subtraction : Operation
+ {
+ public Subtraction(DataType dataType, Operation argument1, Operation argument2)
+ : base(dataType, argument1.DependsOnVariables || argument2.DependsOnVariables, argument1.IsIdempotent && argument2.IsIdempotent)
+ {
+ this.Argument1 = argument1;
+ this.Argument2 = argument2;
+ }
+
+ public Operation Argument1 { get; internal set; }
+ public Operation Argument2 { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/Subtraction.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/Subtraction.cs.meta
index e37f87e..1afd0d4 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/Subtraction.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: ddba1b68f54ac7841ac6b91dfb55a185
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/UnaryMinus.cs b/Main/Common/Jace/Operations/UnaryMinus.cs
new file mode 100644
index 0000000..c7633d5
--- /dev/null
+++ b/Main/Common/Jace/Operations/UnaryMinus.cs
@@ -0,0 +1,18 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ public class UnaryMinus : Operation
+ {
+ public UnaryMinus(DataType dataType, Operation argument)
+ : base(dataType, argument.DependsOnVariables, argument.IsIdempotent)
+ {
+ this.Argument = argument;
+ }
+
+ public Operation Argument { get; internal set; }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/UnaryMinus.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/UnaryMinus.cs.meta
index e37f87e..74d4e63 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/UnaryMinus.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 350a4f213d50975468899e32708859b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Operations/Variable.cs b/Main/Common/Jace/Operations/Variable.cs
new file mode 100644
index 0000000..618be27
--- /dev/null
+++ b/Main/Common/Jace/Operations/Variable.cs
@@ -0,0 +1,37 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Operations
+{
+ /// <summary>
+ /// Represents a variable in a mathematical formula.
+ /// </summary>
+ public class Variable : Operation
+ {
+ public Variable(string name)
+ : base(DataType.FloatingPoint, true, false)
+ {
+ this.Name = name;
+ }
+
+ public string Name { get; private set; }
+
+ public override bool Equals(object obj)
+ {
+ Variable other = obj as Variable;
+ if (other != null)
+ {
+ return this.Name.Equals(other.Name);
+ }
+ else
+ return false;
+ }
+
+ public override int GetHashCode()
+ {
+ return this.Name.GetHashCode();
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Operations/Variable.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Operations/Variable.cs.meta
index e37f87e..346c06d 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Operations/Variable.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 34fb9551f3d90cf418e9557742735a18
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Optimizer.cs b/Main/Common/Jace/Optimizer.cs
new file mode 100644
index 0000000..16fe53f
--- /dev/null
+++ b/Main/Common/Jace/Optimizer.cs
@@ -0,0 +1,76 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Jace.Operations;
+using Jace.Execution;
+
+namespace Jace
+{
+ public class Optimizer
+ {
+ private readonly IExecutor executor;
+
+ public Optimizer(IExecutor executor)
+ {
+ this.executor = executor;
+ }
+
+ public Operation Optimize(Operation operation, IFunctionRegistry functionRegistry, IConstantRegistry constantRegistry)
+ {
+ if (!operation.DependsOnVariables && operation.IsIdempotent && operation.GetType() != typeof(IntegerConstant)
+ && operation.GetType() != typeof(FloatingPointConstant))
+ {
+ double result = executor.Execute(operation, functionRegistry, constantRegistry);
+ return new FloatingPointConstant(result);
+ }
+ else
+ {
+ if (operation.GetType() == typeof(Addition))
+ {
+ Addition addition = (Addition)operation;
+ addition.Argument1 = Optimize(addition.Argument1, functionRegistry, constantRegistry);
+ addition.Argument2 = Optimize(addition.Argument2, functionRegistry, constantRegistry);
+ }
+ else if (operation.GetType() == typeof(Subtraction))
+ {
+ Subtraction substraction = (Subtraction)operation;
+ substraction.Argument1 = Optimize(substraction.Argument1, functionRegistry, constantRegistry);
+ substraction.Argument2 = Optimize(substraction.Argument2, functionRegistry, constantRegistry);
+ }
+ else if (operation.GetType() == typeof(Multiplication))
+ {
+ Multiplication multiplication = (Multiplication)operation;
+ multiplication.Argument1 = Optimize(multiplication.Argument1, functionRegistry, constantRegistry);
+ multiplication.Argument2 = Optimize(multiplication.Argument2, functionRegistry, constantRegistry);
+
+ if ((multiplication.Argument1.GetType() == typeof(FloatingPointConstant) && ((FloatingPointConstant)multiplication.Argument1).Value == 0.0)
+ || (multiplication.Argument2.GetType() == typeof(FloatingPointConstant) && ((FloatingPointConstant)multiplication.Argument2).Value == 0.0))
+ {
+ return new FloatingPointConstant(0.0);
+ }
+ }
+ else if (operation.GetType() == typeof(Division))
+ {
+ Division division = (Division)operation;
+ division.Dividend = Optimize(division.Dividend, functionRegistry, constantRegistry);
+ division.Divisor = Optimize(division.Divisor, functionRegistry, constantRegistry);
+ }
+ else if (operation.GetType() == typeof(Exponentiation))
+ {
+ Exponentiation division = (Exponentiation)operation;
+ division.Base = Optimize(division.Base, functionRegistry, constantRegistry);
+ division.Exponent = Optimize(division.Exponent, functionRegistry, constantRegistry);
+ }
+ else if(operation.GetType() == typeof(Function))
+ {
+ Function function = (Function)operation;
+ IList<Operation> arguments = function.Arguments.Select(a => Optimize(a, functionRegistry, constantRegistry)).ToList();
+ function.Arguments = arguments;
+ }
+
+ return operation;
+ }
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Optimizer.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Optimizer.cs.meta
index e37f87e..4508183 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Optimizer.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 3d95e6f9d0000c54c9abd40e1f81ab4a
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/ParseException.cs b/Main/Common/Jace/ParseException.cs
new file mode 100644
index 0000000..1f3ea3f
--- /dev/null
+++ b/Main/Common/Jace/ParseException.cs
@@ -0,0 +1,19 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace
+{
+ /// <summary>
+ /// The exception that is thrown when there is a syntax error in the formula provided
+ /// to the calculation engine.
+ /// </summary>
+ public class ParseException : Exception
+ {
+ public ParseException(string message)
+ : base(message)
+ {
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/ParseException.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/ParseException.cs.meta
index e37f87e..7574695 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/ParseException.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: df2bb315758f36a429552a2b28b667e2
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Core/GameEngine/Common.meta b/Main/Common/Jace/Tokenizer.meta
similarity index 76%
copy from Main/Core/GameEngine/Common.meta
copy to Main/Common/Jace/Tokenizer.meta
index 29b34bc..dae8336 100644
--- a/Main/Core/GameEngine/Common.meta
+++ b/Main/Common/Jace/Tokenizer.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 6b68b2e87cfa2fc48aff8e7f40a5c555
+guid: 2b67a41b280e4f143861b982f7dbc630
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Main/Common/Jace/Tokenizer/Token.cs b/Main/Common/Jace/Tokenizer/Token.cs
new file mode 100644
index 0000000..8b2a13f
--- /dev/null
+++ b/Main/Common/Jace/Tokenizer/Token.cs
@@ -0,0 +1,33 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Tokenizer
+{
+ /// <summary>
+ /// Represents an input token
+ /// </summary>
+ public struct Token
+ {
+ /// <summary>
+ /// The start position of the token in the input function text.
+ /// </summary>
+ public int StartPosition;
+
+ /// <summary>
+ /// The length of token in the input function text.
+ /// </summary>
+ public int Length;
+
+ /// <summary>
+ /// The type of the token.
+ /// </summary>
+ public TokenType TokenType;
+
+ /// <summary>
+ /// The value of the token.
+ /// </summary>
+ public object Value;
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Tokenizer/Token.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Tokenizer/Token.cs.meta
index e37f87e..9d7cb38 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Tokenizer/Token.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 9fa03dbd0043c2b41a256b11a7669fc9
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Tokenizer/TokenReader.cs b/Main/Common/Jace/Tokenizer/TokenReader.cs
new file mode 100644
index 0000000..18400d5
--- /dev/null
+++ b/Main/Common/Jace/Tokenizer/TokenReader.cs
@@ -0,0 +1,255 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Tokenizer
+{
+ /// <summary>
+ /// A token reader that converts the input string in a list of tokens.
+ /// </summary>
+ public class TokenReader
+ {
+ private readonly CultureInfo cultureInfo;
+ private readonly char decimalSeparator;
+ private readonly char argumentSeparator;
+
+ public TokenReader()
+ : this(CultureInfo.CurrentCulture)
+ {
+ }
+
+ public TokenReader(CultureInfo cultureInfo)
+ {
+ this.cultureInfo = cultureInfo;
+ this.decimalSeparator = cultureInfo.NumberFormat.NumberDecimalSeparator[0];
+ this.argumentSeparator = cultureInfo.TextInfo.ListSeparator[0];
+ }
+
+ /// <summary>
+ /// Read in the provided formula and convert it into a list of takens that can be processed by the
+ /// Abstract Syntax Tree Builder.
+ /// </summary>
+ /// <param name="formula">The formula that must be converted into a list of tokens.</param>
+ /// <returns>The list of tokens for the provided formula.</returns>
+ public List<Token> Read(string formula)
+ {
+ if (string.IsNullOrEmpty(formula))
+ throw new ArgumentNullException("formula");
+
+ List<Token> tokens = new List<Token>();
+
+ char[] characters = formula.ToCharArray();
+
+ bool isFormulaSubPart = true;
+ bool isScientific = false;
+
+ for(int i = 0; i < characters.Length; i++)
+ {
+ if (IsPartOfNumeric(characters[i], true, isFormulaSubPart))
+ {
+ StringBuilder buffer = new StringBuilder();
+ buffer.Append(characters[i]);
+ //string buffer = "" + characters[i];
+ int startPosition = i;
+
+
+ while (++i < characters.Length && IsPartOfNumeric(characters[i], false, isFormulaSubPart))
+ {
+ if (isScientific && IsScientificNotation(characters[i]))
+ throw new ParseException(string.Format("Invalid token \"{0}\" detected at position {1}.", characters[i], i));
+
+ if (IsScientificNotation(characters[i]))
+ {
+ isScientific = IsScientificNotation(characters[i]);
+
+ if (characters[i + 1] == '-')
+ {
+ buffer.Append(characters[i++]);
+ }
+ }
+
+ buffer.Append(characters[i]);
+ }
+
+ // Verify if we do not have an int
+ int intValue;
+ if (int.TryParse(buffer.ToString(), out intValue))
+ {
+ tokens.Add(new Token() { TokenType = TokenType.Integer, Value = intValue, StartPosition = startPosition, Length = i - startPosition });
+ isFormulaSubPart = false;
+ }
+ else
+ {
+ double doubleValue;
+ if (double.TryParse(buffer.ToString(), NumberStyles.Float | NumberStyles.AllowThousands,
+ cultureInfo, out doubleValue))
+ {
+ tokens.Add(new Token() { TokenType = TokenType.FloatingPoint, Value = doubleValue, StartPosition = startPosition, Length = i - startPosition });
+ isScientific = false;
+ isFormulaSubPart = false;
+ }
+ else if (buffer.ToString() == "-")
+ {
+ // Verify if we have a unary minus, we use the token '_' for a unary minus in the AST builder
+ tokens.Add(new Token() { TokenType = TokenType.Operation, Value = '_', StartPosition = startPosition, Length = 1 });
+ }
+ // Else we skip
+ }
+
+ if (i == characters.Length)
+ {
+ // Last character read
+ continue;
+ }
+ }
+
+ if (IsPartOfVariable(characters[i], true))
+ {
+ string buffer = "" + characters[i];
+ int startPosition = i;
+
+ while (++i < characters.Length && IsPartOfVariable(characters[i], false))
+ {
+ buffer += characters[i];
+ }
+
+ tokens.Add(new Token() { TokenType = TokenType.Text, Value = buffer, StartPosition = startPosition, Length = i -startPosition });
+ isFormulaSubPart = false;
+
+ if (i == characters.Length)
+ {
+ // Last character read
+ continue;
+ }
+ }
+ if (characters[i] == this.argumentSeparator)
+ {
+ tokens.Add(new Token() { TokenType = Tokenizer.TokenType.ArgumentSeparator, Value = characters[i], StartPosition = i, Length = 1 });
+ isFormulaSubPart = false;
+ }
+ else
+ {
+ switch (characters[i])
+ {
+ case ' ':
+ continue;
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '^':
+ case '%':
+ case '鈮�':
+ case '鈮�':
+ case '鈮�':
+ if (IsUnaryMinus(characters[i], tokens))
+ {
+ // We use the token '_' for a unary minus in the AST builder
+ tokens.Add(new Token() { TokenType = TokenType.Operation, Value = '_', StartPosition = i, Length = 1 });
+ }
+ else
+ {
+ tokens.Add(new Token() { TokenType = TokenType.Operation, Value = characters[i], StartPosition = i, Length = 1 });
+ }
+ isFormulaSubPart = true;
+ break;
+ case '(':
+ tokens.Add(new Token() { TokenType = TokenType.LeftBracket, Value = characters[i], StartPosition = i, Length = 1 });
+ isFormulaSubPart = true;
+ break;
+ case ')':
+ tokens.Add(new Token() { TokenType = TokenType.RightBracket, Value = characters[i], StartPosition = i, Length = 1 });
+ isFormulaSubPart = false;
+ break;
+ case '<':
+ if (i + 1 < characters.Length && characters[i + 1] == '=')
+ tokens.Add(new Token() { TokenType = TokenType.Operation, Value = '鈮�', StartPosition = i++, Length = 2 });
+ else
+ tokens.Add(new Token() { TokenType = TokenType.Operation, Value = '<', StartPosition = i, Length = 1 });
+ isFormulaSubPart = false;
+ break;
+ case '>':
+ if (i + 1 < characters.Length && characters[i + 1] == '=')
+ tokens.Add(new Token() { TokenType = TokenType.Operation, Value = '鈮�', StartPosition = i++, Length = 2 });
+ else
+ tokens.Add(new Token() { TokenType = TokenType.Operation, Value = '>', StartPosition = i, Length = 1 });
+ isFormulaSubPart = false;
+ break;
+ case '!':
+ if (i + 1 < characters.Length && characters[i + 1] == '=')
+ {
+ tokens.Add(new Token() { TokenType = TokenType.Operation, Value = '鈮�', StartPosition = i++, Length = 2 });
+ isFormulaSubPart = false;
+ }
+ else
+ throw new ParseException(string.Format("Invalid token \"{0}\" detected at position {1}.", characters[i], i));
+ break;
+ case '&':
+ if (i + 1 < characters.Length && characters[i + 1] == '&')
+ {
+ tokens.Add(new Token() { TokenType = TokenType.Operation, Value = '&', StartPosition = i++, Length = 2 });
+ isFormulaSubPart = false;
+ }
+ else
+ throw new ParseException(string.Format("Invalid token \"{0}\" detected at position {1}.", characters[i], i));
+ break;
+ case '|':
+ if (i + 1 < characters.Length && characters[i + 1] == '|')
+ {
+ tokens.Add(new Token() { TokenType = TokenType.Operation, Value = '|', StartPosition = i++, Length = 2 });
+ isFormulaSubPart = false;
+ }
+ else
+ throw new ParseException(string.Format("Invalid token \"{0}\" detected at position {1}.", characters[i], i));
+ break;
+ case '=':
+ if (i + 1 < characters.Length && characters[i + 1] == '=')
+ {
+ tokens.Add(new Token() { TokenType = TokenType.Operation, Value = '=', StartPosition = i++, Length = 2 });
+ isFormulaSubPart = false;
+ }
+ else
+ throw new ParseException(string.Format("Invalid token \"{0}\" detected at position {1}.", characters[i], i));
+ break;
+ default:
+ throw new ParseException(string.Format("Invalid token \"{0}\" detected at position {1}.", characters[i], i));
+ }
+ }
+ }
+
+ return tokens;
+ }
+
+ private bool IsPartOfNumeric(char character, bool isFirstCharacter, bool isFormulaSubPart)
+ {
+ return character == decimalSeparator || (character >= '0' && character <= '9') || (isFormulaSubPart && isFirstCharacter && character == '-') || (!isFirstCharacter && character == 'e') || (!isFirstCharacter && character == 'E');
+ }
+
+ private bool IsPartOfVariable(char character, bool isFirstCharacter)
+ {
+ return (character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') || (!isFirstCharacter && character >= '0' && character <= '9') || (!isFirstCharacter && character == '_');
+ }
+
+ private bool IsUnaryMinus(char currentToken, List<Token> tokens)
+ {
+ if (currentToken == '-')
+ {
+ Token previousToken = tokens[tokens.Count - 1];
+
+ return !(previousToken.TokenType == TokenType.FloatingPoint ||
+ previousToken.TokenType == TokenType.Integer ||
+ previousToken.TokenType == TokenType.Text ||
+ previousToken.TokenType == TokenType.RightBracket);
+ }
+ else
+ return false;
+ }
+
+ private bool IsScientificNotation(char currentToken)
+ {
+ return currentToken == 'e' || currentToken == 'E';
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Tokenizer/TokenReader.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Tokenizer/TokenReader.cs.meta
index e37f87e..8237aed 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Tokenizer/TokenReader.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: e7f38551c1077ee4896e7b1d5aabd1a2
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Tokenizer/TokenType.cs b/Main/Common/Jace/Tokenizer/TokenType.cs
new file mode 100644
index 0000000..f77c3df
--- /dev/null
+++ b/Main/Common/Jace/Tokenizer/TokenType.cs
@@ -0,0 +1,18 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Tokenizer
+{
+ public enum TokenType
+ {
+ Integer,
+ FloatingPoint,
+ Text,
+ Operation,
+ LeftBracket,
+ RightBracket,
+ ArgumentSeparator
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Tokenizer/TokenType.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Tokenizer/TokenType.cs.meta
index e37f87e..2cc8356 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Tokenizer/TokenType.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: ca43eadac5024d040a3f89d8c15e0967
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Core/GameEngine/Common.meta b/Main/Common/Jace/Util.meta
similarity index 76%
copy from Main/Core/GameEngine/Common.meta
copy to Main/Common/Jace/Util.meta
index 29b34bc..6e283a2 100644
--- a/Main/Core/GameEngine/Common.meta
+++ b/Main/Common/Jace/Util.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 6b68b2e87cfa2fc48aff8e7f40a5c555
+guid: 78f08781a2381ff409b92d3767b449bc
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Main/Common/Jace/Util/EngineUtil.cs b/Main/Common/Jace/Util/EngineUtil.cs
new file mode 100644
index 0000000..612b0c2
--- /dev/null
+++ b/Main/Common/Jace/Util/EngineUtil.cs
@@ -0,0 +1,46 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Util
+{
+ /// <summary>
+ /// Utility methods of Jace.NET that can be used throughout the engine.
+ /// </summary>
+ internal static class EngineUtil
+ {
+ static internal IDictionary<string, double> ConvertVariableNamesToLowerCase(IDictionary<string, double> variables)
+ {
+ Dictionary<string, double> temp = new Dictionary<string, double>();
+ foreach (KeyValuePair<string, double> keyValuePair in variables)
+ {
+ temp.Add(keyValuePair.Key.ToLowerFast(), keyValuePair.Value);
+ }
+
+ return temp;
+ }
+
+ // This is a fast ToLower for strings that are in ASCII
+ static internal string ToLowerFast(this string text)
+ {
+ StringBuilder buffer = new StringBuilder(text.Length);
+
+ for(int i = 0; i < text.Length; i++)
+ {
+ char c = text[i];
+
+ if (c >= 'A' && c <= 'Z')
+ {
+ buffer.Append((char)(c + 32));
+ }
+ else
+ {
+ buffer.Append(c);
+ }
+ }
+
+ return buffer.ToString();
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Util/EngineUtil.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Util/EngineUtil.cs.meta
index e37f87e..be229e1 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Util/EngineUtil.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 3725a3ccea7f46f4bb6980cdd7823745
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Util/FuncAdapter.cs b/Main/Common/Jace/Util/FuncAdapter.cs
new file mode 100644
index 0000000..d5add57
--- /dev/null
+++ b/Main/Common/Jace/Util/FuncAdapter.cs
@@ -0,0 +1,126 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Text;
+using Jace.Operations;
+
+namespace Jace.Util
+{
+ /// <summary>
+ /// An adapter for creating a func wrapper around a func accepting a dictionary. The wrapper
+ /// can create a func that has an argument for every expected key in the dictionary.
+ /// </summary>
+ public class FuncAdapter
+ {
+ /// <summary>
+ /// Wrap the parsed the function into a delegate of the specified type. The delegate must accept
+ /// the parameters defined in the parameters collection. The order of parameters is respected as defined
+ /// in parameters collection.
+ /// <br/>
+ /// The function must accept a dictionary of strings and doubles as input. The values passed to the
+ /// wrapping function will be passed to the function using the dictionary. The keys in the dictionary
+ /// are the names of the parameters of the wrapping function.
+ /// </summary>
+ /// <param name="parameters">The required parameters of the wrapping function delegate.</param>
+ /// <param name="function">The function that must be wrapped.</param>
+ /// <returns>A delegate instance of the required type.</returns>
+ public Delegate Wrap(IEnumerable<Jace.Execution.ParameterInfo> parameters,
+ Func<IDictionary<string, double>, double> function)
+ {
+ Jace.Execution.ParameterInfo[] parameterArray = parameters.ToArray();
+
+ return GenerateDelegate(parameterArray, function);
+ }
+
+ // Uncomment for debugging purposes
+ //public void CreateDynamicModuleBuilder()
+ //{
+ // AssemblyName assemblyName = new AssemblyName("JaceDynamicAssembly");
+ // AppDomain domain = AppDomain.CurrentDomain;
+ // AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName,
+ // AssemblyBuilderAccess.RunAndSave);
+ // ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, "test.dll");
+
+ // TypeBuilder typeBuilder = moduleBuilder.DefineType("MyTestClass");
+
+ // MethodBuilder method = typeBuilder.DefineMethod("MyTestMethod", MethodAttributes.Static, typeof(double),
+ // new Type[] { typeof(FuncAdapterArguments), typeof(int), typeof(double) });
+
+ // ILGenerator generator = method.GetILGenerator();
+ // GenerateMethodBody(generator, new List<Calculator.Execution.ParameterInfo>() {
+ // new Calculator.Execution.ParameterInfo() { Name = "test1", DataType = DataType.Integer },
+ // new Calculator.Execution.ParameterInfo() { Name = "test2", DataType = DataType.FloatingPoint }},
+ // (a) => 0.0);
+
+ // typeBuilder.CreateType();
+
+ // assemblyBuilder.Save(@"test.dll");
+ //}
+
+ private Delegate GenerateDelegate(Jace.Execution.ParameterInfo[] parameterArray,
+ Func<Dictionary<string, double>, double> function)
+ {
+ Type delegateType = GetDelegateType(parameterArray);
+ Type dictionaryType = typeof(Dictionary<string, double>);
+
+ ParameterExpression dictionaryExpression =
+ Expression.Variable(typeof(Dictionary<string, double>), "dictionary");
+ BinaryExpression dictionaryAssignExpression =
+ Expression.Assign(dictionaryExpression, Expression.New(dictionaryType));
+
+ ParameterExpression[] parameterExpressions = new ParameterExpression[parameterArray.Length];
+
+ List<Expression> methodBody = new List<Expression>();
+ methodBody.Add(dictionaryAssignExpression);
+
+ for (int i = 0; i < parameterArray.Length; i++)
+ {
+ // Create parameter expression for each func parameter
+ Type parameterType = parameterArray[i].DataType == DataType.FloatingPoint ? typeof(double) : typeof(int);
+ parameterExpressions[i] = Expression.Parameter(parameterType, parameterArray[i].Name);
+
+ methodBody.Add(Expression.Call(dictionaryExpression,
+ dictionaryType.GetRuntimeMethod("Add", new Type[] { typeof(string), typeof(double) }),
+ Expression.Constant(parameterArray[i].Name),
+ Expression.Convert(parameterExpressions[i], typeof(double)))
+ );
+ }
+
+ InvocationExpression invokeExpression = Expression.Invoke(Expression.Constant(function), dictionaryExpression);
+ methodBody.Add(invokeExpression);
+
+ LambdaExpression lambdaExpression = Expression.Lambda(delegateType,
+ Expression.Block(new[] { dictionaryExpression }, methodBody),
+ parameterExpressions);
+
+ return lambdaExpression.Compile();
+ }
+
+ private Type GetDelegateType(Jace.Execution.ParameterInfo[] parameters)
+ {
+ string funcTypeName = string.Format("System.Func`{0}", parameters.Length + 1);
+ Type funcType = Type.GetType(funcTypeName);
+
+ Type[] typeArguments = new Type[parameters.Length + 1];
+ for (int i = 0; i < parameters.Length; i++)
+ typeArguments[i] = (parameters[i].DataType == DataType.FloatingPoint) ? typeof(double) : typeof(int);
+ typeArguments[typeArguments.Length - 1] = typeof(double);
+
+ return funcType.MakeGenericType(typeArguments);
+ }
+
+ private class FuncAdapterArguments
+ {
+ private readonly Func<Dictionary<string, double>, double> function;
+
+ public FuncAdapterArguments(Func<Dictionary<string, double>, double> function)
+ {
+ this.function = function;
+ }
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Util/FuncAdapter.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Util/FuncAdapter.cs.meta
index e37f87e..8919198 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Util/FuncAdapter.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 878d5799cfe90cb4dbf7aebc38c3e9ae
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Util/MathExtended.cs b/Main/Common/Jace/Util/MathExtended.cs
new file mode 100644
index 0000000..189295b
--- /dev/null
+++ b/Main/Common/Jace/Util/MathExtended.cs
@@ -0,0 +1,81 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+
+namespace Jace.Util
+{
+ static class MathExtended
+ {
+ /// <summary>
+ /// Partitions the given list around a pivot element such that all elements on left of pivot are <= pivot
+ /// and the ones at thr right are > pivot. This method can be used for sorting, N-order statistics such as
+ /// as median finding algorithms.
+ /// Pivot is selected ranodmly if random number generator is supplied else its selected as last element in the list.
+ /// Reference: Introduction to Algorithms 3rd Edition, Corman et al, pp 171
+ /// </summary>
+ private static int Partition<T>(this IList<T> list, int start, int end, Random rnd = null) where T : IComparable<T>
+ {
+ if (rnd != null)
+ list.Swap(end, rnd.Next(start, end + 1));
+
+ var pivot = list[end];
+ var lastLow = start - 1;
+ for (var i = start; i < end; i++)
+ {
+ if (list[i].CompareTo(pivot) <= 0)
+ list.Swap(i, ++lastLow);
+ }
+ list.Swap(end, ++lastLow);
+ return lastLow;
+ }
+
+ /// <summary>
+ /// Returns Nth smallest element from the list. Here n starts from 0 so that n=0 returns minimum, n=1 returns 2nd smallest element etc.
+ /// Note: specified list would be mutated in the process.
+ /// Reference: Introduction to Algorithms 3rd Edition, Corman et al, pp 216
+ /// </summary>
+ public static T NthOrderStatistic<T>(this IList<T> list, int n, Random rnd = null) where T : IComparable<T>
+ {
+ return NthOrderStatistic(list, n, 0, list.Count - 1, rnd);
+ }
+ private static T NthOrderStatistic<T>(this IList<T> list, int n, int start, int end, Random rnd) where T : IComparable<T>
+ {
+ while (true)
+ {
+ var pivotIndex = list.Partition(start, end, rnd);
+ if (pivotIndex == n)
+ return list[pivotIndex];
+
+ if (n < pivotIndex)
+ end = pivotIndex - 1;
+ else
+ start = pivotIndex + 1;
+ }
+ }
+
+ public static void Swap<T>(this IList<T> list, int i, int j)
+ {
+ if (i == j) //This check is not required but Partition function may make many calls so its for perf reason
+ return;
+ var temp = list[i];
+ list[i] = list[j];
+ list[j] = temp;
+ }
+
+ /// <summary>
+ /// Note: specified list would be mutated in the process.
+ /// </summary>
+ public static T Median<T>(this IList<T> list) where T : IComparable<T>
+ {
+ return list.NthOrderStatistic((list.Count - 1) / 2);
+ }
+
+ public static double Median<T>(this IEnumerable<T> sequence, Func<T, double> getValue)
+ {
+ var list = sequence.Select(getValue).ToList();
+ var mid = (list.Count - 1) / 2;
+ return list.NthOrderStatistic(mid);
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Util/MathExtended.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Util/MathExtended.cs.meta
index e37f87e..f00b53a 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Util/MathExtended.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 9fd567b7004de6e41ae2720dd0b3c1ce
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Util/MathUtil.cs b/Main/Common/Jace/Util/MathUtil.cs
new file mode 100644
index 0000000..c64844a
--- /dev/null
+++ b/Main/Common/Jace/Util/MathUtil.cs
@@ -0,0 +1,30 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace.Util
+{
+ public static class MathUtil
+ {
+ public static double Cot(double a)
+ {
+ return 1 / Math.Tan(a);
+ }
+
+ public static double Acot(double d)
+ {
+ return Math.Atan(1 / d);
+ }
+
+ public static double Csc(double a)
+ {
+ return 1 / Math.Sin(a);
+ }
+
+ public static double Sec(double d)
+ {
+ return 1 / Math.Cos(d);
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Util/MathUtil.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Util/MathUtil.cs.meta
index e37f87e..e790998 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Util/MathUtil.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: b51d1dc4b0eab6e4c9cfb6bdec1d86ea
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Util/MemoryCache.cs b/Main/Common/Jace/Util/MemoryCache.cs
new file mode 100644
index 0000000..c2d728a
--- /dev/null
+++ b/Main/Common/Jace/Util/MemoryCache.cs
@@ -0,0 +1,165 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Collections.Concurrent;
+using System.Threading;
+
+namespace Jace.Util
+{
+ /// <summary>
+ /// An in-memory based cache to store objects. The implementation is thread safe and supports
+ /// the multiple platforms supported by Jace (.NET, WinRT, WP7 and WP8).
+ /// </summary>
+ /// <typeparam name="TKey">The type of the keys.</typeparam>
+ /// <typeparam name="TValue">The type of the values.</typeparam>
+ public class MemoryCache<TKey, TValue>
+ {
+ private readonly int maximumSize;
+ private readonly int reductionSize;
+
+ private long counter; // We cannot use DateTime.Now, because the precission is not high enough.
+
+ private readonly ConcurrentDictionary<TKey, CacheItem> dictionary;
+
+ /// <summary>
+ /// Create a new instance of the <see cref="MemoryCache"/>.
+ /// </summary>
+ /// <param name="maximumSize">The maximum allowed number of items in the cache.</param>
+ /// <param name="reductionSize">The number of items to be deleted per cleanup of the cache.</param>
+ public MemoryCache(int maximumSize, int reductionSize)
+ {
+ if (maximumSize < 1)
+ throw new ArgumentOutOfRangeException("maximumSize",
+ "The maximum allowed number of items in the cache must be at least one.");
+
+ if (reductionSize < 1)
+ throw new ArgumentOutOfRangeException("reductionSize",
+ "The cache reduction size must be at least one.");
+
+ this.maximumSize = maximumSize;
+ this.reductionSize = reductionSize;
+
+ this.dictionary = new ConcurrentDictionary<TKey, CacheItem>();
+ }
+
+ /// <summary>
+ /// Get the value in the cache for the given key.
+ /// </summary>
+ /// <param name="key">The key to lookup in the cache.</param>
+ /// <returns>The value for the given key.</returns>
+ public TValue this[TKey key]
+ {
+ get
+ {
+ CacheItem cacheItem = dictionary[key];
+ cacheItem.Accessed();
+ return cacheItem.Value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of items in the cache.
+ /// </summary>
+ public int Count
+ {
+ get
+ {
+ return dictionary.Count;
+ }
+ }
+
+ /// <summary>
+ /// Returns true if an item with the given key is present in the cache.
+ /// </summary>
+ /// <param name="key">The key to lookup in the cache.</param>
+ /// <returns>True if an item is present in the cache for the given key.</returns>
+ public bool ContainsKey(TKey key)
+ {
+ return dictionary.ContainsKey(key);
+ }
+
+ public bool TryGetValue (TKey key, out TValue result)
+ {
+ if (dictionary.TryGetValue(key, out var cachedItem))
+ {
+ cachedItem.Accessed();
+ result = cachedItem.Value;
+ return true;
+ }
+ else
+ {
+ result = default(TValue);
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// If for a given key an item is present in the cache, this method will return
+ /// the value for the given key. If no item is present in the cache for the given
+ /// key, the valueFactory is executed to produce the value. This value is stored in
+ /// the cache and returned to the caller.
+ /// </summary>
+ /// <param name="key">The key to lookup in the cache.</param>
+ /// <param name="valueFactory">The factory to produce the value matching with the key.</param>
+ /// <returns>The value for the given key.</returns>
+ public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
+ {
+ if (valueFactory == null)
+ throw new ArgumentNullException("valueFactory");
+
+ CacheItem cacheItem = dictionary.GetOrAdd(key, k =>
+ {
+ EnsureCacheStorageAvailable();
+
+ TValue value = valueFactory(k);
+ return new CacheItem(this, valueFactory(k));
+ });
+ return cacheItem.Value;
+ }
+
+ /// <summary>
+ /// Ensure that the cache has room for an additional item.
+ /// If there is not enough room anymore, force a removal of oldest
+ /// accessed items in the cache.
+ /// </summary>
+ private void EnsureCacheStorageAvailable()
+ {
+ if (dictionary.Count >= maximumSize) // >= because we want to add an item after this method
+ {
+ IList<TKey> keysToDelete = (from p in dictionary.ToArray()
+ where p.Key != null && p.Value != null
+ orderby p.Value.LastAccessed ascending
+ select p.Key).Take(reductionSize).ToList();
+
+ foreach (TKey key in keysToDelete)
+ {
+ CacheItem cacheItem;
+ dictionary.TryRemove(key, out cacheItem);
+ }
+ }
+ }
+
+ private class CacheItem
+ {
+ private MemoryCache<TKey, TValue> cache;
+
+ public CacheItem(MemoryCache<TKey, TValue> cache, TValue value)
+ {
+ this.cache = cache;
+ this.Value = value;
+
+ Accessed();
+ }
+
+ public TValue Value { get; private set; }
+
+ public long LastAccessed { get; private set; }
+
+ public void Accessed()
+ {
+ this.LastAccessed = Interlocked.Increment(ref cache.counter);
+ }
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Util/MemoryCache.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Util/MemoryCache.cs.meta
index e37f87e..aa87558 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Util/MemoryCache.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: da84d8440a462ad44b25f3e1ae8d0c36
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/Util/TypeExtensions.cs b/Main/Common/Jace/Util/TypeExtensions.cs
new file mode 100644
index 0000000..952812f
--- /dev/null
+++ b/Main/Common/Jace/Util/TypeExtensions.cs
@@ -0,0 +1,43 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+namespace Jace.Util
+{
+ public static class TypeExtensions
+ {
+ /// <summary>
+ /// Get constructor for a given type matching with the parameter types provided.
+ /// </summary>
+ /// <param name="type">The type for witch a matching constructor must be found.</param>
+ /// <param name="parameters">The types of the parameters of the constructor.</param>
+ /// <returns>The matching constructor.</returns>
+ public static ConstructorInfo GetConstructor(this Type type, Type[] parameters)
+ {
+ IEnumerable<ConstructorInfo> constructors =
+ type.GetTypeInfo().DeclaredConstructors.Where(c => c.GetParameters().Length == parameters.Length);
+
+ foreach (ConstructorInfo constructor in constructors)
+ {
+ bool parametersMatch = true;
+
+ ParameterInfo[] constructorParameters = constructor.GetParameters();
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ if (parameters[i] != constructorParameters[i].ParameterType)
+ {
+ parametersMatch = false;
+ break;
+ }
+ }
+
+ if (parametersMatch)
+ return constructor;
+ }
+
+ throw new Exception("No constructor was found matching with the provided parameters.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/Util/TypeExtensions.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/Util/TypeExtensions.cs.meta
index e37f87e..59e7da8 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/Util/TypeExtensions.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: adedcd02cabd3f94d8be60ce8b3b4a1e
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Common/Jace/VariableNotDefinedException.cs b/Main/Common/Jace/VariableNotDefinedException.cs
new file mode 100644
index 0000000..7aab7d9
--- /dev/null
+++ b/Main/Common/Jace/VariableNotDefinedException.cs
@@ -0,0 +1,23 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jace
+{
+ /// <summary>
+ /// An exception thrown when a formula must be executed with a variable that is not defined.
+ /// </summary>
+ public class VariableNotDefinedException : Exception
+ {
+ public VariableNotDefinedException(string message)
+ : base(message)
+ {
+ }
+
+ public VariableNotDefinedException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Common/Jace/VariableNotDefinedException.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Common/Jace/VariableNotDefinedException.cs.meta
index e37f87e..f1e2fc7 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Common/Jace/VariableNotDefinedException.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: b54823a4c30c0db4992f01e0a5b4bcb6
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Component/UI/Effect/UIEffectPlayer.cs b/Main/Component/UI/Effect/UIEffectPlayer.cs
index c71396f..35a5bfe 100644
--- a/Main/Component/UI/Effect/UIEffectPlayer.cs
+++ b/Main/Component/UI/Effect/UIEffectPlayer.cs
@@ -47,6 +47,7 @@
if (!isInit)
{
InitComponent(showLog);
+ //effeid 涓�0涔熷垵濮嬪寲鎴愬姛锛岄伩鍏嶉噸澶嶅鐞嗭紝鍦ㄥ彉鏇磂ffectid鏃朵細閲嶆柊鍒濆鍖�
isInit = true;
}
else
@@ -56,7 +57,8 @@
{
this.gameObject.SetActive(true);
}
- if (effectConfig.isSpine != 0)
+ //闃茶寖effeid 涓�0
+ if (effectConfig != null && effectConfig.isSpine != 0)
{
PlayerTheSpineAnim();
}
diff --git a/Main/Config/ConfigManager.cs b/Main/Config/ConfigManager.cs
index 8d2b82d..efaf67e 100644
--- a/Main/Config/ConfigManager.cs
+++ b/Main/Config/ConfigManager.cs
@@ -43,6 +43,7 @@
typeof(DamageNumConfig),
typeof(DirtyWordConfig),
typeof(FaceConfig),
+ typeof(FightPowerRatioConfig),
typeof(HeroLineupHaloConfig),
typeof(HeroQualityLVConfig),
typeof(ItemConfig),
@@ -221,6 +222,8 @@
ClearConfigDictionary<DirtyWordConfig>();
// 娓呯┖ FaceConfig 瀛楀吀
ClearConfigDictionary<FaceConfig>();
+ // 娓呯┖ FightPowerRatioConfig 瀛楀吀
+ ClearConfigDictionary<FightPowerRatioConfig>();
// 娓呯┖ HeroLineupHaloConfig 瀛楀吀
ClearConfigDictionary<HeroLineupHaloConfig>();
// 娓呯┖ HeroQualityLVConfig 瀛楀吀
diff --git a/Main/Config/Configs/FightPowerRatioConfig.cs b/Main/Config/Configs/FightPowerRatioConfig.cs
new file mode 100644
index 0000000..4f87731
--- /dev/null
+++ b/Main/Config/Configs/FightPowerRatioConfig.cs
@@ -0,0 +1,107 @@
+锘�//--------------------------------------------------------
+// [Author]: YYL
+// [ Date ]: 2025骞�8鏈�18鏃�
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class FightPowerRatioConfig : ConfigBase<int, FightPowerRatioConfig>
+{
+ static FightPowerRatioConfig()
+ {
+ // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+ visit = true;
+ }
+
+ public int LV;
+ public float AtkRatio;
+ public float MaxHPRatio;
+ public float DefRatio;
+ public float StunRateRatio;
+ public float SuperHitRateRatio;
+ public float ComboRateRatio;
+ public float MissRateRatio;
+ public float ParryRateRatio;
+ public float SuckHPPerRatio;
+ public float StunRateDefRatio;
+ public float SuperHitRateDefRatio;
+ public float ComboRateDefRatio;
+ public float MissRateDefRatio;
+ public float ParryRateDefRatio;
+ public float SuckHPPerDefRatio;
+ public float NormalSkillPerRatio;
+ public float NormalSkillPerDefRatio;
+ public float AngerSkillPerRatio;
+ public float AngerSkillPerDefRatio;
+ public float SuperDamPerRatio;
+ public float SuperDamPerDefRatio;
+ public float ShieldPerRatio;
+ public float ShieldPerDefRatio;
+
+ public override int LoadKey(string _key)
+ {
+ int key = GetKey(_key);
+ return key;
+ }
+
+ public override void LoadConfig(string input)
+ {
+ try {
+ string[] tables = input.Split('\t');
+ int.TryParse(tables[0],out LV);
+
+ float.TryParse(tables[1],out AtkRatio);
+
+ float.TryParse(tables[2],out MaxHPRatio);
+
+ float.TryParse(tables[3],out DefRatio);
+
+ float.TryParse(tables[4],out StunRateRatio);
+
+ float.TryParse(tables[5],out SuperHitRateRatio);
+
+ float.TryParse(tables[6],out ComboRateRatio);
+
+ float.TryParse(tables[7],out MissRateRatio);
+
+ float.TryParse(tables[8],out ParryRateRatio);
+
+ float.TryParse(tables[9],out SuckHPPerRatio);
+
+ float.TryParse(tables[10],out StunRateDefRatio);
+
+ float.TryParse(tables[11],out SuperHitRateDefRatio);
+
+ float.TryParse(tables[12],out ComboRateDefRatio);
+
+ float.TryParse(tables[13],out MissRateDefRatio);
+
+ float.TryParse(tables[14],out ParryRateDefRatio);
+
+ float.TryParse(tables[15],out SuckHPPerDefRatio);
+
+ float.TryParse(tables[16],out NormalSkillPerRatio);
+
+ float.TryParse(tables[17],out NormalSkillPerDefRatio);
+
+ float.TryParse(tables[18],out AngerSkillPerRatio);
+
+ float.TryParse(tables[19],out AngerSkillPerDefRatio);
+
+ float.TryParse(tables[20],out SuperDamPerRatio);
+
+ float.TryParse(tables[21],out SuperDamPerDefRatio);
+
+ float.TryParse(tables[22],out ShieldPerRatio);
+
+ float.TryParse(tables[23],out ShieldPerDefRatio);
+ }
+ catch (Exception exception)
+ {
+ Debug.LogError(exception);
+ }
+ }
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Config/Configs/FightPowerRatioConfig.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Config/Configs/FightPowerRatioConfig.cs.meta
index e37f87e..f1becbd 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Config/Configs/FightPowerRatioConfig.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 600fc786340faaf44aed165f5642df6d
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/Config/Configs/HeroConfig.cs b/Main/Config/Configs/HeroConfig.cs
index 738f35d..4b8810f 100644
--- a/Main/Config/Configs/HeroConfig.cs
+++ b/Main/Config/Configs/HeroConfig.cs
@@ -1,6 +1,6 @@
锘�//--------------------------------------------------------
// [Author]: YYL
-// [ Date ]: Wednesday, August 6, 2025
+// [ Date ]: 2025骞�8鏈�17鏃�
//--------------------------------------------------------
using System.Collections.Generic;
@@ -28,7 +28,7 @@
public int AtkInheritPer;
public int DefInheritPer;
public int HPInheritPer;
- public string BatAttrDict;
+ public Dictionary<int, int> BatAttrDict;
public int[] FetterIDList;
public float UIScale;
public string Desc;
@@ -79,7 +79,7 @@
int.TryParse(tables[11],out HPInheritPer);
- BatAttrDict = tables[12];
+ BatAttrDict = ConfigParse.ParseIntDict(tables[12]);
if (tables[13].Contains("["))
{
diff --git a/Main/Config/Configs/PlayerLVConfig.cs b/Main/Config/Configs/PlayerLVConfig.cs
index b864aa6..da8a466 100644
--- a/Main/Config/Configs/PlayerLVConfig.cs
+++ b/Main/Config/Configs/PlayerLVConfig.cs
@@ -1,6 +1,6 @@
锘�//--------------------------------------------------------
// [Author]: YYL
-// [ Date ]: 2025骞�8鏈�5鏃�
+// [ Date ]: 2025骞�8鏈�16鏃�
//--------------------------------------------------------
using System.Collections.Generic;
@@ -18,6 +18,9 @@
public int LV;
public long EXP;
+ public int MaxHP;
+ public int Atk;
+ public int Def;
public override int LoadKey(string _key)
{
@@ -32,6 +35,12 @@
int.TryParse(tables[0],out LV);
long.TryParse(tables[1],out EXP);
+
+ int.TryParse(tables[2],out MaxHP);
+
+ int.TryParse(tables[3],out Atk);
+
+ int.TryParse(tables[4],out Def);
}
catch (Exception exception)
{
diff --git a/Main/Config/PartialConfigs/HeroConfig.cs b/Main/Config/PartialConfigs/HeroConfig.cs
deleted file mode 100644
index 6727d54..0000000
--- a/Main/Config/PartialConfigs/HeroConfig.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using System.Collections.Generic;
-using UnityEngine;
-using LitJson;
-
-public partial class HeroConfig : ConfigBase<int, HeroConfig>
-{
- public Dictionary<HeroAttrType, int> inheritPropertiesDict = new Dictionary<HeroAttrType, int>();
-
- protected override void OnConfigParseCompleted()
- {
- base.OnConfigParseCompleted();
-
- inheritPropertiesDict.Clear();
-
- inheritPropertiesDict.Add(HeroAttrType.attack, AtkInheritPer);
- inheritPropertiesDict.Add(HeroAttrType.defense, DefInheritPer);
- inheritPropertiesDict.Add(HeroAttrType.hp, HPInheritPer);
-
-
- // json鏍煎紡
- // {"灞炴�D":鍊�, ...}
- // 灞炴�D瀵瑰簲灞炴�ф潯鐩〃鐨処D
- // 鏈夊�肩殑閰嶅嵆鍙紝娌℃湁閰嶇疆鐨勫睘鎬ч粯璁�0
- JsonData jsonData = JsonMapper.ToObject(BatAttrDict);
-
- foreach (var attrId in jsonData.Keys)
- {
- if (int.TryParse(attrId.ToString(), out int attrTypeId))
- {
- HeroAttrType attrType = (HeroAttrType)attrTypeId;
- if (jsonData[attrId] != null && int.TryParse(jsonData[attrId].ToString(), out int value))
- {
- if (inheritPropertiesDict.ContainsKey(attrType))
- {
- Debug.LogError($"HeroTalentConfig: 灞炴�� {attrType} 宸茬粡瀛樺湪锛屾棤娉曢噸澶嶆坊鍔犮�傝妫�鏌ラ厤缃枃浠躲��");
- }
- else
- {
- inheritPropertiesDict.Add(attrType, value);
- }
- }
- }
- }
- }
-
- public int GetInheritPercent(HeroAttrType attrType)
- {
- if (inheritPropertiesDict.TryGetValue(attrType, out int perc))
- {
- return perc;
- }
-
- return 0;
- }
-}
\ No newline at end of file
diff --git a/Main/Config/PartialConfigs/HeroConfig.cs.meta b/Main/Config/PartialConfigs/HeroConfig.cs.meta
deleted file mode 100644
index c03e9a5..0000000
--- a/Main/Config/PartialConfigs/HeroConfig.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: dd269c7c73dcf3f4f87848b25f007405
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Main/Config/PartialConfigs/HeroTalentConfig.cs b/Main/Config/PartialConfigs/HeroTalentConfig.cs
index f568ac8..83e7bbd 100644
--- a/Main/Config/PartialConfigs/HeroTalentConfig.cs
+++ b/Main/Config/PartialConfigs/HeroTalentConfig.cs
@@ -3,10 +3,6 @@
public partial class HeroTalentConfig : ConfigBase<int, HeroTalentConfig>
{
- // public int Quality;
- // public int AttrID;
-
- // Quality, List<HeroTalentConfig>
public static Dictionary<int, List<HeroTalentConfig>> configDics = new Dictionary<int, List<HeroTalentConfig>>();
protected override void OnConfigParseCompleted()
diff --git a/Main/Config/PartialConfigs/PlayerPropertyConfig.cs b/Main/Config/PartialConfigs/PlayerPropertyConfig.cs
index 82ce7a6..f7014ae 100644
--- a/Main/Config/PartialConfigs/PlayerPropertyConfig.cs
+++ b/Main/Config/PartialConfigs/PlayerPropertyConfig.cs
@@ -5,6 +5,11 @@
public partial class PlayerPropertyConfig : ConfigBase<int, PlayerPropertyConfig>
{
+ public const int baseType = 1; //鍩虹灞炴��
+ public const int fightType = 2; //鎴樻枟灞炴��
+ public const int fightAntiType = 3; //鎴樻枟鎶楁��
+ public const int specialType = 4; //鐗规畩灞炴��
+
// 鎸夋樉绀虹被鍨嬪垎
private static Dictionary<int, List<int>> m_PlayerPropertyDict = new Dictionary<int, List<int>>();
public static Dictionary<int, List<int>> playerPropertyDict
@@ -17,42 +22,21 @@
}
}
- private static int[] m_inheritAttrs;//鏀婚槻琛� 缁ф壙鐨勭櫨鍒嗘瘮
- public static int[] inheritAttrs
- {
- get
- {
- if (m_inheritAttrs.IsNullOrEmpty())
- {
- if (playerPropertyDict.ContainsKey(5))
- {
- m_inheritAttrs = playerPropertyDict[5].ToArray();
- }
- }
- return m_inheritAttrs;
- }
- }
+ public static int[] inheritAttrs = new int[] { 13, 14, 15 };
- private static int[] m_basePerAttrs; //鏀婚槻琛� 鍔犳垚鐧惧垎姣�
- public static int[] basePerAttrs
- {
- get
- {
- if (m_basePerAttrs.IsNullOrEmpty())
- {
- if (playerPropertyDict.ContainsKey(6))
- {
- m_basePerAttrs = playerPropertyDict[6].ToArray();
- }
- }
- return m_basePerAttrs;
- }
- }
- public const int baseType = 1; //鍩虹灞炴��
- public const int fightType = 2; //鎴樻枟灞炴��
- public const int fightAntiType = 3; //鎴樻枟鎶楁��
- public const int specialType = 4; //鐗规畩灞炴��
+ //涓嶅悓鐨勫姛鑳借〃璋冪敤瀵瑰簲鑷繁鐨勫姛鑳藉惈涔夊拰浣跨敤鏂瑰紡锛屽闃靛鍏夌幆閰嶇疆灏辩敤鍦ㄥ搴旇绠楀眰
+ public static int[] basePerAttrs = new int[] { 16, 17, 18 };
+
+ public static int[] baseAttrs = new int[] { 6, 7, 8 };
+
+ public static Dictionary<int, int> baseAttr2perDict = new Dictionary<int, int>()
+ {
+ { 6,16 },
+ { 7,17 },
+ { 8,18 }
+ };
+
private static Dictionary<int, List<int>> RefreshShowDict()
{
if (m_PlayerPropertyDict.IsNullOrEmpty())
diff --git a/Main/Core/GameEngine/Common/Equation.cs b/Main/Core/GameEngine/Common/Equation.cs
deleted file mode 100644
index 9fd64c8..0000000
--- a/Main/Core/GameEngine/Common/Equation.cs
+++ /dev/null
@@ -1,455 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-using System.Text.RegularExpressions;
-using UnityEngine;
-
-
-/// <summary>
-/// 鍏紡璁$畻妯″潡锛屾敮鎸佸姩鎬佸彉閲忔浛鎹㈠拰澶氱杩愮畻绗﹁绠椼��
-/// </summary>
-public class Equation : Singleton<Equation>
-{
- /// <summary>
- /// 鏀寔鐨勮繍绠楃鍒楄〃銆�
- /// </summary>
- public static readonly List<char> operatorList = new List<char>() { '*', '-', '+', '/', '^', '!', '@', '%', ';', '#', '$', '~', '&' };
-
- /// <summary>
- /// 鐢ㄤ簬涓存椂瀛楃涓叉瀯寤虹殑鍏变韩瀹炰緥銆�
- /// </summary>
- public static StringBuilder textBuilder = new StringBuilder();
-
- /// <summary>
- /// 瀛樺偍鍙橀噺鍚嶅拰鍊肩殑閿�煎鍒楄〃銆�
- /// </summary>
- private List<KeyValuePair<string, string>> keyValueDic = new List<KeyValuePair<string, string>>();
-
- /// <summary>
- /// 鐢ㄤ簬鍖归厤鍙橀噺鍚嶇殑姝e垯琛ㄨ揪寮忋��
- /// </summary>
- public static readonly Regex replaecRegex = new Regex(@"[a-zA-Z]{2,50}");
-
- public T Eval<T>(string equation) where T : struct
- {
- keyValueDic.Sort(Compare);
- equation = GetEquation(equation);
- T val = default(T);
- try
- {
- EquationParse equationParse = new EquationParse(equation);
- val = (T)Convert.ChangeType(equationParse.result, typeof(T));
- equationParse = null;
- }
- catch (Exception e)
- {
- Debug.LogError(e.Message);
- }
- return val;
- }
-
- /// <summary>
- /// 鏇挎崲鍏紡涓殑鍙橀噺鍚嶄负瀵瑰簲鐨勫�笺��
- /// </summary>
- /// <param name="equation">鍘熷鍏紡瀛楃涓层��</param>
- /// <returns>鏇挎崲鍚庣殑鍏紡瀛楃涓层��</returns>
- private string GetEquation(string equation)
- {
- try
- {
- MatchCollection matchArray = replaecRegex.Matches(equation);
- textBuilder.Length = 0;
- int length = 0;
-
- if (matchArray != null)
- {
- foreach (Match match in matchArray)
- {
- // 娣诲姞闈炲彉閲忛儴鍒�
- textBuilder.Append(equation, length, match.Index - length);
- length = match.Index + match.Length;
-
- // 鏌ユ壘鍙橀噺瀵瑰簲鐨勫��
- var foundPair = keyValueDic.Find(x => x.Key.Equals(match.Value));
- string replacement = foundPair.Equals(default(KeyValuePair<string, string>)) ? "0" : foundPair.Value;
- textBuilder.Append(replacement ?? "0");
- }
- }
-
- // 娣诲姞鍓╀綑閮ㄥ垎
- textBuilder.Append(equation, length, equation.Length - length);
- }
- catch (Exception e)
- {
- Debug.LogError($"鍏紡鍙橀噺鏇挎崲澶辫触: {e.Message}");
- }
-
- return textBuilder.ToString();
- }
-
- public void AddKeyValue(string key, object val)
- {
- int index = keyValueDic.FindIndex((x) => {
- return x.Key == key;
- });
- if (index == -1)
- {
- KeyValuePair<string, string> keyValuePair = new KeyValuePair<string, string>(key, val.ToString());
- keyValueDic.Add(keyValuePair);
- }
- }
-
- public void Clear()
- {
- keyValueDic.Clear();
- }
-
- int Compare(KeyValuePair<string, string> x, KeyValuePair<string, string> y)
- {
- return -x.Key.Length.CompareTo(y.Key.Length);
- }
-
- public class EquationParse
- {
- public string equation { get; private set; }
- public string result { get; private set; }
- private StringBuilder equationBuilder = new StringBuilder();
- private List<EquationParse> subEquations = new List<EquationParse>();
- private List<OperatorType> operatorTypeList = new List<OperatorType>();
- private List<string> values = new List<string>();
- public EquationParse(string _equation)
- {
- this.equation = _equation;
- this.result = string.Empty;
- equationBuilder.Length = 0;
- if (CheckSplit())
- {
- return;
- }
- Subsection();
- GetResult();
- }
- private bool CheckSplit()
- {
- var _left = string.Empty;
- var _right = string.Empty;
- OperatorType _operatorType;
- if (Split(equation, out _left, out _right, out _operatorType))
- {
- var _leftResult = new EquationParse(_left);
- var _rightResult = new EquationParse(_right);
- result = GetResult(_leftResult.result, _rightResult.result, _operatorType).ToString();
- return true;
- }
- return false;
- }
- /// <summary>
- /// 瑙f瀽鍏紡涓殑瀛愯〃杈惧紡锛堟嫭鍙峰唴鐨勯儴鍒嗭級銆�
- /// </summary>
- private void Subsection()
- {
- try
- {
- int bracketCnt = 0;
- int startIndex = 0;
- int length = 0;
- int index = 0;
-
- for (int i = 0; i < equation.Length; i++)
- {
- if (equation[i] == '(')
- {
- i++;
- startIndex = i;
-
- // 鎻愬彇鎷彿鍐呯殑瀛愯〃杈惧紡
- while (i < equation.Length && (equation[i] != ')' || bracketCnt > 0))
- {
- if (equation[i] == '(') bracketCnt++;
- else if (equation[i] == ')') bracketCnt--;
- length++;
- i++;
- }
-
- // 澶勭悊瀛愯〃杈惧紡
- subEquations.Add(new EquationParse(equation.Substring(startIndex, length)));
- equationBuilder.Append($"={index}=");
- index++;
- length = 0;
- continue;
- }
-
- equationBuilder.Append(equation[i]);
- }
- }
- catch (Exception e)
- {
- Debug.LogError($"瀛愯〃杈惧紡瑙f瀽澶辫触: {e.Message}");
- }
- }
-
- private void AnalysisEquation()
- {
- try
- {
- textBuilder.Length = 0;
- for (int i = 0; i < subEquations.Count; i++)
- {
- equationBuilder.Replace(string.Format("={0}=", i), subEquations[i].result);
- subEquations[i] = null;
- }
- subEquations.Clear();
- var _result = equationBuilder.ToString();
- char _lastChar = default(char);
- for (int i = 0; i < _result.Length; i++)
- {
- if (i - 1 > 0 && _result[i - 1] == 'E')
- {//杩囨护瓒呭ぇ鏁板�煎悗鐨勭鍙�
- textBuilder.Append(_result[i]);
- continue;
- }
- int index = operatorList.IndexOf(_result[i]);
- if (index != -1 && _lastChar >= '0' && _lastChar <= '9')
- {
- values.Add(textBuilder.ToString());
- textBuilder.Length = 0;
- operatorTypeList.Add(GetOperatorType(_result[i]));
- }
- else
- {
- textBuilder.Append(_result[i]);
- }
- _lastChar = _result[i];
- }
- values.Add(textBuilder.ToString());
- }
- catch (Exception e)
- {
- Debug.Log(e.Message);
- }
- }
-
- public void GetResult()
- {
- AnalysisEquation();
- try
- {
- for (int i = 0; i < operatorTypeList.Count; i++)
- {
- if (IsPriorityOperator(operatorTypeList[i]))
- {
- double _result = 0;
- if (IsUnaryOperator(operatorTypeList[i]))
- {
- _result = GetResult(values[i], string.Empty, operatorTypeList[i]);
- }
- else
- {
- _result = GetResult(values[i], values[i + 1], operatorTypeList[i]);
- values.RemoveAt(i);
- }
- values.RemoveAt(i);
- values.Insert(i, _result.ToString());
- operatorTypeList.RemoveAt(i);
- i--;
- }
- }
- while (values.Count > 1 && operatorTypeList.Count > 0)
- {
- double _result = 0;
- if (IsUnaryOperator(operatorTypeList[0]))
- {
- _result = GetResult(values[0], string.Empty, operatorTypeList[0]);
- }
- else
- {
- _result = GetResult(values[0], values[1], operatorTypeList[0]);
- values.RemoveAt(0);
- }
- values.RemoveAt(0);
- values.Insert(0, _result.ToString());
- operatorTypeList.RemoveAt(0);
- }
- if (operatorTypeList.Count == 1 && IsUnaryOperator(operatorTypeList[0]))
- {
- result = GetResult(values[0], string.Empty, operatorTypeList[0]).ToString();
- }
- else
- {
- result = values[0];
- }
- }
- catch (Exception e)
- {
- Debug.Log(e.Message);
- }
- }
-
- /// <summary>
- /// 鏍规嵁杩愮畻绗︾被鍨嬭绠楃粨鏋溿��
- /// </summary>
- /// <param name="leftValue">宸︽搷浣滄暟銆�</param>
- /// <param name="rightValue">鍙虫搷浣滄暟銆�</param>
- /// <param name="operatorType">杩愮畻绗︾被鍨嬨��</param>
- /// <returns>璁$畻缁撴灉銆�</returns>
- public static double GetResult(string leftValue, string rightValue, OperatorType operatorType)
- {
- if (!double.TryParse(leftValue, out double _leftValue) || !double.TryParse(rightValue, out double _rightValue))
- {
- Debug.LogError($"鏃犳硶灏嗗瓧绗︿覆杞崲涓烘暟鍊�: {leftValue} 鎴� {rightValue}");
- return 0;
- }
-
- switch (operatorType)
- {
- case OperatorType.Plus: return _leftValue + _rightValue;
- case OperatorType.Subtract: return _leftValue - _rightValue;
- case OperatorType.Ride: return _leftValue * _rightValue;
- case OperatorType.Divide: return _rightValue == 0 ? _leftValue : _leftValue / _rightValue;
- case OperatorType.Pow: return Math.Pow(_leftValue, _rightValue);
- case OperatorType.Min: return Math.Min(_leftValue, _rightValue);
- case OperatorType.Max: return Math.Max(_leftValue, _rightValue);
- case OperatorType.Remain: return _leftValue % _rightValue;
- case OperatorType.Random: return UnityEngine.Random.Range((float)_leftValue, (float)_rightValue);
- case OperatorType.Floor: return Math.Floor(_leftValue);
- case OperatorType.Ceil: return Math.Ceiling((float)_leftValue);
- case OperatorType.RandomInt: return UnityEngine.Random.Range((int)_leftValue, (int)_rightValue);
- case OperatorType.Sqrt: return Math.Sqrt(_leftValue);
- default: return 0;
- }
- }
- public static OperatorType GetOperatorType(char _operator)
- {
- switch (_operator)
- {
- case '+':
- return OperatorType.Plus;
- case '-':
- return OperatorType.Subtract;
- case '*':
- return OperatorType.Ride;
- case '/':
- return OperatorType.Divide;
- case '^':
- return OperatorType.Pow;
- case '!':
- return OperatorType.Min;
- case '@':
- return OperatorType.Max;
- case '%':
- return OperatorType.Remain;
- case ';':
- return OperatorType.Random;
- case '#':
- return OperatorType.Floor;
- case '$':
- return OperatorType.Ceil;
- case '~':
- return OperatorType.RandomInt;
- case '&':
- return OperatorType.Sqrt;
- }
- return OperatorType.Plus;
- }
- public static bool IsPriorityOperator(OperatorType operatorType)
- {
- if (operatorType == OperatorType.Plus || operatorType == OperatorType.Subtract)
- {
- return false;
- }
- return true;
- }
- public static bool IsUnaryOperator(OperatorType operatorType)
- {
- if (operatorType == OperatorType.Floor || operatorType == OperatorType.Ceil
- || operatorType == OperatorType.Sqrt)
- {
- return true;
- }
- return false;
- }
-
- private static bool Split(string _source, out string _left, out string _right, out OperatorType _type)
- {
- _left = _right = string.Empty;
- _type = OperatorType.Plus;
- try
- {
- var _index = 0;
- for (int i = _source.Length - 1; i >= 0; i--)
- {
- if (_source[i] == ')')
- {
- _index++;
- continue;
- }
- else if (_source[i] == '(')
- {
- _index--;
- continue;
- }
- if (IsSplitOperator(_source[i], out _type) && _index == 0)
- {
- _left = _source.Substring(0, i);
- if (i + 1 < _source.Length)
- {
- _right = _source.Substring(i + 1);
- }
- return true;
- }
- }
- }
- catch (Exception e)
- {
- Debug.Log(e.Message);
- }
- return false;
- }
-
- public static bool IsSplitOperator(char _char, out OperatorType _type)
- {
- var _index = operatorList.FindIndex((x) =>
- {
- return x == _char;
- });
- _type = OperatorType.Plus;
- if (_index == -1)
- {
- return false;
- }
- _type = GetOperatorType(_char);
- switch (_type)
- {
- case OperatorType.Floor:
- case OperatorType.Ceil:
- case OperatorType.Min:
- case OperatorType.Max:
- case OperatorType.Remain:
- case OperatorType.Pow:
- case OperatorType.Random:
- case OperatorType.RandomInt:
- case OperatorType.Sqrt:
- return true;
- }
- return false;
- }
- }
-
- public enum OperatorType
- {
- Plus,//+
- Subtract,//-
- Ride,//*
- Divide,// /
- Pow,// ^
- Min,// !
- Max,// @
- Remain,// %
- Random,
- Floor,
- Ceil,
- RandomInt,
- Sqrt
- }
-}
diff --git a/Main/Core/GameEngine/Common/Equation.cs.meta b/Main/Core/GameEngine/Common/Equation.cs.meta
deleted file mode 100644
index 662170c..0000000
--- a/Main/Core/GameEngine/Common/Equation.cs.meta
+++ /dev/null
@@ -1,12 +0,0 @@
-fileFormatVersion: 2
-guid: 87f34f1073caa794c85c409b99178842
-timeCreated: 1513492313
-licenseType: Free
-MonoImporter:
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/H04_Scene/DTC0403_tagPlayerLoginLoadOK.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/H04_Scene/DTC0403_tagPlayerLoginLoadOK.cs
index c006fc4..5a05687 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/H04_Scene/DTC0403_tagPlayerLoginLoadOK.cs
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/H04_Scene/DTC0403_tagPlayerLoginLoadOK.cs
@@ -7,7 +7,7 @@
public static bool finishedLogin = false;
public static event Action playerLoginOkEvent;
//public static event Action mapInitOkEvent; 鏈嶅姟绔�氱煡鍦烘櫙鍒囨崲鎴愬姛
-
+
public override void Done(GameNetPackBasic vNetPack)
{
@@ -31,6 +31,10 @@
playerLoginOkEvent?.Invoke();
}
finishedLogin = true;
+ if (PlayerDatas.Instance.baseData.FightPoint == 0)
+ {
+ BattleManager.Instance.MainFightRequest(1, 1);
+ }
//if (mapInitOkEvent != null)
//{
// mapInitOkEvent();
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HB1_Role/DTCB122_tagSCHeroInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HB1_Role/DTCB122_tagSCHeroInfo.cs
index ae72da7..aff48f1 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HB1_Role/DTCB122_tagSCHeroInfo.cs
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HB1_Role/DTCB122_tagSCHeroInfo.cs
@@ -4,8 +4,10 @@
// B1 22 姝﹀皢鍥鹃壌淇℃伅 #tagSCHeroInfo
public class DTCB122_tagSCHeroInfo : DtcBasic {
- public override void Done(GameNetPackBasic vNetPack) {
+ public override void Done(GameNetPackBasic vNetPack)
+ {
base.Done(vNetPack);
HB122_tagSCHeroInfo vNetData = vNetPack as HB122_tagSCHeroInfo;
+ HeroUIManager.Instance.UpdateHeroCollectInfo(vNetData);
}
}
diff --git a/Main/System/CustomizedGift/CustomizedGiftModel.cs b/Main/System/CustomizedGift/CustomizedGiftModel.cs
index 5f70623..e1e8096 100644
--- a/Main/System/CustomizedGift/CustomizedGiftModel.cs
+++ b/Main/System/CustomizedGift/CustomizedGiftModel.cs
@@ -14,7 +14,7 @@
public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_Activity2;
public const int activityID = (int)NewDayActivityID.CustomizedGiftWin;
- public static Operation operaType = Operation.default35;
+ public static OperationType operaType = OperationType.default35;
public int actNum; //瀵瑰簲鐣岄潰
public event Action UpdateRechargeGiftActEvent;
@@ -56,7 +56,7 @@
}
}
- private void OperationEndEvent(Operation type, int state)
+ private void OperationEndEvent(OperationType type, int state)
{
if (type == operaType && state == 0)
{
@@ -68,7 +68,7 @@
}
}
- private void OperationAdvanceEvent(Operation type)
+ private void OperationAdvanceEvent(OperationType type)
{
if (type == operaType)
{
@@ -79,7 +79,7 @@
}
}
- private void OperationStartEvent(Operation type, int state)
+ private void OperationStartEvent(OperationType type, int state)
{
if (type == operaType && state == 0)
{
diff --git a/Main/System/Equip/EquipExchangeCell.cs b/Main/System/Equip/EquipExchangeCell.cs
index 62f9ce8..3c39c5e 100644
--- a/Main/System/Equip/EquipExchangeCell.cs
+++ b/Main/System/Equip/EquipExchangeCell.cs
@@ -97,11 +97,14 @@
if (showFightPower < 0)
{
- fightPowerNum.text = UIHelper.AppendColor(TextColType.Red, $"-{UIHelper.ReplaceLargeNum(showFightPower)}", false);
+ fightPowerNum.text = UIHelper.AppendColor(TextColType.Red, $"-{UIHelper.ReplaceLargeNum(Math.Abs(showFightPower))}", false);
+ cmpResult = 2;
}
else
{
+ cmpResult = showFightPower > 0 ? 1 : 0;
fightPowerNum.text = UIHelper.AppendColor(TextColType.Green, $"+{UIHelper.ReplaceLargeNum(showFightPower)}", false);
+
}
}
diff --git a/Main/System/Equip/EquipExchangeWin.cs b/Main/System/Equip/EquipExchangeWin.cs
index e39f807..fb3c1c2 100644
--- a/Main/System/Equip/EquipExchangeWin.cs
+++ b/Main/System/Equip/EquipExchangeWin.cs
@@ -17,11 +17,11 @@
protected override void OnPreOpen()
{
-
// 閫氱煡涓绘垬鍦烘殏鍋�
BattleManager.Instance.storyBattleField.IsPause = true;
EquipModel.Instance.OnEquipOPResultAction += OnRefreshItem;
Display();
+
// if (EquipModel.Instance.newEquipIDToGuideID.ContainsKey(EquipModel.Instance.selectFloorEquip.itemId))
// {
// // if (!NewBieCenter.Instance.IsGuideCompleted(EquipModel.Instance.newEquipIDToGuideID[EquipModel.Instance.selectFloorEquip.itemId]))
diff --git a/Main/System/Equip/EquipModel.cs b/Main/System/Equip/EquipModel.cs
index cb42268..5cf7211 100644
--- a/Main/System/Equip/EquipModel.cs
+++ b/Main/System/Equip/EquipModel.cs
@@ -8,8 +8,9 @@
public class EquipModel : GameSystemManager<EquipModel>
{
+ public const int TotleEquip = 12; //瑁呭鏍忓ぇ灏�
public bool waitEquipOPPack = false;
- public event Action<bool, int > OnEquipOPResultAction; //鏄惁鎹笂浜嗘柊瑁呭涓斿垎瑙d簡 瑁呭绱㈠紩
+ public event Action<bool, int> OnEquipOPResultAction; //鏄惁鎹笂浜嗘柊瑁呭涓斿垎瑙d簡 瑁呭绱㈠紩
public event Action<List<int>, RectTransform> OnItemDropEvent;
//鐢ㄤ簬椋樺姩閫昏緫
@@ -79,7 +80,7 @@
}
void OnDropEvent(string guid, BattleDrops drops, Action action)
- {
+ {
NotifyItemDrop(drops.dropItemPackIndex, drops.rectTransform);
action?.Invoke();
}
@@ -158,7 +159,7 @@
else
{
if (!UIManager.Instance.IsOpened<EquipExchangeWin>())
- {
+ {
UIManager.Instance.OpenWindow<EquipExchangeWin>();
}
}
@@ -264,7 +265,7 @@
{
if (waitEquipOP.Count == 0)
return null;
-
+
ItemModel item = PackManager.Instance.GetItemByIndex(PackType.DropItem, waitEquipOP.Dequeue());
if (AutoFightModel.Instance.isAutoAttack)
{
@@ -272,7 +273,7 @@
return null;
}
-
+
return item;
}
@@ -344,9 +345,14 @@
}
public bool IsEquip(int itemID)
- {
+ {
return ItemConfig.Get(itemID).EquipPlace != 0;
}
+
+ public ItemModel GetEquip(int index)
+ {
+ return PackManager.Instance.GetItemByIndex(PackType.Equip, index);
+ }
}
diff --git a/Main/System/Hero/HeroAttrType.cs b/Main/System/Hero/HeroAttrType.cs
index 9e7e2d3..3a6cd67 100644
--- a/Main/System/Hero/HeroAttrType.cs
+++ b/Main/System/Hero/HeroAttrType.cs
@@ -2,12 +2,12 @@
public enum HeroAttrType
{
- // 鐢熷懡
- hp,
// 鏀诲嚮鍔�
- attack,
+ attack = 6,
// 闃插尽鍔�
- defense,
+ defense = 7,
+ // 鐢熷懡
+ hp = 8,
//鐪╂檿姒傜巼
stunRate,
//鏆村嚮姒傜巼
diff --git a/Main/System/Hero/HeroInfo.Awake.cs b/Main/System/Hero/HeroInfo.Awake.cs
index 8be924d..0dd7b23 100644
--- a/Main/System/Hero/HeroInfo.Awake.cs
+++ b/Main/System/Hero/HeroInfo.Awake.cs
@@ -5,23 +5,10 @@
{
// 瑙夐啋閰嶇疆
- public HeroAwakeConfig awakeConfig
- {
- get
- {
- return HeroAwakeConfig.GetHeroAwakeConfig(heroId, awakeLevel);
- }
- }
+ public HeroAwakeConfig awakeConfig { get; private set; }
-
// 鍝佽川瑙夐啋閰嶇疆
- public HeroQualityAwakeConfig qualityAwakeConfig
- {
- get
- {
- return HeroQualityAwakeConfig.GetQualityAwakeConfig(Quality, awakeLevel);
- }
- }
+ public HeroQualityAwakeConfig qualityAwakeConfig { get; private set; }
// 姝﹀皢瑙夐啋绛夌骇
public int awakeLevel
@@ -34,9 +21,65 @@
}
}
- protected int GetIFByInheritAwakePercent(HeroAttrType attrType)
- {
- // YYL TODO
- return 0;
- }
+
+ Dictionary<int, int> awakeAttrs = new Dictionary<int, int>();
+ //璁$畻瑙夐啋灞炴��
+ public void RefreshAwakeAttr()
+ {
+ awakeAttrs.Clear();
+
+ for (int i = 0; i < awakeLevel; i++)
+ {
+ var tmpAwakeConfig = HeroAwakeConfig.GetHeroAwakeConfig(heroId, awakeLevel);
+ if (tmpAwakeConfig == null)
+ continue;
+ for(int j = 0; j < tmpAwakeConfig.AttrIDList.Length; j++)
+ {
+ int id = tmpAwakeConfig.AttrIDList[j];
+ if (!breakAttrs.ContainsKey(id))
+ {
+ breakAttrs.Add(id, tmpAwakeConfig.AttrValueList[j]);
+ }
+ else
+ {
+ breakAttrs[id] += tmpAwakeConfig.AttrValueList[j];
+ }
+ }
+
+ if (tmpAwakeConfig.SkillID != 0)
+ {
+ var skillConfig = SkillConfig.Get(tmpAwakeConfig.SkillID);
+ if (allSkillTypeIDToID.ContainsKey(skillConfig.SkillTypeID))
+ {
+ var tmpSkillConfig = SkillConfig.Get(allSkillTypeIDToID[skillConfig.SkillTypeID]);
+ if (skillConfig.SkillID > tmpSkillConfig.SkillID)
+ {
+ //鍙栨渶澶ф妧鑳�
+ allSkillTypeIDToID[skillConfig.SkillTypeID] = tmpAwakeConfig.SkillID;
+ }
+ }
+ else
+ {
+ allSkillTypeIDToID[skillConfig.SkillTypeID] = tmpAwakeConfig.SkillID;
+ }
+ }
+ }
+ }
+
+ public int GetAwakeAttrValue(int attrType)
+ {
+ int value = 0;
+ awakeAttrs.TryGetValue(attrType, out value);
+ return value;
+ }
+
+ public int GetAwakeAttrPer(int attrType)
+ {
+ if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrType))
+ {
+ var pertype = PlayerPropertyConfig.baseAttr2perDict[attrType];
+ return awakeAttrs.ContainsKey(pertype) ? awakeAttrs[pertype] : 0;
+ }
+ return 0;
+ }
}
\ No newline at end of file
diff --git a/Main/System/Hero/HeroInfo.Break.cs b/Main/System/Hero/HeroInfo.Break.cs
index e91b69c..43158c8 100644
--- a/Main/System/Hero/HeroInfo.Break.cs
+++ b/Main/System/Hero/HeroInfo.Break.cs
@@ -1,19 +1,15 @@
+//姝﹀皢绐佺牬锛氭灏嗗崌绾у悗闇�瑕佺獊鐮存墠鑳界户缁崌绾э紝绐佺牬鍙幏寰楁綔鑳�
+using System.Collections.Generic;
public partial class HeroInfo
{
// 绐佺牬閰嶇疆
- public HeroBreakConfig breakConfig
- {
- get
- {
- return HeroBreakConfig.GetHeroBreakConfig(heroId, breakLevel);
- }
- }
+ public HeroBreakConfig breakConfig { get; private set;}
// 鍝佽川绐佺牬閰嶇疆
- public HeroQualityBreakConfig qualityBreakConfig;
+ public HeroQualityBreakConfig qualityBreakConfig { get; private set;}
// 姝﹀皢绐佺牬绛夌骇
public int breakLevel
@@ -26,17 +22,64 @@
}
}
- protected int GetBreakCultivationPercent(HeroAttrType attrType)
+ Dictionary<int, int> breakAttrs = new Dictionary<int, int>(); //娼滆兘灞炴�d锛氭綔鑳藉��
+ //璁$畻娼滆兘灞炴��
+ public void RefreshBreakAttr()
{
- // YYL TODO
- return 0;
- }
-
- protected int GetIFByInheritBreakPercent(HeroAttrType attrType)
- {
- // YYL TODO
- return 0;
- }
-
+ breakAttrs.Clear();
+ for (int i = 0; i < breakLevel; i++)
+ {
+ var tmpBreakConfig = HeroBreakConfig.GetHeroBreakConfig(heroId, i);
+ if (tmpBreakConfig == null)
+ continue;
+ for(int j = 0; j < tmpBreakConfig.AttrIDList.Length; j++)
+ {
+ int id = tmpBreakConfig.AttrIDList[j];
+ if (!breakAttrs.ContainsKey(id))
+ {
+ breakAttrs.Add(id, tmpBreakConfig.AttrValueList[j]);
+ }
+ else
+ {
+ breakAttrs[id] += tmpBreakConfig.AttrValueList[j];
+ }
+ }
+ if (tmpBreakConfig.SkillID != 0)
+ {
+ var skillConfig = SkillConfig.Get(tmpBreakConfig.SkillID);
+ if (skillConfig == null) continue;
+ if (allSkillTypeIDToID.ContainsKey(skillConfig.SkillTypeID))
+ {
+ var tmpSkillConfig = SkillConfig.Get(allSkillTypeIDToID[skillConfig.SkillTypeID]);
+ if (skillConfig.SkillID > tmpSkillConfig.SkillID)
+ {
+ //鍙栨渶澶ф妧鑳�
+ allSkillTypeIDToID[skillConfig.SkillTypeID] = tmpBreakConfig.SkillID;
+ }
+ }
+ else
+ {
+ allSkillTypeIDToID[skillConfig.SkillTypeID] = tmpBreakConfig.SkillID;
+ }
+ }
+ }
+ }
+
+ public int GetBreakAttrValue(int attrType)
+ {
+ int value = 0;
+ breakAttrs.TryGetValue(attrType, out value);
+ return value;
+ }
+
+ public int GetBreakAttrPer(int attrType)
+ {
+ if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrType))
+ {
+ var pertype = PlayerPropertyConfig.baseAttr2perDict[attrType];
+ return breakAttrs.ContainsKey(pertype) ? breakAttrs[pertype] : 0;
+ }
+ return 0;
+ }
}
diff --git a/Main/System/Hero/HeroInfo.Equip.cs b/Main/System/Hero/HeroInfo.Equip.cs
deleted file mode 100644
index 223adc7..0000000
--- a/Main/System/Hero/HeroInfo.Equip.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-public partial class HeroInfo
-{
- protected int GetEquipStableProperties(HeroAttrType attrType)
- {
- // YYL TODO
- return 0;
- }
-
-}
diff --git a/Main/System/Hero/HeroInfo.Equip.cs.meta b/Main/System/Hero/HeroInfo.Equip.cs.meta
deleted file mode 100644
index 72b571d..0000000
--- a/Main/System/Hero/HeroInfo.Equip.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 27a10dfeaeacac3439ab8ecc85001796
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Main/System/Hero/HeroInfo.Fetter.cs b/Main/System/Hero/HeroInfo.Fetter.cs
index 9175f06..98f01cd 100644
--- a/Main/System/Hero/HeroInfo.Fetter.cs
+++ b/Main/System/Hero/HeroInfo.Fetter.cs
@@ -1,15 +1,56 @@
-
-
-
using System.Collections.Generic;
using System.Linq;
+//缇佺粖锛氫笂闃靛悗鐨勬灏嗙粍鍚堝彲婵�娲荤緛缁�
public partial class HeroInfo
{
- // 缇佺粖閰嶇疆
- public HeroFetterConfig fetterConfig;
+ Dictionary<int, int> fetterAttrs = new Dictionary<int, int>(); //缇佺粖灞炴�D锛氬睘鎬у��
+ //涓嶅悓闃靛缇佺粖灞炴�т笉鍚岋紝瀹炴椂璁$畻锛屼笌鍏朵粬缂撳瓨鐨勪笉鍚�
+ public void RefreshFetterAttrsWhenCalcPower(TeamType teamType)
+ {
+ fetterAttrs.Clear();
+ var list = GetActiveFetter(heroConfig, TeamManager.Instance.GetTeam(teamType));
+
+ foreach (var id in list)
+ {
+ var config = HeroFetterConfig.Get(id);
+ var attrIDs = config.AttrIDList;
+ var attrValues = config.AttrValueList;
+ for (int i = 0; i < attrIDs.Length; i++)
+ {
+ if (!fetterAttrs.ContainsKey(attrIDs[i]))
+ {
+ fetterAttrs.Add(attrIDs[i], attrValues[i]);
+ }
+ else
+ {
+ fetterAttrs[attrIDs[i]] += attrValues[i];
+ }
+ }
+ }
+ }
+
+
+ public int GetFetterAttrValue(int attrType)
+ {
+ int value = 0;
+ fetterAttrs.TryGetValue(attrType, out value);
+ return value;
+ }
+
+ public int GetFetterAttrPer(int attrType)
+ {
+ if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrType))
+ {
+ var pertype = PlayerPropertyConfig.baseAttr2perDict[attrType];
+ return fetterAttrs.ContainsKey(pertype) ? fetterAttrs[pertype] : 0;
+ }
+ return 0;
+ }
+
+
public List<int> GetActiveFetter(HeroConfig config, TeamBase teamBase)
{
List<int> list = new List<int>();
diff --git a/Main/System/Hero/HeroInfo.InheritPer.cs b/Main/System/Hero/HeroInfo.InheritPer.cs
new file mode 100644
index 0000000..bcd084e
--- /dev/null
+++ b/Main/System/Hero/HeroInfo.InheritPer.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+using System.Linq;
+
+public partial class HeroInfo
+{
+ //缁ф壙鐧惧垎姣斿搴斾笁鍥达紝瀵瑰簲灞炴�ф潯鐩〃閲岀殑ID
+ Dictionary<int, int> inheritPer
+ {
+ get
+ {
+ return new Dictionary<int, int>() {
+ { 6, heroConfig.AtkInheritPer },
+ { 7, heroConfig.DefInheritPer },
+ { 8, heroConfig.HPInheritPer },
+ };
+ }
+ }
+
+ public int GetInheritAttrPer(int attrType)
+ {
+ return inheritPer.ContainsKey(attrType) ? inheritPer[attrType] : 0;
+ }
+
+}
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/System/Hero/HeroInfo.InheritPer.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/System/Hero/HeroInfo.InheritPer.cs.meta
index e37f87e..ff98ed8 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/System/Hero/HeroInfo.InheritPer.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: 43bccdd0f6575254591fc49d33072614
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/System/Hero/HeroInfo.Level.cs b/Main/System/Hero/HeroInfo.Level.cs
deleted file mode 100644
index cf413f2..0000000
--- a/Main/System/Hero/HeroInfo.Level.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-public partial class HeroInfo
-{
- // 姝﹀皢绛夌骇
- public int heroLevel
- {
- get
- {
- if (itemHero == null)
- return 0;
- return itemHero.GetUseDataFirstValue(70);
- }
- }
-
- protected int GetLevelCultivationPercent(HeroAttrType attrType)
- {
- // YYL TODO
- return 0;
- }
-
-}
diff --git a/Main/System/Hero/HeroInfo.Level.cs.meta b/Main/System/Hero/HeroInfo.Level.cs.meta
deleted file mode 100644
index 781b376..0000000
--- a/Main/System/Hero/HeroInfo.Level.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 2a7ad855fa3dd5249a06835e88181ddd
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Main/System/Hero/HeroInfo.Lineup.cs b/Main/System/Hero/HeroInfo.Lineup.cs
index eac9cd5..7c23aa8 100644
--- a/Main/System/Hero/HeroInfo.Lineup.cs
+++ b/Main/System/Hero/HeroInfo.Lineup.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using UnityEngine;
+//闃靛甯冮樀
public partial class HeroInfo
{
public Dictionary<TeamType, KeyValuePair<int, int>> GetTeamTypeShapeTypePositionDict()
@@ -29,7 +30,7 @@
teamTypeShapeTypePositionDict.Add((TeamType)teamType, shapeTypePosition);
}
}
-
+
return teamTypeShapeTypePositionDict;
}
}
diff --git a/Main/System/Hero/HeroInfo.Properties.cs b/Main/System/Hero/HeroInfo.Properties.cs
index 4b383dd..fc5bb2b 100644
--- a/Main/System/Hero/HeroInfo.Properties.cs
+++ b/Main/System/Hero/HeroInfo.Properties.cs
@@ -1,14 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
public partial class HeroInfo
{
- // 鎴樻枟灞炴�х殑瑙﹀彂鍑犵巼璁$畻鏄�1瀵�1鐨勶紝鍙悓鏃惰Е鍙戝涓睘鎬т笖澶氭瑙﹀彂锛岃Е鍙戝嚑鐜囦笉浼氶殢鐫�鐩爣鏁伴噺澶氬皯鑰屾敼鍙橈紝鍙細鏍规嵁鍚屼竴鐩爣鐨勮Е鍙戞鏁板澶氳�岄檷浣庛��
- // 鍗冲湪涓�鍥炲悎鍐咃紝鍚屼竴涓洰鏍囧弽鍑汇�佽繛鍑汇�佸嚮鏅曘�佹毚鍑汇�侀棯閬垮彲浠ュ悓鏃跺苟澶氭瑙﹀彂锛岃Е鍙戝嚑鐜囬殢鏈鸿Е鍙戞鏁扮殑澧炲姞鑰岄檷浣庯紝姣忎釜灞炴�у紑鍏紡鏉ワ紙鍙傛暟锛氳Е鍙戝嚑鐜囥�佹姷鎶楀嚑鐜囥�佸凡瑙﹀彂娆℃暟锛�
- // 浼樺厛鍒ゆ柇鏄惁鍛戒腑锛屽繀涓悗鍚屾椂鍒ゆ柇姝ゆ鏀诲嚮鏄惁杩炲嚮銆佸嚮鏅曘�佹毚鍑荤敓鏁�
- // 鍙嶅嚮鏃跺繀鍛戒腑鐩爣
- // 姝﹀皢灞炴�ч渶鏃舵椂璁$畻锛屾牴鎹妧鑳姐�丅UFF銆佽澶囩瓑灞炴�ф潵婧愭敼鍙樿�屾敼鍙�
- // 鍩虹灞炴��
// 鐢熷懡
public int hp = 0;
// 鏀诲嚮鍔�
@@ -85,96 +83,75 @@
public int shieldSkillReduce;
+
//璁$畻涓汉/鑱屼笟/绉嶆棌鍏绘垚灞炴�у姞鎴�
public void CalculateProperties()
{
- // 姝﹀皢鍗曚綋灞炴�э紝鏍规嵁缁ф壙姣斾緥锛屼粠鍏ㄤ綋灞炴�х户鎵垮緱鍒�
- // 渚嬪锛氭灏嗘敾鍑诲姏=
- // [锛堣澶囧熀纭�鍥哄畾鍊�+鍏跺畠妯″潡鐨勫浐瀹氬�硷級* 锛�1+鍒濆鍔犳垚%+姝﹀皢鍗囩骇鍔犳垚%+姝﹀皢绐佺牬鍔犳垚%+姝﹀皢鍚炲櫖鏄熺骇鍔犳垚%+鍥鹃壌鍔犳垚%锛塢
- // *
- // [ 缁ф壙姣斾緥*锛�1+缇佺粖鍔犳垚%+娼滆兘鍔犳垚%+澶╄祴鍔犳垚%+瑙夐啋鏁堟灉鍔犳垚%锛塢
- hp = GetProperties(HeroAttrType.hp);
- attack = GetProperties(HeroAttrType.attack);
- defense = GetProperties(HeroAttrType.defense);
- stunRate = GetProperties(HeroAttrType.stunRate);
- critRate = GetProperties(HeroAttrType.critRate);
- comboRate = GetProperties(HeroAttrType.comboRate);
- blockRate = GetProperties(HeroAttrType.blockRate);
- counterAttackRate = GetProperties(HeroAttrType.counterAttackRate);
- recoverRate = GetProperties(HeroAttrType.recoverRate);
- stunResist = GetProperties(HeroAttrType.stunResist);
- critResist = GetProperties(HeroAttrType.critResist);
- comboResist = GetProperties(HeroAttrType.comboResist);
- blockResist = GetProperties(HeroAttrType.blockResist);
- counterAttackResist = GetProperties(HeroAttrType.counterAttackResist);
- recoverResist = GetProperties(HeroAttrType.recoverResist);
- }
+ allSkillTypeIDToID.Clear();
+ var skill = SkillConfig.Get(heroConfig.AtkSkillID);
+ if (skill != null)
+ {
+ allSkillTypeIDToID[skill.SkillTypeID] = heroConfig.AtkSkillID;
+ }
+ skill = SkillConfig.Get(heroConfig.AngerSkillID);
+ if (skill != null)
+ {
+ allSkillTypeIDToID[skill.SkillTypeID] = heroConfig.AngerSkillID;
+ }
- protected int GetProperties(HeroAttrType attrType)
- {
- return GetStableProperties(attrType)
- * GetCultivationPercent(attrType)
- * GetInheritRate(attrType)
- * GetTotalPercent(attrType);
+ RefreshTalentAttr();
+ RefreshBreakAttr();
+ RefreshAwakeAttr();
}
- // 鍥哄畾鍊煎睘鎬�
- public int GetStableProperties(HeroAttrType attrType)
- {
- int stableValue = 0;
- stableValue += GetEquipStableProperties(attrType);
- return stableValue;
- }
- // 鍩瑰吇鐧惧垎姣�
- public int GetCultivationPercent(HeroAttrType attrType)
+ long tmpFightPower = 0;
+ public long CalculatePower(bool forceRefresh = true)
{
- int cultivationPercent = 100;
- cultivationPercent += GetQualityCultivationPercent(attrType);//鍒濆鍔犳垚鏍规嵁姝﹀皢鍝佽川鍐冲畾锛屼笉鍚屽搧璐ㄦ灏嗗垵濮嬪姞鎴愪笉鍚� HeroInfo.Quality.cs
- cultivationPercent += GetLevelCultivationPercent(attrType);// 绛夌骇缁欑殑鐧惧垎姣� HeroInfo.Level.cs
- cultivationPercent += GetBreakCultivationPercent(attrType);// 绐佺牬缁欑殑鐧惧垎姣� HeroInfo.Break.cs
- cultivationPercent += GetStarCultivationPercent(attrType);// 鍚炲櫖鏄熺骇缁欑殑鐧惧垎姣� HeroInfo.Star.cs
- return cultivationPercent;
- }
-
- // 琚户鎵挎瘮渚嬪奖鍝嶇殑鐧惧垎姣斿睘鎬�
- public int GetTotalPercent(HeroAttrType attrType)
- {
- // 锛�1+缇佺粖鍔犳垚%+娼滆兘鍔犳垚%+澶╄祴鍔犳垚%+瑙夐啋鏁堟灉鍔犳垚%锛�
-
- int IFByInheritPercent = 100;
- // IFByInheritPercent += GetIFByInheritFetterPercent(attrType); //缇佺粖鍔犳垚 HeroInfo.Fetter
- // IFByInheritPercent += GetIFByInheritBreakPercent(attrType); //娼滆兘鍔犳垚 HeroInfo.Break
- // IFByInheritPercent += GetIFByInheritTalentPercent(attrType); //澶╄祴鍔犳垚 HeroInfo.Talent
- // IFByInheritPercent += GetIFByInheritAwakePercent(attrType); //瑙夐啋鍔犳垚 HeroInfo.Awake
- return IFByInheritPercent;
- }
-
- public int CalculatePower()
- {
- // 鏆傝
- return hp +
- attack +
- defense +
- stunRate +
- critRate +
- comboRate +
- blockRate +
- counterAttackRate +
- recoverRate +
- stunResist +
- critResist +
- comboResist +
- blockResist +
- counterAttackResist +
- recoverResist;
+ if (forceRefresh || tmpFightPower == 0)
+ {
+ tmpFightPower = FightPowerManager.Instance.GetHeroFightPower(this);
+ }
+ return tmpFightPower;
}
//涓婇樀灞炴��:鏀婚槻琛�
public int GetOnBattleAddPer()
- {
+ {
return qualityConfig.InitAddPer + qualityConfig.LVAddPer * heroLevel + qualityConfig.BreakLVAddPer * breakLevel + qualityConfig.StarAddPer * heroStar;
}
+
+ public int GetLineupLVAddPer()
+ {
+ return qualityConfig.LVAddPer * heroLevel;
+ }
+
+ public int GetLineupBreakLVAddPer()
+ {
+ return qualityConfig.BreakLVAddPer * breakLevel;
+ }
+
+ public int GetLineupStarAddPer()
+ {
+ return qualityConfig.StarAddPer * heroStar;
+ }
+
+ //棰濆閰嶇疆鐨勭櫨鍒嗙櫨姣斿姞鎴� 涓夊洿瀵瑰簲鐨� 鐧惧垎姣斿姞鎴�
+ public int GetSelfAddPer(int attrType)
+ {
+ if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrType))
+ {
+ var pertype = PlayerPropertyConfig.baseAttr2perDict[attrType];
+ return heroConfig.BatAttrDict.ContainsKey(pertype) ? heroConfig.BatAttrDict[pertype] : 0;
+ }
+ return 0;
+ }
+
+ public int GetSelfAddValue(int attrType)
+ {
+ return heroConfig.BatAttrDict.ContainsKey(attrType) ? heroConfig.BatAttrDict[attrType] : 0;
+ }
+
}
\ No newline at end of file
diff --git a/Main/System/Hero/HeroInfo.Quality.cs b/Main/System/Hero/HeroInfo.Quality.cs
deleted file mode 100644
index f320710..0000000
--- a/Main/System/Hero/HeroInfo.Quality.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-public partial class HeroInfo
-{
- // 鍝佽川閰嶇疆
- public HeroQualityConfig qualityConfig;
-
- public int Quality
- {
- get
- {
- return heroConfig.Quality;
- }
- }
-
- protected int GetQualityCultivationPercent(HeroAttrType attrType)
- {
- // YYL TODO
- return 0;
- }
-
-}
diff --git a/Main/System/Hero/HeroInfo.Star.cs b/Main/System/Hero/HeroInfo.Star.cs
deleted file mode 100644
index e966eec..0000000
--- a/Main/System/Hero/HeroInfo.Star.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-public partial class HeroInfo
-{
- // 姝﹀皢鏄熺骇
- public int heroStar
- {
- get
- {
- if (itemHero == null)
- return 0;
- return itemHero.GetUseDataFirstValue(72);
- }
- }
-
-
- protected int GetStarCultivationPercent(HeroAttrType attrType)
- {
- // YYL TODO
- return 0;
- }
-
-}
diff --git a/Main/System/Hero/HeroInfo.Star.cs.meta b/Main/System/Hero/HeroInfo.Star.cs.meta
deleted file mode 100644
index d113b22..0000000
--- a/Main/System/Hero/HeroInfo.Star.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 01382d3bab4b6674ba541f0704dd7037
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Main/System/Hero/HeroInfo.Talent.cs b/Main/System/Hero/HeroInfo.Talent.cs
index f66f6b7..4e5108d 100644
--- a/Main/System/Hero/HeroInfo.Talent.cs
+++ b/Main/System/Hero/HeroInfo.Talent.cs
@@ -1,12 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
-
-
+//姝﹀皢澶╄祴锛氬崌鏄熻幏寰楀ぉ璧嬶紝鍙礂缁�
public partial class HeroInfo
{
- protected int GetIFByInheritTalentPercent(HeroAttrType attrType)
+
+ public int heroStar
+ {
+ get
+ {
+ if (itemHero == null)
+ return 0;
+ return itemHero.GetUseDataFirstValue(72);
+ }
+ }
+
+ public List<HeroTalentInfo> talentList = new List<HeroTalentInfo>();
+
+
+ Dictionary<int, int> talentAttrDic = new Dictionary<int, int>(); //灞炴�D : 澶╄祴灞炴�у��
+ // 71 # 鑻遍泟澶╄祴ID鍒楄〃
+ // 73 # 鑻遍泟澶╄祴ID绛夌骇鍒楄〃锛屽搴�71澶╄祴ID鐨勭瓑绾�
+ // 75 # 鑻遍泟澶╄祴娲楃偧閿佸畾绱㈠紩鍒楄〃锛屽搴�71澶╄祴ID绱㈠紩
+ // 77 # 鑻遍泟澶╄祴娲楃偧闅忔満ID鍒楄〃
+ // 79 # 鑻遍泟瑙夐啋鏃堕殢鏈哄ぉ璧嬮�夐」ID鍒楄〃
+ protected void RefreshTalentAttr()
{
- // YYL TODO
- return 0;
+ // 71 # 鑻遍泟澶╄祴ID鍒楄〃
+ List<int> talentIDList = itemHero.GetUseData(71);
+ // // 73 # 鑻遍泟澶╄祴ID绛夌骇鍒楄〃锛屽搴�71澶╄祴ID鐨勭瓑绾�
+ List<int> talentLvList = itemHero.GetUseData(73);
+ talentAttrDic.Clear();
+
+ for (int i = 0; i < talentIDList.Count; i++)
+ {
+ if (talentIDList[i] == 0)
+ {
+ continue;
+ }
+ var config = HeroTalentConfig.Get(talentIDList[i]);
+ if (!talentAttrDic.ContainsKey(config.AttrID))
+ {
+ //澶╄祴灞炴�э紝鍊�*澶╄祴绛夌骇
+ talentAttrDic[config.AttrID] = config.AttrValue * talentLvList[i];
+ }
+ else
+ {
+ talentAttrDic[config.AttrID] += config.AttrValue * talentLvList[i];
+ }
+ }
+
+ }
+
+ public int GetTalentAttrValue(int attrType)
+ {
+ int value = 0;
+ talentAttrDic.TryGetValue(attrType, out value);
+ return value;
+ }
+
+ public int GetTalentAttrPer(int attrType)
+ {
+ if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrType))
+ {
+ var pertype = PlayerPropertyConfig.baseAttr2perDict[attrType];
+ return talentAttrDic.ContainsKey(pertype) ? talentAttrDic[pertype] : 0;
+ }
+ return 0;
}
}
diff --git a/Main/System/Hero/HeroInfo.cs b/Main/System/Hero/HeroInfo.cs
index 2080d00..2d0ae87 100644
--- a/Main/System/Hero/HeroInfo.cs
+++ b/Main/System/Hero/HeroInfo.cs
@@ -9,7 +9,7 @@
public int heroId;
// 姝﹀皢閰嶇疆
- public HeroConfig heroConfig;
+ public HeroConfig heroConfig { get; private set; }
public ItemModel itemHero; //寮曠敤鑳屽寘閲岀殑 鏁版嵁鍚屾
public HeroCountry heroCountry
@@ -20,7 +20,27 @@
}
}
+ // 鍝佽川閰嶇疆
+ public HeroQualityConfig qualityConfig { get; private set; }
+ public int Quality
+ {
+ get
+ {
+ return heroConfig.Quality;
+ }
+ }
+
+ // 姝﹀皢绛夌骇
+ public int heroLevel
+ {
+ get
+ {
+ if (itemHero == null)
+ return 0;
+ return itemHero.GetUseDataFirstValue(70);
+ }
+ }
// 浼樺厛鍔熻兘鎻愰啋绫诲瀷锛�1瑙夐啋 2鍗囩骇 3绐佺牬 4鍗囨槦
// 浼樺厛椤哄簭锛�
public int funcState
@@ -40,8 +60,8 @@
}
-
- public List<HeroTalentInfo> talentList = new List<HeroTalentInfo>();
+ //宸插涔犵殑鎵�鏈夋妧鑳藉彇鏈�楂樼骇鐨勬妧鑳�
+ Dictionary<int, int> allSkillTypeIDToID = new Dictionary<int, int>(); //鎶�鑳界被鍨婭D锛� 鏈�楂樻妧鑳絀D
public HeroInfo(ItemModel _itemHero)
@@ -49,17 +69,7 @@
UpdateHero(_itemHero);
}
-#if UNITY_EDITOR
- public HeroInfo()
- {
- heroId = 520001; // 榛樿鑻遍泟ID
- heroConfig = HeroConfig.Get(heroId);
- qualityConfig = HeroQualityConfig.Get(Quality);
- qualityBreakConfig = HeroQualityBreakConfig.GetQualityBreakConfig(Quality, awakeLevel);
- CalculateProperties();
- }
-#endif
public void UpdateHero(ItemModel _itemHero)
@@ -68,28 +78,9 @@
// HeroConfigUtility
heroId = itemHero.config.ID;
-
InitConfigs();
- // 71 # 鑻遍泟澶╄祴ID鍒楄〃
- // List<int> talentSkillList = itemHero.GetUseData(71);
- // // 73 # 鑻遍泟澶╄祴ID绛夌骇鍒楄〃锛屽搴�71澶╄祴ID鐨勭瓑绾�
- // List<int> talentLvList = itemHero.GetUseData(73);
- // // 75 # 鑻遍泟澶╄祴娲楃偧閿佸畾绱㈠紩鍒楄〃锛屽搴�71澶╄祴ID绱㈠紩
- // List<int> talentLockList = itemHero.GetUseData(75);
-
- // if (talentLockList.Count != talentLvList.Count || talentLvList.Count != talentSkillList.Count)
- // {
- // Debug.LogError("澶╄祴ID鍒楄〃鍙婂悗缁殑鏁版嵁鏁伴噺娌″涓�");
- // }
-
- // // 澶╄祴
- // talentList.Clear();
- // for (int i = 0; i < talentSkillList.Count; i++)
- // {
- // talentList.Add(new HeroTalentInfo(this, talentSkillList[i], talentLvList[i], talentLockList[i]));
- // }
-
+ CalculateProperties();
// // 缇佺粖
// fetterInfoList.Clear();
// for (int i = 0; i < heroConfig.FetterIDList.Length; i++)
@@ -97,8 +88,6 @@
// fetterInfoList.Add(new HeroFetterInfo(this, heroConfig.FetterIDList[i]));
// }
- // 77 # 鑻遍泟澶╄祴娲楃偧闅忔満ID鍒楄〃
- // 79 # 鑻遍泟瑙夐啋鏃堕殢鏈哄ぉ璧嬮�夐」ID鍒楄〃
// 80 # 涓婚樀鍨嬩笂闃典綅缃�
}
@@ -106,33 +95,34 @@
{
// 姝﹀皢閰嶇疆
heroConfig = HeroConfig.Get(heroId);
-
-
// 鍝佽川閰嶇疆
qualityConfig = HeroQualityConfig.Get(Quality);
// 鍝佽川绐佺牬閰嶇疆
qualityBreakConfig = HeroQualityBreakConfig.GetQualityBreakConfig(Quality, breakLevel);
+ breakConfig = HeroBreakConfig.GetHeroBreakConfig(heroId, breakLevel);
+ awakeConfig = HeroAwakeConfig.GetHeroAwakeConfig(heroId, awakeLevel);
+ qualityAwakeConfig = HeroQualityAwakeConfig.GetQualityAwakeConfig(Quality, awakeLevel);
+
}
- public int GetInheritRate(HeroAttrType attrType)
- {
- return heroConfig.GetInheritPercent(attrType);
- }
-
- //鏄惁涓妜闃� 81 # 鎵�鍦ㄩ樀瀹逛俊鎭垪琛� [闃靛绫诲瀷*10000+闃靛瀷绫诲瀷*100+浣嶇疆缂栧彿, ...]
+
+
+ //鏄惁涓妜闃� 鏈嶅姟绔槦浼�
public bool IsInTeamByTeamType(TeamType teamType)
{
- var list = itemHero.GetUseData(81);
- if (list != null && list.Count > 0)
- {
- var index = list.FindIndex((item) => item / 10000 == (int)teamType);
- if (index >= 0)
- {
- return true;
- }
- }
- return false;
+ return TeamManager.Instance.GetTeam(teamType).HasHeroInServer(itemHero.guid);
}
+
+ public long GetSkillsFightPower()
+ {
+ long fightPower = 0;
+ foreach (var skillID in allSkillTypeIDToID.Values)
+ {
+ fightPower += SkillConfig.Get(skillID).FightPower;
+ }
+ return fightPower;
+ }
+
}
\ No newline at end of file
diff --git a/Main/System/Hero/HeroManager.cs b/Main/System/Hero/HeroManager.cs
index b7259a0..668ba42 100644
--- a/Main/System/Hero/HeroManager.cs
+++ b/Main/System/Hero/HeroManager.cs
@@ -124,8 +124,8 @@
heroList.Sort((a, b) =>
{
- int power1 = a.CalculatePower();
- int power2 = b.CalculatePower();
+ long power1 = a.CalculatePower(false);
+ long power2 = b.CalculatePower(false);
if (power1 == power2)
{
diff --git a/Main/System/HeroUI/HeroFormationCell.cs b/Main/System/HeroUI/HeroFormationCell.cs
index 8290d71..d12a38c 100644
--- a/Main/System/HeroUI/HeroFormationCell.cs
+++ b/Main/System/HeroUI/HeroFormationCell.cs
@@ -12,7 +12,7 @@
public void Display(int index)
{
- Int2 result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.selectTeamType);
+ Int2 result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.selectTeamType, true);
var config = HeroLineupHaloConfig.GetConfig(result.x, result.y);
bool sameCountry = result.x == (index + 1);
diff --git a/Main/System/HeroUI/HeroFormationWin.cs b/Main/System/HeroUI/HeroFormationWin.cs
index 4c8e657..a2c0369 100644
--- a/Main/System/HeroUI/HeroFormationWin.cs
+++ b/Main/System/HeroUI/HeroFormationWin.cs
@@ -24,7 +24,7 @@
scroller.OnRefreshCell += OnRefreshCell;
CreateScroller();
- Int2 result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.selectTeamType);
+ Int2 result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.selectTeamType, true);
var config = HeroLineupHaloConfig.GetConfig(result.x, result.y);
if (config == null)
diff --git a/Main/System/HeroUI/HeroLVBreakWin.cs b/Main/System/HeroUI/HeroLVBreakWin.cs
index e2603a3..015731a 100644
--- a/Main/System/HeroUI/HeroLVBreakWin.cs
+++ b/Main/System/HeroUI/HeroLVBreakWin.cs
@@ -80,7 +80,7 @@
}
if (nextQualityBreakConfig.SkillID != 0)
{
- attrStrArr.Add(SkillConfig.Get(nextQualityBreakConfig.SkillID).Description);
+ attrStrArr.Add(SkillConfig.Get(nextQualityBreakConfig.SkillID)?.Description);
}
potentialText.text = Language.Get("L1100", Language.Get("herocard56"), string.Join(Language.Get("L1112"), attrStrArr));
}
diff --git a/Main/System/HeroUI/HeroPosWin.cs b/Main/System/HeroUI/HeroPosWin.cs
index 5689a2c..75bc0db 100644
--- a/Main/System/HeroUI/HeroPosWin.cs
+++ b/Main/System/HeroUI/HeroPosWin.cs
@@ -48,7 +48,7 @@
private bool m_IsToggleOn = false;
private bool isToggleOn
- {
+ {
get { return m_IsToggleOn; }
set
{
@@ -114,6 +114,7 @@
HeroUIManager.Instance.SortHeroOnTeamList();
heroListScroller.OnRefreshCell += OnRefreshCell;
HeroUIManager.Instance.OnTeamPosChangeEvent += TeamChangeEvent;
+ TeamManager.Instance.OnTeamChange += OnTeamChange;
CreateScroller();
Refresh();
}
@@ -123,6 +124,7 @@
CancelCurrentTask();
heroListScroller.OnRefreshCell -= OnRefreshCell;
HeroUIManager.Instance.OnTeamPosChangeEvent -= TeamChangeEvent;
+ TeamManager.Instance.OnTeamChange -= OnTeamChange;
TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType).RestoreTeam();
}
@@ -143,9 +145,9 @@
fiterManager.Display(0, HeroUIManager.Instance.selectTeamPosJob, HeroUIManager.Instance.selectTeamPosCountry, SelectJobCountry);
- fightPowerText.text = "1234k";
+ fightPowerText.text = UIHelper.ReplaceLargeArtNum(FightPowerManager.Instance.GetTeamFightPower(HeroUIManager.Instance.selectTeamType, true));
-
+
}
void RefreshFlyHead()
@@ -176,7 +178,7 @@
}
void RefreshEmptyTip()
- {
+ {
if (HeroUIManager.Instance.heroOnTeamSortList.Count <= 0)
{
heroListEmpty.SetActive(true);
@@ -237,7 +239,7 @@
//涓婇樀姝﹀皢鍥藉鍏夌幆婵�娲�
void RefreshOnTeamCountry(bool playEffect = false)
{
- Int2 result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.selectTeamType);
+ Int2 result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.selectTeamType, true);
var config = HeroLineupHaloConfig.GetConfig(result.x, result.y);
if (config == null)
@@ -380,10 +382,12 @@
sequence.onComplete = () => { flyHead.transform.localScale = Vector3.zero; };
if (isToggleOn)
- {
+ {
ShowFetter(flyHero);
}
}
+ fightPowerText.text = UIHelper.ReplaceLargeArtNum(FightPowerManager.Instance.GetTeamFightPower(HeroUIManager.Instance.selectTeamType, true));
+
}
void ShowFetter(HeroInfo hero)
@@ -392,7 +396,7 @@
var fetterList = hero.GetActiveFetter(heroConfig, TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType));
for (int i = 0; i < fetterList.Count; i++)
{
- if(!showConnectTipQueue.Contains(fetterList[i]))
+ if (!showConnectTipQueue.Contains(fetterList[i]))
showConnectTipQueue.Enqueue(fetterList[i]);
}
@@ -472,12 +476,20 @@
{
return;
}
-
HeroUIManager.Instance.selectTeamPosJob = 0;
HeroUIManager.Instance.selectTeamPosCountry = 0;
- HeroUIManager.Instance.SortHeroOnTeamList();
HeroUIManager.Instance.selectTeamType = type;
+ HeroUIManager.Instance.SortHeroOnTeamList();
Refresh();
heroListScroller.m_Scorller.RefreshActiveCellViews();
}
+
+ protected void OnTeamChange(TeamType teamType)
+ {
+ if (HeroUIManager.Instance.selectTeamType == teamType)
+ {
+ HeroUIManager.Instance.SortHeroOnTeamList();
+ heroListScroller.m_Scorller.RefreshActiveCellViews();
+ }
+ }
}
\ No newline at end of file
diff --git a/Main/System/HeroUI/HeroTrainWin.cs b/Main/System/HeroUI/HeroTrainWin.cs
index 492fd0e..513bb57 100644
--- a/Main/System/HeroUI/HeroTrainWin.cs
+++ b/Main/System/HeroUI/HeroTrainWin.cs
@@ -140,7 +140,7 @@
jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(hero.heroConfig.Class));
jobPosNameText.text = HeroUIManager.Instance.GetJobName(hero.heroConfig.Class);
descText.text = hero.heroConfig.Desc;
- fightPowerText.text = hero.CalculatePower().ToString();
+ fightPowerText.text = UIHelper.ReplaceLargeArtNum(hero.CalculatePower());
lockImg.SetActive(hero.isLock);
unLockImg.SetActive(!hero.isLock);
nameText.text = hero.breakLevel == 0 ? hero.heroConfig.Name : Language.Get("herocardbreaklv", hero.heroConfig.Name, hero.breakLevel);
@@ -451,6 +451,8 @@
for (int i = 0; i < list.Count; i++)
{
var nextQualityBreakConfig = HeroBreakConfig.GetHeroBreakConfig(hero.heroId, i + 1);
+ if (nextQualityBreakConfig == null)
+ break;
List<string> attrStrArr = new List<string>();
for (int j = 0; j < nextQualityBreakConfig.AttrIDList.Length; j++)
{
@@ -459,7 +461,7 @@
}
if (nextQualityBreakConfig.SkillID != 0)
{
- attrStrArr.Add(SkillConfig.Get(nextQualityBreakConfig.SkillID).Description);
+ attrStrArr.Add(SkillConfig.Get(nextQualityBreakConfig.SkillID)?.Description);
}
if (i < hero.breakLevel)
{
diff --git a/Main/System/HeroUI/HeroUIManager.Collect.cs b/Main/System/HeroUI/HeroUIManager.Collect.cs
new file mode 100644
index 0000000..92a1705
--- /dev/null
+++ b/Main/System/HeroUI/HeroUIManager.Collect.cs
@@ -0,0 +1,46 @@
+锘縰sing System;
+using System.Collections;
+using System.Collections.Generic;
+
+using UnityEngine;
+
+public partial class HeroUIManager : GameSystemManager<HeroUIManager>
+{
+
+ #region 鍥鹃壌鍜岀毊鑲�
+
+ //鍥鹃壌鍜岀毊鑲ょ殑婵�娲绘儏鍐�
+ public Dictionary<int, HB122_tagSCHeroInfo.tagSCHero> heroCollectInfoDic { get; private set; } = new Dictionary<int, HB122_tagSCHeroInfo.tagSCHero>();
+
+ public int bookPer;
+ public event Action OnHeroCollectEvent;
+
+ public void UpdateHeroCollectInfo(HB122_tagSCHeroInfo netPack)
+ {
+ for (int i = 0; i < netPack.HeroCnt; i++)
+ {
+ heroCollectInfoDic[(int)netPack.HeroInfoList[i].HeroID] = netPack.HeroInfoList[i];
+ }
+ bookPer = GetHeroCollectBookPer();
+ OnHeroCollectEvent?.Invoke();
+ }
+
+
+ public int GetHeroCollectBookPer()
+ {
+ int per = 0;
+ foreach (var kv in heroCollectInfoDic)
+ {
+ var config = HeroQualityConfig.Get(HeroConfig.Get(kv.Key).Quality);
+ if (kv.Value.BookInitState != 2)
+ continue;
+ per += config.BookInitAddPer;
+ per += kv.Value.BookStarLV * config.BookStarAddPer;
+ per += kv.Value.BookBreakLV * config.BookBreakLVAddPer;
+ }
+ return per;
+ }
+
+ #endregion
+}
+
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/System/HeroUI/HeroUIManager.Collect.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/System/HeroUI/HeroUIManager.Collect.cs.meta
index e37f87e..cc3dae1 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/System/HeroUI/HeroUIManager.Collect.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: fde2bfe0f6468dc49951c562fd445d51
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/System/HeroUI/HeroUIManager.OnTeam.cs b/Main/System/HeroUI/HeroUIManager.OnTeam.cs
new file mode 100644
index 0000000..b3f4167
--- /dev/null
+++ b/Main/System/HeroUI/HeroUIManager.OnTeam.cs
@@ -0,0 +1,311 @@
+锘縰sing System;
+using System.Collections;
+using System.Collections.Generic;
+
+using UnityEngine;
+
+public partial class HeroUIManager : GameSystemManager<HeroUIManager>
+{
+
+
+ #region 甯冮樀鐣岄潰
+ public List<string> heroOnTeamSortList { get; private set; } = new List<string>(); //涓嶅悓涓婇樀鐨勫垪琛ㄦ帓搴�
+
+ private TeamType m_SelectTeamType = TeamType.Story; //褰撳墠閫変腑鐨勬槸鍝釜闃靛, 甯冮樀鐩稿叧閫昏緫浣跨敤
+ public TeamType selectTeamType
+ {
+ get { return m_SelectTeamType; }
+ set
+ {
+ if (m_SelectTeamType == value)
+ return;
+ //涓婁竴涓樀瀹归渶瑕佹仮澶嶅埌鍘熺姸鎬�
+ if (m_SelectTeamType != TeamType.None)
+ {
+ TeamManager.Instance.GetTeam(m_SelectTeamType).RestoreTeam();
+ }
+
+ m_SelectTeamType = value;
+ }
+ }
+
+ public int selectTeamPosJob = 0; //甯冮樀鐣岄潰 绛涢�夎亴涓�
+ public int selectTeamPosCountry = 0; //甯冮樀鐣岄潰 绛涢�夊浗瀹�
+
+ public const float clickFlyPosTime = 0.5f; //鐐瑰嚮鍒楄〃涓殑姝﹀皢鍥炬爣鏃�, 椋炲叆甯冮樀鐨勬椂闂�
+
+ public event Action<List<int>, int, Vector3> OnTeamPosChangeEvent; //甯冮樀鍙樺寲 浣嶇疆锛屽垪琛ㄧ殑璧烽绱㈠紩锛岃捣椋炲潗鏍�
+
+
+ // 銆愰樀瀹瑰睘鎬с�� - 璇ラ樀瀹规墍鏈夋灏嗘湁鏁�
+ // 鍒濆鍔犳垚 lineupInitAddPer
+ // 鍗囩骇鍔犳垚 lineupLVAddPer
+ // 绐佺牬鍔犳垚 lineupBreakLVAddPer
+ // 鍚炲櫖鍔犳垚 lineupStarAddPer
+ // 闃靛鍏夌幆 lineupHaloValue 銆� lineupHaloPer
+
+ /// <summary>
+ /// 鎸夐槦浼嶆眹鎬讳笂闃靛睘鎬�
+ /// </summary>
+ /// <param name="type"></param>
+ /// <param name="isPreview">true 瀹㈡埛绔瑙堥樀瀹癸紝榛樿false 鏈嶅姟鍣ㄩ樀瀹�</param>
+ /// <returns></returns>
+ public Dictionary<string, int> GetLineupPer(TeamType type, bool isPreview = false)
+ {
+ Dictionary<string, int> lineUPPer = new Dictionary<string, int>()
+ {
+ {"lineupInitAddPer", 0},
+ {"lineupLVAddPer", 0},
+ {"lineupBreakLVAddPer", 0},
+ {"lineupStarAddPer", 0},
+ };
+
+ var team = TeamManager.Instance.GetTeam(type);
+ if (team == null)
+ {
+ return lineUPPer;
+ }
+ TeamHero[] teamHeroes = isPreview ? team.tempHeroes : team.serverHeroes;
+
+ foreach (var teamHero in teamHeroes)
+ {
+ if (teamHero == null)
+ {
+ continue;
+ }
+ var config = HeroQualityConfig.Get(HeroConfig.Get(teamHero.heroId).Quality);
+ lineUPPer["lineupInitAddPer"] += config.InitAddPer;
+
+ HeroInfo hero = HeroManager.Instance.GetHero(teamHero.guid);
+ if (hero == null) continue;
+ lineUPPer["lineupLVAddPer"] += hero.GetLineupLVAddPer();
+ lineUPPer["lineupBreakLVAddPer"] += hero.GetLineupBreakLVAddPer();
+ lineUPPer["lineupStarAddPer"] += hero.GetLineupStarAddPer();
+
+ }
+ return lineUPPer;
+ }
+
+ /// <summary>
+ /// 鎸夐槦浼嶈幏寰楅樀鍨嬶紙鍥藉鍏夌幆锛夊睘鎬�
+ /// </summary>
+ /// <param name="teamType"></param>
+ /// <param name="isPreview">true 瀹㈡埛绔瑙堥樀瀹癸紝榛樿false 鏈嶅姟鍣ㄩ樀瀹�</param>
+ /// <returns></returns>
+ public Dictionary<int, int> GetCountryAttrs(TeamType teamType, bool isPreview = false)
+ {
+ Dictionary<int, int> countryAttrs = new Dictionary<int, int>();
+ Int2 result = GetMaxCountHeroCountry(teamType, isPreview);
+ var lineupconfig = HeroLineupHaloConfig.GetConfig(result.x, result.y);
+ if (lineupconfig != null)
+ {
+ for (int i = 0; i < lineupconfig.AttrIDList.Length; i++)
+ {
+ countryAttrs[lineupconfig.AttrIDList[i]] = lineupconfig.AttrValueList[i];
+ }
+ }
+
+ return countryAttrs;
+ }
+
+ public void SortHeroOnTeamList()
+ {
+ heroOnTeamSortList = HeroManager.Instance.GetHeroGuidList(selectTeamPosJob, selectTeamPosCountry);
+ heroOnTeamSortList.Sort(CmpHeroByTeamType);
+ }
+
+
+ int CmpHeroByTeamType(string guidA, string guidB)
+ {
+ HeroInfo heroA = HeroManager.Instance.GetHero(guidA);
+ HeroInfo heroB = HeroManager.Instance.GetHero(guidB);
+ if (heroA == null || heroB == null)
+ {
+ return 0;
+ }
+
+ var team = TeamManager.Instance.GetTeam(selectTeamType);
+ // 鎺掑簭瑙勫垯锛氫笂闃�>姝﹀皢绛夌骇锛炵獊鐮寸瓑绾э紴姝﹀皢瑙夐啋闃剁骇锛炴灏嗗搧璐紴姝﹀皢鍚炲櫖鏄熺骇锛炴灏咺D
+ bool isInTeamA = team.HasHeroInServer(guidA);
+ bool isInTeamB = team.HasHeroInServer(guidB);
+ if (isInTeamA != isInTeamB)
+ {
+ return isInTeamA ? -1 : 1;
+ }
+ if (heroA.heroLevel != heroB.heroLevel)
+ {
+ return heroA.heroLevel > heroB.heroLevel ? -1 : 1;
+ }
+ if (heroA.breakLevel != heroB.breakLevel)
+ {
+ return heroA.breakLevel > heroB.breakLevel ? -1 : 1;
+ }
+ if (heroA.awakeLevel != heroB.awakeLevel)
+ {
+ return heroA.awakeLevel > heroB.awakeLevel ? -1 : 1;
+ }
+ if (heroA.Quality != heroB.Quality)
+ {
+ return heroA.Quality > heroB.Quality ? -1 : 1;
+ }
+ if (heroA.heroStar != heroA.heroStar)
+ {
+ return heroA.heroStar > heroB.heroStar ? -1 : 1;
+ }
+
+ return heroA.heroId.CompareTo(heroB.heroId);
+ }
+
+
+
+
+ /// <summary>
+ /// 涓婇樀闃熶紞涓悇涓浗瀹剁殑姝﹀皢鏁伴噺
+ /// </summary>
+ /// <param name="teamType"></param>
+ /// <param name="isPreview">true 瀹㈡埛绔瑙堥樀瀹癸紝榛樿false 鏈嶅姟鍣ㄩ樀瀹�</param>
+ /// <returns></returns>
+ public Dictionary<HeroCountry, int> GetCountryHeroCountByTeamType(TeamType teamType, bool isPreview = false)
+ {
+ Dictionary<HeroCountry, int> heroCountryCount = new Dictionary<HeroCountry, int>();
+
+ var team = TeamManager.Instance.GetTeam(teamType);
+ if (team == null)
+ {
+ return heroCountryCount;
+ }
+ TeamHero[] teamHeroes = isPreview ? team.tempHeroes : team.serverHeroes;
+
+ for (int i = 0; i < teamHeroes.Length; i++)
+ {
+ if (teamHeroes[i] == null)
+ continue;
+ var country = teamHeroes[i].Country;
+
+ if (!heroCountryCount.ContainsKey(country))
+ {
+ heroCountryCount.Add(country, 1);
+ }
+ else
+ {
+ heroCountryCount[country] += 1;
+ }
+
+ }
+
+
+ return heroCountryCount;
+ }
+
+ /// <summary>
+ /// 鑾峰緱涓婇樀涓灏嗘暟閲忔渶澶х殑鍥藉鍜屾暟閲�
+ /// </summary>
+ /// <param name="teamType"></param>
+ /// <param name="isPreview">true 瀹㈡埛绔瑙堥樀瀹癸紝榛樿false 鏈嶅姟鍣ㄩ樀瀹�</param>
+ /// <returns></returns>
+ public Int2 GetMaxCountHeroCountry(TeamType teamType, bool isPreview = false)
+ {
+ var countryCountDict = GetCountryHeroCountByTeamType(teamType, isPreview);
+ //鎵惧埌鏈�澶х殑鍥藉鍜屾暟閲�
+ HeroCountry country = HeroCountry.None;
+ int maxValue = 0;
+ foreach (var data in countryCountDict)
+ {
+ if (data.Value > maxValue)
+ {
+ country = data.Key;
+ maxValue = data.Value;
+ }
+ }
+ return new Int2((int)country, maxValue);
+ }
+
+ //鍦ㄤ笉鍚岄〉绛句笅閫堿ttackType 0 鏀诲嚮闃靛 1 闃插畧闃靛
+ public int GetSelectTeamTypeByAttackType(int AttackType)
+ {
+ if (selectTeamType == TeamType.Arena || selectTeamType == TeamType.ArenaDefense)
+ {
+ return AttackType == 0 ? (int)TeamType.Arena : (int)TeamType.ArenaDefense;
+ }
+
+
+ return (int)TeamType.Story;
+ }
+
+
+ public void NotifyOnTeamPosChangeEvent(List<int> posList, int flyIndex, Vector3 startPos)
+ {
+ OnTeamPosChangeEvent?.Invoke(posList, flyIndex, startPos);
+ }
+
+ //鎺ㄨ崘闃靛
+ public List<string> SelectRecommend()
+ {
+ //鎺ㄨ崘闃靛鐨勭畻娉曢�昏緫
+ //鑷姩閫夋嫨浼樺厛绾э細姝﹀皢绛夌骇锛炵獊鐮寸瓑绾э紴姝﹀皢瑙夐啋闃剁骇锛炴灏嗗搧璐紴姝﹀皢鍚炲櫖鏄熺骇锛炴灏咺D
+ var tmpList = HeroManager.Instance.GetHeroGuidList();
+ tmpList.Sort(CmpHeroRecommend);
+
+
+ //鎺ㄨ崘鏈�澶�6涓紝瀛樺湪鐩稿悓heroid锛屽垯璺宠繃
+ List<string> selectHeroList = new List<string>();
+ List<int> selectHeroIDList = new List<int>();
+ for (int i = 0; i < tmpList.Count; i++)
+ {
+ if (selectHeroList.Count >= TeamConst.MaxTeamHeroCount)
+ break;
+
+ string guid = tmpList[i];
+ HeroInfo heroInfo = HeroManager.Instance.GetHero(guid);
+ if (selectHeroIDList.Contains(heroInfo.heroId))
+ continue;
+ //濡傛灉閲嶅浜�,璺宠繃
+ if (selectHeroList.Contains(guid))
+ continue;
+ selectHeroList.Add(guid);
+ selectHeroIDList.Add(heroInfo.heroId);
+ }
+ return selectHeroList;
+ }
+
+
+ int CmpHeroRecommend(string guidA, string guidB)
+ {
+ HeroInfo heroA = HeroManager.Instance.GetHero(guidA);
+ HeroInfo heroB = HeroManager.Instance.GetHero(guidB);
+ if (heroA == null || heroB == null)
+ {
+ return 0;
+ }
+
+ // 鎺掑簭瑙勫垯锛氭灏嗙瓑绾э紴绐佺牬绛夌骇锛炴灏嗚閱掗樁绾э紴姝﹀皢鍝佽川锛炴灏嗗悶鍣槦绾э紴姝﹀皢ID
+ if (heroA.heroLevel != heroB.heroLevel)
+ {
+ return heroA.heroLevel > heroB.heroLevel ? -1 : 1;
+ }
+ if (heroA.breakLevel != heroB.breakLevel)
+ {
+ return heroA.breakLevel > heroB.breakLevel ? -1 : 1;
+ }
+ if (heroA.awakeLevel != heroB.awakeLevel)
+ {
+ return heroA.awakeLevel > heroB.awakeLevel ? -1 : 1;
+ }
+ if (heroA.Quality != heroB.Quality)
+ {
+ return heroA.Quality > heroB.Quality ? -1 : 1;
+ }
+ if (heroA.heroStar != heroA.heroStar)
+ {
+ return heroA.heroStar > heroB.heroStar ? -1 : 1;
+ }
+
+ return heroA.heroId.CompareTo(heroB.heroId);
+ }
+
+
+ #endregion
+
+
+}
+
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/System/HeroUI/HeroUIManager.OnTeam.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/System/HeroUI/HeroUIManager.OnTeam.cs.meta
index e37f87e..4e8ae78 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/System/HeroUI/HeroUIManager.OnTeam.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: c8e0c0a46a38f1e49856253add1794e3
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/System/HeroUI/HeroUIManager.Reborn.cs b/Main/System/HeroUI/HeroUIManager.Reborn.cs
new file mode 100644
index 0000000..2ad8871
--- /dev/null
+++ b/Main/System/HeroUI/HeroUIManager.Reborn.cs
@@ -0,0 +1,83 @@
+锘縰sing System;
+using System.Collections;
+using System.Collections.Generic;
+
+using UnityEngine;
+
+public partial class HeroUIManager : GameSystemManager<HeroUIManager>
+{
+
+
+ #region 閲嶇敓 閬f暎
+ public int awakeRebirthCnt { get; private set; }
+ public int payBackMoneyType;
+ public int payBackMoney;
+ public Dictionary<int, ulong> GetHeroLVPayBack(int quality, int lv)
+ {
+ //姹囨�昏繑杩樻�绘暟閲�
+ Dictionary<int, ulong> itemCounDic = new Dictionary<int, ulong>();
+ for (int i = 1; i < lv; i++)
+ {
+ var config = HeroQualityLVConfig.GetQualityLVConfig(quality, lv);
+ var itemID = config.UPCostItem[0];
+ var count = (ulong)config.UPCostItem[1];
+ if (!itemCounDic.ContainsKey(itemID))
+ {
+ itemCounDic[itemID] = count;
+ }
+ itemCounDic[itemID] = itemCounDic[itemID] + count;
+ }
+
+ return itemCounDic;
+ }
+
+
+ public Dictionary<int, ulong> GetHeroBreakPayBack(int quality, int lv)
+ {
+ //姹囨�昏繑杩樻�绘暟閲�
+ Dictionary<int, ulong> itemCounDic = new Dictionary<int, ulong>();
+ for (int i = 0; i < lv; i++)
+ {
+ var config = HeroQualityBreakConfig.GetQualityBreakConfig(quality, lv);
+ var itemID = config.UPCostItem[0];
+ var count = (ulong)config.UPCostItem[1];
+ if (!itemCounDic.ContainsKey(itemID))
+ {
+ itemCounDic[itemID] = count;
+ }
+ itemCounDic[itemID] = itemCounDic[itemID] + count;
+ }
+
+ return itemCounDic;
+
+
+ }
+
+ public Dictionary<int, ulong> GetHeroQualityAwakePayBack(int quality, int lv)
+ {
+ //姹囨�昏繑杩樻�绘暟閲�
+ Dictionary<int, ulong> itemCounDic = new Dictionary<int, ulong>();
+ for (int i = 0; i < lv; i++)
+ {
+ var config = HeroQualityAwakeConfig.GetQualityAwakeConfig(quality, lv);
+ var itemID = config.UPCostItem[0];
+ var count = (ulong)config.UPCostItem[1];
+ if (!itemCounDic.ContainsKey(itemID))
+ {
+ itemCounDic[itemID] = count;
+ }
+ itemCounDic[itemID] = itemCounDic[itemID] + count;
+ }
+
+ return itemCounDic;
+ }
+
+ public void UpdateHeroInfo(HB125_tagSCPlayerHeroInfo netPack)
+ {
+ awakeRebirthCnt = netPack.AwakeRebirthCnt;
+ }
+
+ #endregion
+
+}
+
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/System/HeroUI/HeroUIManager.Reborn.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/System/HeroUI/HeroUIManager.Reborn.cs.meta
index e37f87e..9d5e3ee 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/System/HeroUI/HeroUIManager.Reborn.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: bf68f7332b968f14491059586ac32df5
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Main/System/HeroUI/HeroUIManager.cs b/Main/System/HeroUI/HeroUIManager.cs
index 5b6b3d6..8480413 100644
--- a/Main/System/HeroUI/HeroUIManager.cs
+++ b/Main/System/HeroUI/HeroUIManager.cs
@@ -5,7 +5,7 @@
using UnityEngine;
//姝﹀皢鐩稿叧鐣岄潰鐨勬搷浣滄暟鎹鐞�
-public class HeroUIManager : GameSystemManager<HeroUIManager>
+public partial class HeroUIManager : GameSystemManager<HeroUIManager>
{
#region 姝﹀皢鍒楄〃鐣岄潰
public List<string> heroSortList { get; private set; } = new List<string>(); //涓婇樀涓轰富绾跨殑 GUID鍒楄〃
@@ -14,7 +14,7 @@
public string selectHeroGuid; //閫変腑鐨勬灏唅d
#endregion
- public WaitHeroFuncResponse waitResponse; //璇锋眰姝﹀皢鍔熻兘
+ public WaitHeroFuncResponse waitResponse; //璇锋眰姝﹀皢鍔熻兘锛屼笌鏈嶅姟绔氦浜�
public override void Init()
@@ -43,6 +43,7 @@
heroOnTeamSortList.Clear();
awakeRebirthCnt = 0;
waitResponse = default;
+ heroCollectInfoDic.Clear();
}
private void OnHeroChangeEvent(HeroInfo hero)
@@ -67,7 +68,7 @@
}
if (hero.itemHero.guid != waitResponse.guid)
- {
+ {
return;
}
@@ -77,7 +78,7 @@
}
waitResponse = default;
-
+
}
#region 姝﹀皢UI甯哥敤鎺ュ彛
@@ -119,7 +120,7 @@
}
public bool IsLVMaxByBreakLevel(HeroInfo hero)
- {
+ {
return hero.heroLevel == GetMaxLVByBreakLV(hero.Quality, hero.breakLevel);
}
@@ -201,289 +202,11 @@
return heroA.heroId.CompareTo(heroB.heroId);
}
- #region 甯冮樀鐣岄潰
- public List<string> heroOnTeamSortList { get; private set; } = new List<string>(); //涓嶅悓涓婇樀鐨勫垪琛ㄦ帓搴�
- private TeamType m_SelectTeamType = TeamType.Story; //褰撳墠閫変腑鐨勬槸鍝釜闃靛, 甯冮樀鐩稿叧閫昏緫浣跨敤
- public TeamType selectTeamType
- {
- get { return m_SelectTeamType; }
- set
- {
- if (m_SelectTeamType == value)
- return;
- //涓婁竴涓樀瀹归渶瑕佹仮澶嶅埌鍘熺姸鎬�
- if (m_SelectTeamType != TeamType.None)
- {
- TeamManager.Instance.GetTeam(m_SelectTeamType).RestoreTeam();
- }
-
- m_SelectTeamType = value;
- }
- }
-
- public int selectTeamPosJob = 0; //甯冮樀鐣岄潰 绛涢�夎亴涓�
- public int selectTeamPosCountry = 0; //甯冮樀鐣岄潰 绛涢�夊浗瀹�
-
- public const float clickFlyPosTime = 0.5f; //鐐瑰嚮鍒楄〃涓殑姝﹀皢鍥炬爣鏃�, 椋炲叆甯冮樀鐨勬椂闂�
-
- public event Action<List<int>, int, Vector3> OnTeamPosChangeEvent; //甯冮樀鍙樺寲 浣嶇疆锛屽垪琛ㄧ殑璧烽绱㈠紩锛岃捣椋炲潗鏍�
-
-
- public void SortHeroOnTeamList()
- {
- heroOnTeamSortList = HeroManager.Instance.GetHeroGuidList(selectTeamPosJob, selectTeamPosCountry);
- heroOnTeamSortList.Sort(CmpHeroByTeamType);
- }
-
-
- int CmpHeroByTeamType(string guidA, string guidB)
- {
- HeroInfo heroA = HeroManager.Instance.GetHero(guidA);
- HeroInfo heroB = HeroManager.Instance.GetHero(guidB);
- if (heroA == null || heroB == null)
- {
- return 0;
- }
-
- // 鎺掑簭瑙勫垯锛氫笂闃�>姝﹀皢绛夌骇锛炵獊鐮寸瓑绾э紴姝﹀皢瑙夐啋闃剁骇锛炴灏嗗搧璐紴姝﹀皢鍚炲櫖鏄熺骇锛炴灏咺D
- bool isInTeamA = heroA.IsInTeamByTeamType(selectTeamType);
- bool isInTeamB = heroB.IsInTeamByTeamType(selectTeamType);
- if (isInTeamA != isInTeamB)
- {
- return isInTeamA ? -1 : 1;
- }
- if (heroA.heroLevel != heroB.heroLevel)
- {
- return heroA.heroLevel > heroB.heroLevel ? -1 : 1;
- }
- if (heroA.breakLevel != heroB.breakLevel)
- {
- return heroA.breakLevel > heroB.breakLevel ? -1 : 1;
- }
- if (heroA.awakeLevel != heroB.awakeLevel)
- {
- return heroA.awakeLevel > heroB.awakeLevel ? -1 : 1;
- }
- if (heroA.Quality != heroB.Quality)
- {
- return heroA.Quality > heroB.Quality ? -1 : 1;
- }
- if (heroA.heroStar != heroA.heroStar)
- {
- return heroA.heroStar > heroB.heroStar ? -1 : 1;
- }
-
- return heroA.heroId.CompareTo(heroB.heroId);
- }
-
-
-
-
- //涓婇樀闃熶紞涓悇涓浗瀹剁殑姝﹀皢鏁伴噺
- public Dictionary<HeroCountry, int> GetCountryHeroCountByTeamType(TeamType teamType)
- {
- Dictionary<HeroCountry, int> heroCountryCount = new Dictionary<HeroCountry, int>();
-
- var team = TeamManager.Instance.GetTeam(teamType);
- if (team != null)
- {
- for (int i = 0; i < team.tempHeroes.Length; i++)
- {
- if (team.tempHeroes[i] == null)
- continue;
- var country = (HeroCountry)team.tempHeroes[i].Country;
-
- if (!heroCountryCount.ContainsKey(country))
- {
- heroCountryCount.Add(country, 1);
- }
- else
- {
- heroCountryCount[country] = heroCountryCount[country] + 1;
- }
-
- }
-
- }
-
- return heroCountryCount;
- }
-
- //鑾峰緱涓婇樀涓灏嗘暟閲忔渶澶х殑鍥藉鍜屾暟閲�
- public Int2 GetMaxCountHeroCountry(TeamType teamType)
- {
- var countryCount = GetCountryHeroCountByTeamType(teamType);
- //鎵惧埌鏈�澶х殑鍥藉鍜屾暟閲�
- HeroCountry country = HeroCountry.None;
- int maxValue = 0;
- foreach (var data in countryCount)
- {
- if (data.Value > maxValue)
- {
- country = data.Key;
- maxValue = data.Value;
- }
- }
- return new Int2((int)country, maxValue);
- }
-
- //鍦ㄤ笉鍚岄〉绛句笅閫堿ttackType 0 鏀诲嚮闃靛 1 闃插畧闃靛
- public int GetSelectTeamTypeByAttackType(int AttackType)
- {
- if (selectTeamType == TeamType.Arena || selectTeamType == TeamType.ArenaDefense)
- {
- return AttackType == 0 ? (int)TeamType.Arena : (int)TeamType.ArenaDefense;
- }
-
-
- return (int)TeamType.Story;
- }
-
-
- public void NotifyOnTeamPosChangeEvent(List<int> posList, int flyIndex, Vector3 startPos)
- {
- OnTeamPosChangeEvent?.Invoke(posList, flyIndex, startPos);
- }
-
- //鎺ㄨ崘闃靛
- public List<string> SelectRecommend()
- {
- //鎺ㄨ崘闃靛鐨勭畻娉曢�昏緫
- //鑷姩閫夋嫨浼樺厛绾э細姝﹀皢绛夌骇锛炵獊鐮寸瓑绾э紴姝﹀皢瑙夐啋闃剁骇锛炴灏嗗搧璐紴姝﹀皢鍚炲櫖鏄熺骇锛炴灏咺D
- var tmpList = HeroManager.Instance.GetHeroGuidList();
- tmpList.Sort(CmpHeroRecommend);
-
-
- //鎺ㄨ崘鏈�澶�6涓紝瀛樺湪鐩稿悓heroid锛屽垯璺宠繃
- List<string> selectHeroList = new List<string>();
- List<int> selectHeroIDList = new List<int>();
- for (int i = 0; i < tmpList.Count; i++)
- {
- if (selectHeroList.Count >= TeamConst.MaxTeamHeroCount)
- break;
-
- string guid = tmpList[i];
- HeroInfo heroInfo = HeroManager.Instance.GetHero(guid);
- if (selectHeroIDList.Contains(heroInfo.heroId))
- continue;
- //濡傛灉閲嶅浜�,璺宠繃
- if (selectHeroList.Contains(guid))
- continue;
- selectHeroList.Add(guid);
- selectHeroIDList.Add(heroInfo.heroId);
- }
- return selectHeroList;
- }
-
-
- int CmpHeroRecommend(string guidA, string guidB)
- {
- HeroInfo heroA = HeroManager.Instance.GetHero(guidA);
- HeroInfo heroB = HeroManager.Instance.GetHero(guidB);
- if (heroA == null || heroB == null)
- {
- return 0;
- }
-
- // 鎺掑簭瑙勫垯锛氭灏嗙瓑绾э紴绐佺牬绛夌骇锛炴灏嗚閱掗樁绾э紴姝﹀皢鍝佽川锛炴灏嗗悶鍣槦绾э紴姝﹀皢ID
- if (heroA.heroLevel != heroB.heroLevel)
- {
- return heroA.heroLevel > heroB.heroLevel ? -1 : 1;
- }
- if (heroA.breakLevel != heroB.breakLevel)
- {
- return heroA.breakLevel > heroB.breakLevel ? -1 : 1;
- }
- if (heroA.awakeLevel != heroB.awakeLevel)
- {
- return heroA.awakeLevel > heroB.awakeLevel ? -1 : 1;
- }
- if (heroA.Quality != heroB.Quality)
- {
- return heroA.Quality > heroB.Quality ? -1 : 1;
- }
- if (heroA.heroStar != heroA.heroStar)
- {
- return heroA.heroStar > heroB.heroStar ? -1 : 1;
- }
-
- return heroA.heroId.CompareTo(heroB.heroId);
- }
-
-
- #endregion
-
- #region 閲嶇敓 閬f暎
- public int awakeRebirthCnt { get; private set; }
- public int payBackMoneyType;
- public int payBackMoney;
- public Dictionary<int, ulong> GetHeroLVPayBack(int quality, int lv)
- {
- //姹囨�昏繑杩樻�绘暟閲�
- Dictionary<int, ulong> itemCounDic = new Dictionary<int, ulong>();
- for (int i = 1; i < lv; i++)
- {
- var config = HeroQualityLVConfig.GetQualityLVConfig(quality, lv);
- var itemID = config.UPCostItem[0];
- var count = (ulong)config.UPCostItem[1];
- if (!itemCounDic.ContainsKey(itemID))
- {
- itemCounDic[itemID] = count;
- }
- itemCounDic[itemID] = itemCounDic[itemID] + count;
- }
-
- return itemCounDic;
- }
-
-
- public Dictionary<int, ulong> GetHeroBreakPayBack(int quality, int lv)
- {
- //姹囨�昏繑杩樻�绘暟閲�
- Dictionary<int, ulong> itemCounDic = new Dictionary<int, ulong>();
- for (int i = 0; i < lv; i++)
- {
- var config = HeroQualityBreakConfig.GetQualityBreakConfig(quality, lv);
- var itemID = config.UPCostItem[0];
- var count = (ulong)config.UPCostItem[1];
- if (!itemCounDic.ContainsKey(itemID))
- {
- itemCounDic[itemID] = count;
- }
- itemCounDic[itemID] = itemCounDic[itemID] + count;
- }
-
- return itemCounDic;
-
-
- }
-
- public Dictionary<int, ulong> GetHeroQualityAwakePayBack(int quality, int lv)
- {
- //姹囨�昏繑杩樻�绘暟閲�
- Dictionary<int, ulong> itemCounDic = new Dictionary<int, ulong>();
- for (int i = 0; i < lv; i++)
- {
- var config = HeroQualityAwakeConfig.GetQualityAwakeConfig(quality, lv);
- var itemID = config.UPCostItem[0];
- var count = (ulong)config.UPCostItem[1];
- if (!itemCounDic.ContainsKey(itemID))
- {
- itemCounDic[itemID] = count;
- }
- itemCounDic[itemID] = itemCounDic[itemID] + count;
- }
-
- return itemCounDic;
- }
-
- public void UpdateHeroInfo(HB125_tagSCPlayerHeroInfo netPack)
- {
- awakeRebirthCnt = netPack.AwakeRebirthCnt;
- }
- #endregion
+
+
+
}
public struct WaitHeroFuncResponse
diff --git a/Main/System/KnapSack/Logic/ItemLogicUtility.cs b/Main/System/KnapSack/Logic/ItemLogicUtility.cs
index 750cbf2..104a518 100644
--- a/Main/System/KnapSack/Logic/ItemLogicUtility.cs
+++ b/Main/System/KnapSack/Logic/ItemLogicUtility.cs
@@ -262,26 +262,7 @@
#endregion
- private bool CheckIsExtendGrid(int itemId)
- {
- SinglePack singlePack = packModel.GetSinglePack(PackType.Item);
- if (singlePack == null) return false;
- int startLockIndex = singlePack.unlockedGridCount - PackManager.Instance.initBagGridCount;
- FuncConfigConfig _tagFuncModel = FuncConfigConfig.Get("OpenBagItem");
- var haveCount = packModel.GetItemCountByID(PackType.Item, itemId);
- Equation.Instance.Clear();
- Equation.Instance.AddKeyValue("index", startLockIndex + 1);
- int needTool = Equation.Instance.Eval<int>(_tagFuncModel.Numerical2);
- if (haveCount >= (ulong)needTool)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
/// <summary>
/// <param name="packType 鑳屽寘绫诲瀷"></param>
diff --git a/Main/System/Main/FightPowerManager.cs b/Main/System/Main/FightPowerManager.cs
index dfc2a0f..bd3233f 100644
--- a/Main/System/Main/FightPowerManager.cs
+++ b/Main/System/Main/FightPowerManager.cs
@@ -1,236 +1,479 @@
-锘縰sing System.Collections;
+锘縰sing System;
+using System.Collections;
using System.Collections.Generic;
+using System.Linq;
using UnityEngine;
+using LitJson;
+using Spine;
-
+//锛佸崟鑻遍泟鏌ョ湅鎴樺姏 鍙畻鑷繁鐨勪笂闃靛睘鎬� 涓嶇畻缇佺粖 鎬讳笂闃靛睘鎬� 鍏夌幆
+// 鎴樺姏鐨勮绠楁柟寮�
+// 鍏堢畻涓婇樀鐨勫崟姝﹀皢鎴樺姏鎸夊叕寮忎竴涓�绠楀嚭鍚勪釜灞炴�э紙鍩虹/鎴樻枟锛夛紝鍐嶆妸绠楀嚭鏉ョ殑鍚勪釜灞炴�т唬鍏ュ埌鎴樺姏鍏紡
+// 鎵�鏈夋灏嗘垬鍔涘姞璧锋潵 + 鎶�鑳芥垬鍔涙眹鎬伙紙鍏紡锛夊氨鏄暣涓彿鐨勬垬鍔�
public class FightPowerManager : Singleton<FightPowerManager>
{
- string propertyFormula;
+ public string propertyFormula;
+ public string fightPropertyFormula;
+ public string fightPowerFormula;
+ public string skillFightPowerFormula;
+
+ Dictionary<string, double> propertyVariables = new Dictionary<string, double>();
+ Dictionary<string, double> fightPowerVariables = new Dictionary<string, double>(); //鎬绘垬鍔涗腑鐨勫崟姝﹀皢鎴樺姏
+
public FightPowerManager()
{
+ // 鏁板��1锛氬熀纭�涓夌淮灞炴�ц绠楀叕寮�
+ // 鏁板��2锛氭垬鏂楀睘鎬�/鎴樻枟鎶楁��/鐗规畩灞炴�ц绠楀叕寮�
+ // 鏁板��3锛氬睘鎬ф垬鍔涜绠楀叕寮忥紝璁$畻鍙傛暟璇﹁ S.灞炴�ф潯鐩厤缃�
var config = FuncConfigConfig.Get("HeroAttrFormula");
propertyFormula = config.Numerical1;
+ fightPropertyFormula = config.Numerical2;
+ fightPowerFormula = config.Numerical3;
+ skillFightPowerFormula = config.Numerical4;
}
+ #region 鍒濆鍖栨垬鍔涜绠楃殑淇℃伅
+ TeamType teamTypeCalc = TeamType.Story; //涓嶅悓闃靛鎴樺姏涓嶅悓
+ bool isPreviewTeamPower; //棰勮闃靛锛堥槦浼嶏級鎴樺姏
+ int dropIndexCalc = -1; //鎺夎惤瑁呭鍦ㄩ樀瀹圭殑绱㈠紩锛岀敤浜庨瑙堟垬鍔涘姣�
- //瑁呭鎴樺姏涓烘渶缁堟�绘垬鍔涚殑缁撴灉姣旓紙鎻愬崌鏁翠釜瑙掕壊鎬绘垬鍔涳級
- public int CalculatePower(int level)
+ //璁$畻闃靛鎴樺姏锛岃澶囧姣旂瓑鎯呭喌闇�瑕佷唬鍏�
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="teamType">闃靛绫诲瀷</param>
+ /// <param name="dropindex">鎺夎惤瑁呭鐨勭储寮曪紝-1浠h〃涓嶆浛鎹㈣绠�</param>
+ /// <param name="ispreview">棰勮闃靛鎴樺姏</param>
+ public void InitFightPowerParam(TeamType teamType = TeamType.Story, int dropindex = -1, bool ispreview = false)
{
- // Equation.Instance.Clear();
- // Equation.Instance.AddKeyValue("equipScoreTotal", CountEquipScore(level));
- // var power = Equation.Instance.Eval<int>(scoreFormula);
+ teamTypeCalc = teamType;
+ isPreviewTeamPower = ispreview;
- // var propertyContainer = new Properties();
-
- // Equation.Instance.Clear();
- // var keys = propertyContainer.keys;
- // for (int i = 0; i < keys.Count; i++)
- // {
- // var id = keys[i];
- // var value = propertyContainer[id];
- // var config = PlayerPropertyConfig.Get(id);
- // Equation.Instance.AddKeyValue(config.Parameter, value);
- // }
-
- // var propertyPower = Equation.Instance.Eval<int>(propertyFormula);
- // power += propertyPower;
-
-
- return 0;
+ dropIndexCalc = dropindex;
+#if UNITY_EDITOR
+ Debug.Log("鎴樺姏锛氬垵濮嬪寲鍙傛暟 dropIndex锛�" + dropIndexCalc + " 闃靛瀷锛�" + teamTypeCalc + " ispreview:" + ispreview);
+#endif
}
+ #endregion
- //鍜岃韩涓婅澶囧姣�
- public long GetFightPowerChange(ItemModel item)
+
+
+ #region 鍏堣绠楁墍鏈夊姛鑳界殑姹囨�诲睘鎬�
+
+ //鍔熻兘灞炴�� 绫诲瀷锛氬��
+ public Dictionary<int, int> lvAttrs = new Dictionary<int, int>(); //绛夌骇灞炴��
+
+ //鍒嗗紑瀛樺偍棰勮鍜� 鐪熷疄灞炴��
+ public Dictionary<int, int> equipAttrs = new Dictionary<int, int>(); //瑁呭灞炴��
+ public Dictionary<string, int> lineUpPerDict = new Dictionary<string, int>(); //闃靛灞炴�у姞鎴�
+ public Dictionary<int, int> countryAttrs = new Dictionary<int, int>(); //闃靛鍥藉锛堝厜鐜級灞炴��
+
+ //绛夌骇灞炴��
+ void RefreshLVAttrs()
{
- return 0;
- }
-
-
-
-
- class Properties
- {
- Dictionary<int, int> tables = new Dictionary<int, int>();
-
- public List<int> keys { get { return new List<int>(tables.Keys); } }
-
- public int this[int id] { get { return tables[id]; } }
-
- public void Add(int id, int value)
+ lvAttrs.Clear();
+ var playerLVConfig = PlayerLVConfig.Get(PlayerDatas.Instance.baseData.LV);
+ foreach (var attrType in PlayerPropertyConfig.baseAttrs)
{
- if (id == 7)
+ lvAttrs[attrType] = GetPlayerLVValue(playerLVConfig, attrType);
+ }
+#if UNITY_EDITOR
+ Debug.Log("鎴樺姏锛氱瓑绾у睘鎬� " + JsonMapper.ToJson(lvAttrs));
+#endif
+
+ }
+
+ public int GetPlayerLVValue(PlayerLVConfig config, int type)
+ {
+ if (type == 6)
+ {
+ return config.Atk;
+ }
+ else if (type == 7)
+ {
+ return config.Def;
+ }
+ else if (type == 8)
+ {
+ return config.MaxHP;
+ }
+ return 0;
+ }
+
+ //瑁呭灞炴��:韬笂瑁呭姹囨��
+ void RefrehEquipAttrs()
+ {
+ equipAttrs.Clear(); //韬笂瑁呭灞炴�ч噸缃�
+ for (int i = 0; i < EquipModel.TotleEquip; i++)
+ {
+ var equip = EquipModel.Instance.GetEquip(i);
+ if (dropIndexCalc != -1)
{
- Add(67, value);
- Add(68, value);
+ var dropEquip = PackManager.Instance.GetItemByIndex(PackType.DropItem, dropIndexCalc);
+ if (dropEquip.config.EquipPlace - 1 == i)
+ {
+ equip = dropEquip; //鏇挎崲璁$畻鎬绘垬鍔�
+ }
+ }
+ if (equip == null)
+ {
+ continue;
+ }
+ var baseIDAttrs = EquipModel.Instance.GetEquipBaseAttrs(equip);
+ var baseVauleAttrs = EquipModel.Instance.GetEquipBaseValues(equip);
+ if (baseIDAttrs != null)
+ {
+ for (int j = 0; j < baseIDAttrs.Count; j++)
+ {
+ if (!equipAttrs.ContainsKey(baseIDAttrs[j]))
+ {
+ equipAttrs[baseIDAttrs[j]] = baseVauleAttrs[j];
+ }
+ else
+ {
+ equipAttrs[baseIDAttrs[j]] += baseVauleAttrs[j];
+ }
+ }
+ }
+
+ var fightIDAttrs = EquipModel.Instance.GetEquipFightAttrs(equip);
+ var fightValueAttrs = EquipModel.Instance.GetEquipFightValues(equip);
+ if (fightIDAttrs != null)
+ {
+ for (int j = 0; j < fightIDAttrs.Count; j++)
+ {
+ if (!equipAttrs.ContainsKey(fightIDAttrs[j]))
+ {
+ equipAttrs[fightIDAttrs[j]] = fightValueAttrs[j];
+ }
+ else
+ {
+ equipAttrs[fightIDAttrs[j]] += fightValueAttrs[j];
+ }
+ }
+ }
+ }
+
+#if UNITY_EDITOR
+ Debug.Log("鎴樺姏锛氳澶囧睘鎬� " + JsonMapper.ToJson(equipAttrs));
+#endif
+ }
+
+ // 璁$畻闃熶紞涓笂闃电殑鎵�鏈夋灏嗙殑涓婇樀灞炴�� 鍜� 鍏夌幆
+ void RefreshTeamAttrs()
+ {
+ //闃靛灞炴��
+ // 闃靛锛氭墍鏈夋灏嗕笂闃靛睘鎬�
+ lineUpPerDict = HeroUIManager.Instance.GetLineupPer(teamTypeCalc, isPreviewTeamPower);
+
+#if UNITY_EDITOR
+ Debug.Log("鎴樺姏锛氫笂闃靛睘鎬� " + JsonMapper.ToJson(lineUpPerDict));
+#endif
+ // 闃靛锛氬浗瀹讹紙鍏夌幆锛夊睘鎬�
+ countryAttrs = HeroUIManager.Instance.GetCountryAttrs(teamTypeCalc, isPreviewTeamPower);
+#if UNITY_EDITOR
+ Debug.Log("鎴樺姏锛氬浗瀹讹紙鍏夌幆锛夊睘鎬� " + JsonMapper.ToJson(countryAttrs));
+#endif
+ }
+
+ #endregion
+
+ //鍗曞睘鎬у叕寮忓垎鍩虹涓夌淮鍜屾垬鏂楀睘鎬�
+ // 銆愪富鍏睘鎬с��
+ // 绛夌骇灞炴�� lvValue
+ // 瑁呭灞炴�� equipValue
+ // 鍥鹃壌灞炴�� bookValue 銆� bookPer
+
+ // 銆愰樀瀹瑰睘鎬с�� - 璇ラ樀瀹规墍鏈夋灏嗘湁鏁�
+ // 鍒濆鍔犳垚 lineupInitAddPer
+ // 鍗囩骇鍔犳垚 lineupLVAddPer
+ // 绐佺牬鍔犳垚 lineupBreakLVAddPer
+ // 鍚炲櫖鍔犳垚 lineupStarAddPer
+ // 闃靛鍏夌幆 lineupHaloValue 銆� lineupHaloPer
+
+ // 銆愭灏嗗睘鎬с��
+ // 缁ф壙姣斾緥 inheritPer
+ // 鑷韩灞炴�� heroSelfValue 銆� heroSelfPer
+ // 鍚炲櫖灞炴�� starTalentValue 銆� starTalentPer
+ // 绐佺牬灞炴�� breakLVValue 銆� breakLVPer
+ // 瑙夐啋灞炴�� awakeTalentValue 銆� awakeTalentPer
+ // 缇佺粖灞炴�� fetterValue 銆� fetterPer
+
+ #region 灞炴�у叕寮�
+ // 鍗曞熀纭�灞炴�ц绠�
+ public double GetPropertyVaule(int attrType, HeroInfo hero, string formula)
+ {
+ propertyVariables.Clear();
+ propertyVariables["lvValue"] = lvAttrs.ContainsKey(attrType) ? lvAttrs[attrType] : 0;
+ propertyVariables["equipValue"] = equipAttrs.ContainsKey(attrType) ? equipAttrs[attrType] : 0;
+ propertyVariables["bookValue"] = 0;
+ propertyVariables["bookPer"] = GetBookPer(attrType) / 10000.0f;
+
+ //锛侊紒锛佸崟姝﹀皢鎴樺姏棰勮鐨勮瘽闇�瑕佹帓闄ら槦浼嶅奖鍝嶆垬鍔涳紝鍙畻姝﹀皢鑷韩鐨勪笂闃靛睘鎬�
+ propertyVariables["lineupInitAddPer"] = GetLineUpPer(attrType, "lineupInitAddPer") / 10000.0f;
+ propertyVariables["lineupLVAddPer"] = GetLineUpPer(attrType, "lineupLVAddPer") / 10000.0f;
+ propertyVariables["lineupBreakLVAddPer"] = GetLineUpPer(attrType, "lineupBreakLVAddPer") / 10000.0f;
+ propertyVariables["lineupStarAddPer"] = GetLineUpPer(attrType, "lineupStarAddPer") / 10000.0f;
+
+ //闃靛鍏夌幆 涓夊洿鐧惧垎姣斿姞鎴�
+ propertyVariables["lineupHaloValue"] = countryAttrs.ContainsKey(attrType) ? countryAttrs[attrType] : 0;
+ propertyVariables["lineupHaloPer"] = GetCountryPer(attrType) / 10000.0f;
+
+
+ //姝﹀皢灞炴��
+ propertyVariables["inheritPer"] = hero.GetInheritAttrPer(attrType) / 10000.0f;
+ propertyVariables["heroSelfValue"] = hero.GetSelfAddValue(attrType);
+ propertyVariables["heroSelfPer"] = hero.GetSelfAddPer(attrType) / 10000.0f;
+ propertyVariables["starTalentValue"] = hero.GetTalentAttrValue(attrType);
+ propertyVariables["starTalentPer"] = hero.GetTalentAttrPer(attrType) / 10000.0f;
+ propertyVariables["breakLVValue"] = hero.GetBreakAttrValue(attrType);
+ propertyVariables["breakLVPer"] = hero.GetBreakAttrPer(attrType) / 10000.0f;
+ propertyVariables["awakeTalentValue"] = hero.GetAwakeAttrValue(attrType);
+ propertyVariables["awakeTalentPer"] = hero.GetAwakeAttrPer(attrType) / 10000.0f;
+ propertyVariables["fetterValue"] = hero.GetFetterAttrValue(attrType);
+ propertyVariables["fetterPer"] = hero.GetFetterAttrPer(attrType) / 10000.0f;
+
+#if UNITY_EDITOR
+ //鎺掗櫎鍊间负0鐨勫睘鎬ц緭鍑�
+ var tmpPropertyVariables = propertyVariables.Where(x => x.Value > 0).ToDictionary(x => x.Key, x => x.Value);
+ if (!tmpPropertyVariables.IsNullOrEmpty())
+ propertyStrForDebug += $"灞炴�D {attrType} - {JsonMapper.ToJson(tmpPropertyVariables)}";
+#endif
+ return JaceCalculator.Calculate(formula, propertyVariables);
+ }
+
+
+ int GetLineUpPer(int attrType, string key)
+ {
+ if (!PlayerPropertyConfig.baseAttrs.Contains(attrType))
+ {
+ return 0;
+ }
+
+ return lineUpPerDict[key];
+ }
+
+ int GetBookPer(int attrType)
+ {
+ if (!PlayerPropertyConfig.baseAttrs.Contains(attrType))
+ {
+ return 0;
+ }
+ return HeroUIManager.Instance.bookPer;
+ }
+
+ int GetCountryPer(int attrType)
+ {
+ if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrType))
+ {
+ var pertype = PlayerPropertyConfig.baseAttr2perDict[attrType];
+ return countryAttrs.ContainsKey(pertype) ? countryAttrs[pertype] : 0;
+ }
+
+ return 0;
+ }
+
+
+
+ #endregion
+
+
+ #region 璁$畻鎴樺姏
+ //濡傛灉鏈嶅姟绔垬鍔涜绠楁湁鍘嬪姏锛屽彲鏀规垚鍏抽敭鐐圭粨绠楋紙濡傚悓姝ユ帓琛屾璺ㄦ湇绛夛級锛岃〃鐜扮敱瀹㈡埛绔嚜宸辫绠�
+ //瑁呭鎴樺姏涓烘渶缁堟�绘垬鍔涚殑缁撴灉姣旓紙鎻愬崌鏁翠釜瑙掕壊鎬绘垬鍔涳級
+
+ //璁$畻鎬绘垬鍔涗腑鐨勬灏嗘垬鍔涳紝鍑犱釜姝﹀皢鍔犺捣鏉ュ氨鏄�绘垬鍔涳紝鍏朵粬鍔熻兘灞炴�ц绠楀簲璇ユ兜鐩栧湪鑻遍泟閲�
+ public long CalculatePower()
+ {
+#if UNITY_EDITOR
+ Debug.Log("鎴樺姏锛氬紑濮嬭绠�");
+#endif
+ // --- 鍏堣绠楁墍鏈夊姛鑳界殑姹囨�诲睘鎬� ---
+ RefreshLVAttrs();
+ RefrehEquipAttrs();
+ RefreshTeamAttrs();
+
+
+ // --- 绠楀崟姝﹀皢鍔熻兘灞炴�ф垬鍔� 鍚庣浉鍔�---
+ long fightPower = 0;
+ var team = TeamManager.Instance.GetTeam(teamTypeCalc);
+ if (team == null)
+ {
+ return fightPower;
+ }
+ TeamHero[] teamHeroes = isPreviewTeamPower ? team.tempHeroes : team.serverHeroes;
+ foreach (var hero in teamHeroes)
+ {
+ if (hero == null)
+ {
+ continue;
+ }
+ HeroInfo heroInfo = HeroManager.Instance.GetHero(hero.guid);
+ if (heroInfo == null)
+ {
+ continue;
+ }
+
+ fightPower += CalculateTeamHeroPower(heroInfo);
+
+ }
+
+#if UNITY_EDITOR
+ Debug.Log("鎴樺姏锛氳绠楀畬姣� " + fightPower);
+#endif
+ return fightPower;
+ }
+
+#if UNITY_EDITOR
+ string propertyStrForDebug = "";
+#endif
+
+ //璁$畻闃靛涓灏嗘垬鍔�
+ public long CalculateTeamHeroPower(HeroInfo hero)
+ {
+
+ fightPowerVariables.Clear();
+ hero.RefreshFetterAttrsWhenCalcPower(teamTypeCalc); //缇佺粖灞炴�ц瀹炴椂绠�
+
+#if UNITY_EDITOR
+ propertyStrForDebug = "";
+#endif
+ foreach (var config in PlayerPropertyConfig.GetValues())
+ {
+ if (config.showType < 1 || config.showType > 4)
+ {
+ continue;
+ }
+ if (config.showType == 1)
+ {
+ fightPowerVariables[config.Parameter] = (ulong)GetPropertyVaule(config.ID, hero, propertyFormula);
}
else
{
- if (tables.ContainsKey(id))
- {
- tables[id] = tables[id] + value;
- }
- else
- {
- tables[id] = value;
- }
+ fightPowerVariables[config.Parameter] = (ulong)GetPropertyVaule(config.ID, hero, fightPropertyFormula);
}
}
- public void AddRange(List<int> ids, List<int> values)
- {
- if (ids.IsNullOrEmpty() || values.IsNullOrEmpty())
- {
- return;
- }
+#if UNITY_EDITOR
+ Debug.Log($"鎴樺姏锛氭灏咺D {hero.heroId} 灞炴�т俊鎭� {propertyStrForDebug}");
+#endif
- var count = Mathf.Min(ids.Count, values.Count);
- for (int i = 0; i < count; i++)
- {
- Add(ids[i], values[i]);
- }
- }
+ //灞炴�х郴鏁版牴鎹畼鑱岀瓑绾х殑鍔犳垚
+ var fightPowerRatioConfig = FightPowerRatioConfig.Get(PlayerDatas.Instance.baseData.realmLevel);
+ fightPowerVariables["AtkRatio"] = fightPowerRatioConfig.AtkRatio;
+ fightPowerVariables["MaxHPRatio"] = fightPowerRatioConfig.MaxHPRatio;
+ fightPowerVariables["DefRatio"] = fightPowerRatioConfig.DefRatio;
+ fightPowerVariables["StunRateRatio"] = fightPowerRatioConfig.StunRateRatio;
+ fightPowerVariables["SuperHitRateRatio"] = fightPowerRatioConfig.SuperHitRateRatio;
+ fightPowerVariables["ComboRateRatio"] = fightPowerRatioConfig.ComboRateRatio;
+ fightPowerVariables["MissRateRatio"] = fightPowerRatioConfig.MissRateRatio;
+ fightPowerVariables["ParryRateRatio"] = fightPowerRatioConfig.ParryRateRatio;
+ fightPowerVariables["SuckHPPerRatio"] = fightPowerRatioConfig.SuckHPPerRatio;
+ fightPowerVariables["StunRateDefRatio"] = fightPowerRatioConfig.StunRateDefRatio;
+ fightPowerVariables["SuperHitRateDefRatio"] = fightPowerRatioConfig.SuperHitRateDefRatio;
+ fightPowerVariables["ComboRateDefRatio"] = fightPowerRatioConfig.ComboRateDefRatio;
+ fightPowerVariables["MissRateDefRatio"] = fightPowerRatioConfig.MissRateDefRatio;
+ fightPowerVariables["ParryRateDefRatio"] = fightPowerRatioConfig.ParryRateDefRatio;
+ fightPowerVariables["SuckHPPerDefRatio"] = fightPowerRatioConfig.SuckHPPerDefRatio;
+ fightPowerVariables["NormalSkillPerRatio"] = fightPowerRatioConfig.NormalSkillPerRatio;
+ fightPowerVariables["NormalSkillPerDefRatio"] = fightPowerRatioConfig.NormalSkillPerDefRatio;
+ fightPowerVariables["AngerSkillPerRatio"] = fightPowerRatioConfig.AngerSkillPerRatio;
+ fightPowerVariables["AngerSkillPerDefRatio"] = fightPowerRatioConfig.AngerSkillPerDefRatio;
+ fightPowerVariables["SuperDamPerRatio"] = fightPowerRatioConfig.SuperDamPerRatio;
+ fightPowerVariables["SuperDamPerDefRatio"] = fightPowerRatioConfig.SuperDamPerDefRatio;
+ fightPowerVariables["ShieldPerRatio"] = fightPowerRatioConfig.ShieldPerRatio;
+ fightPowerVariables["ShieldPerDefRatio"] = fightPowerRatioConfig.ShieldPerDefRatio;
+
+
+ long fightPower = (long)JaceCalculator.Calculate(fightPowerFormula, fightPowerVariables);
+#if UNITY_EDITOR
+ //鎺掗櫎鍊间负0鐨勫睘鎬ц緭鍑�
+ var tmpFightPowerVariables = fightPowerVariables.Where(x => x.Value > 0).ToDictionary(x => x.Key, x => x.Value);
+ if (!tmpFightPowerVariables.IsNullOrEmpty())
+ Debug.Log($"鎴樺姏锛氭灏咺D {hero.heroId} 灞炴�ф垬鍔� {fightPower} 灞炴�ф垬鍔涘弬鏁� {JsonMapper.ToJson(tmpFightPowerVariables)}");
+#endif
+
+ //鍔犱笂鎶�鑳芥垬鍔�
+ fightPowerVariables.Clear();
+ fightPowerVariables["PlayerLV"] = PlayerDatas.Instance.baseData.LV;
+ fightPowerVariables["OfficialLV"] = PlayerDatas.Instance.baseData.realmLevel;
+ fightPowerVariables["SkillPower"] = hero.GetSkillsFightPower();
+
+ long skillPower = (long)JaceCalculator.Calculate(skillFightPowerFormula, fightPowerVariables);
+
+#if UNITY_EDITOR
+ Debug.Log($"鎴樺姏锛氭灏咺D {hero.heroId} 鎶�鑳芥垬鍔� {skillPower} 鎶�鑳藉弬鏁� {JsonMapper.ToJson(fightPowerVariables)}");
+
+ Debug.Log($"鎴樺姏锛氭灏咺D {hero.heroId} 鎬绘垬鍔� {fightPower + skillPower}");
+#endif
+
+ return fightPower + skillPower;
}
+ /// <summary>
+ /// 鍜岃韩涓婅澶囧姣斿樊
+ /// </summary>
+ /// <param name="item">鍦版澘瑁呭</param>
+ /// <returns></returns>
+ public long GetFightPowerChange(ItemModel item)
+ {
+ InitFightPowerParam();
+ var fightPower = CalculatePower();
- #region 璁$畻鎴樻枟鍔�
- public static readonly string FightPowerFormula = "FightpowerFormula";
+ InitFightPowerParam(dropindex: item.gridIndex);
+ var tmpFightPower = CalculatePower();
+ return tmpFightPower - fightPower;
+ }
- // public static int GetFightPower(Dictionary<int, int> _propertyDict)
- // {
- // Equation.Instance.Clear();
- // if (_propertyDict == null || _propertyDict.Count == 0)
- // {
- // return 0;
- // }
- // foreach (var _key in _propertyDict.Keys)
- // {
- // PlayerPropertyConfig cfg = PlayerPropertyConfig.Get(_key);
- // if (cfg != null)
- // {
- // if (_key == 7)
- // {
- // Equation.Instance.AddKeyValue("MinAtk", _propertyDict[_key]);
- // Equation.Instance.AddKeyValue("MaxAtk", _propertyDict[_key]);
- // }
- // else if (_key == 24)
- // {
- // Equation.Instance.AddKeyValue("PetMinAtk", _propertyDict[_key]);
- // Equation.Instance.AddKeyValue("PetMaxAtk", _propertyDict[_key]);
- // }
- // else
- // {
- // ulong attrValue = (ulong)_propertyDict[_key];
- // var fightParm = GetFightPowerParmByAttrId(_key);
- // if (_key == 11)
- // {
- // var playerLv = PlayerDatas.Instance.baseData.LV;
- // var paramConfig = FightPowerParamConfig.Get(playerLv);
- // Equation.Instance.AddKeyValue("AtkSpeedParameter", paramConfig.AtkSpeedParameter);
- // }
- // else
- // {
- // if (fightParm != 0)
- // {
- // attrValue = attrValue * (ulong)fightParm;
- // }
- // }
- // Equation.Instance.AddKeyValue(cfg.Parameter, attrValue);
- // }
- // }
+ // 鍗曡嫳闆勬煡鐪嬫垬鍔�
+ // 1. 涓婇樀鑻遍泟鏄剧ず锛屽湪涓荤嚎闃靛涓嬬殑鎴樺姏
+ // 2. 闈炰笂闃垫垨鍏朵粬涓婇樀闃靛锛氫笂闃典笉瓒�6涓汉鐨勶紝鎸夊鍔犵殑鏂瑰紡鐨勮绠楋紱浜烘暟婊$殑鎯呭喌涓嬫寜鏇挎崲6鍙蜂綅璁$畻
+ public long GetHeroFightPower(HeroInfo heroInfo)
+ {
+ bool ispreview = false;
+ var team = TeamManager.Instance.GetTeam(TeamType.Story);
+ if (!team.HasHero(heroInfo.itemHero.guid))
+ {
+ //鏇挎崲涓婇樀浣嶇疆
+ ispreview = true;
+ var index = team.GetEmptyPosition();
+ if (index < 0)
+ {
+ team.AddHero(heroInfo, 5);
+ }
+ else
+ {
+ team.AddHero(heroInfo, index);
+ }
+ }
- // }
- // FuncConfigConfig funcCfg = FuncConfigConfig.Get(FightPowerFormula);
- // return Equation.Instance.Eval<int>(funcCfg.Numerical1);
- // }
+ InitFightPowerParam(ispreview: ispreview);
+ RefreshLVAttrs();
+ RefrehEquipAttrs();
+ RefreshTeamAttrs();
- // public static int GetFightPowerParmByAttrId(int attrId)
- // {
- // int playerLv = PlayerDatas.Instance.baseData.LV;
- // FightPowerParamConfig paramConfig = FightPowerParamConfig.Get(playerLv);
- // PlayerPropertyConfig cfg = PlayerPropertyConfig.Get(attrId);
- // if (paramConfig == null || cfg == null) return 0;
+ var fightPower = CalculateTeamHeroPower(heroInfo);
- // switch (cfg.Parameter)
- // {
- // case "Hit":
- // return paramConfig.Hit;
- // case "Miss":
- // return paramConfig.Miss;
- // case "IgnoreDefRate":
- // return paramConfig.IgnoreDefRate;
- // case "DamChanceDef":
- // return paramConfig.DamChanceDef;
- // case "FaintRate":
- // return paramConfig.FaintRate;
- // case "LuckyHitRateReduce":
- // return paramConfig.LuckyHitRateReduce;
- // case "SkillAtkRate":
- // return paramConfig.SkillAtkRate;
- // case "SkillAtkRateReduce":
- // return paramConfig.SkillAtkRateReduce;
- // case "DamagePerPVP":
- // return paramConfig.DamagePerPVP;
- // case "DamagePerPVPReduce":
- // return paramConfig.DamagePerPVPReduce;
- // case "DamBackPer":
- // return paramConfig.DamBackPer;
- // case "IgnoreDefRateReduce":
- // return paramConfig.IgnoreDefRateReduce;
- // case "FaintDefRate":
- // return paramConfig.FaintDefRate;
- // case "AtkSpeedParameter":
- // return paramConfig.AtkSpeedParameter;
- // case "JobAHurtAddPer":
- // return paramConfig.JobAHurtAddPer;
- // case "JobBHurtAddPer":
- // return paramConfig.JobBHurtAddPer;
- // case "JobCHurtAddPer":
- // return paramConfig.JobCHurtAddPer;
- // case "JobAAtkReducePer":
- // return paramConfig.JobAAtkReducePer;
- // case "JobBAtkReducePer":
- // return paramConfig.JobBAtkReducePer;
- // case "JobCAtkReducePer":
- // return paramConfig.JobCAtkReducePer;
- // case "SuperHitRate":
- // return paramConfig.SuperHitRate;
- // case "LuckyHitRate":
- // return paramConfig.LuckyHitRate;
- // case "SuperHitRateReduce":
- // return paramConfig.SuperHitRateReduce;
- // case "FinalHurtPer":
- // return paramConfig.FinalHurtPer;
- // case "FinalHurtReducePer":
- // return paramConfig.FinalHurtReducePer;
- // case "NPCHurtAddPer":
- // return paramConfig.NPCHurtAddPer;
- // case "NormalHurtPer":
- // return paramConfig.NormalHurtPer;
- // case "FabaoHurtPer":
- // return paramConfig.FabaoHurtPer;
- // case "AffairSpeedPer":
- // return paramConfig.AffairSpeedPer;
- // case "FamilyBossHurtPer":
- // return paramConfig.FamilyBossHurtPer;
- // case "FamilyWarHPPer":
- // return paramConfig.FamilyWarHPPer;
- // case "FamilyWarAtkPer":
- // return paramConfig.FamilyWarAtkPer;
- // case "FamilySitExpPer":
- // return paramConfig.FamilySitExpPer;
- // case "BossFinalHurtPer":
- // return paramConfig.BossFinalHurtPer;
- // }
+ //璁$畻瀹屾仮澶嶉槦浼�
+ if (ispreview)
+ team.RestoreTeam();
+ return fightPower;
+ }
- // return 0;
- // }
+ //鏌ョ湅闃靛鎴樺姏
+ public long GetTeamFightPower(TeamType team, bool isPreview)
+ {
+ InitFightPowerParam(team, -1, isPreview);
+ return CalculatePower();
+ }
#endregion
+
}
diff --git a/Main/System/OpenServerActivity/OperationTimeHepler.cs b/Main/System/OpenServerActivity/OperationTimeHepler.cs
index 94ecc3c..bd6219d 100644
--- a/Main/System/OpenServerActivity/OperationTimeHepler.cs
+++ b/Main/System/OpenServerActivity/OperationTimeHepler.cs
@@ -6,16 +6,16 @@
public class OperationTimeHepler : Singleton<OperationTimeHepler>
{
- public Dictionary<Operation, OperationBase> operationDict = new Dictionary<Operation, OperationBase>();
+ public Dictionary<OperationType, OperationBase> operationDict = new Dictionary<OperationType, OperationBase>();
public static StringBuilder textBuilder = new StringBuilder();
- public event Action<Operation> operationTimeUpdateEvent;
- public event Action<Operation> operationServerCloseEvent;//鐗规畩鎯呭喌涓嬭Е鍙�
- public event Action<Operation, int> operationEndEvent;//娲诲姩缁撴潫鏃堕棿瑙﹀彂 绗簩涓弬鏁�0--杩囨椿鍔ㄦ椂闂磋Е鍙� 1--杩囨椿鍔ㄥぉ瑙﹀彂
- public event Action<Operation, int> operationStartEvent;//娲诲姩寮�濮嬫椂闂村苟涓旀弧瓒冲紑鍚潯浠惰Е鍙� 绗簩涓弬鏁�0--娲诲姩鏃堕棿瑙﹀彂 1--娲诲姩澶╄Е鍙�
+ public event Action<OperationType> operationTimeUpdateEvent;
+ public event Action<OperationType> operationServerCloseEvent;//鐗规畩鎯呭喌涓嬭Е鍙�
+ public event Action<OperationType, int> operationEndEvent;//娲诲姩缁撴潫鏃堕棿瑙﹀彂 绗簩涓弬鏁�0--杩囨椿鍔ㄦ椂闂磋Е鍙� 1--杩囨椿鍔ㄥぉ瑙﹀彂
+ public event Action<OperationType, int> operationStartEvent;//娲诲姩寮�濮嬫椂闂村苟涓旀弧瓒冲紑鍚潯浠惰Е鍙� 绗簩涓弬鏁�0--娲诲姩鏃堕棿瑙﹀彂 1--娲诲姩澶╄Е鍙�
public event Action<int> dayResetEvent;//娲诲姩閲嶇疆浜嬩欢0-0鐐� 1-5鐐�
- public event Action<Operation> operationAdvanceEvent;//娲诲姩鍦ㄦ彁鍓嶅紑鍚殑鏃堕棿鍐�
+ public event Action<OperationType> operationAdvanceEvent;//娲诲姩鍦ㄦ彁鍓嶅紑鍚殑鏃堕棿鍐�
public OperationTimeHepler()
{
@@ -38,30 +38,30 @@
{
return;
}
- for (int i = 0; i < (int)Operation.max; i++)
+ for (int i = 0; i < (int)OperationType.max; i++)
{
- if (operationDict.ContainsKey((Operation)i))
+ if (operationDict.ContainsKey((OperationType)i))
{
- var operation = operationDict[(Operation)i];
+ var operation = operationDict[(OperationType)i];
if (!operation.inDateNotify && operation.SatisfyOpenCondition()
&& operation.InDay(TimeUtility.ServerNow))
{
operation.inDateNotify = true;
operation.stepDateNotify = false;
- Debug.LogFormat("{0} 娲诲姩澶╁紑濮�", (Operation)i);
+ Debug.LogFormat("{0} 娲诲姩澶╁紑濮�", (OperationType)i);
if (operationStartEvent != null)
{
- operationStartEvent((Operation)i, 1);
+ operationStartEvent((OperationType)i, 1);
}
}
else if (!operation.stepDateNotify && !operation.InDay(TimeUtility.ServerNow))
{
operation.inDateNotify = false;
operation.stepDateNotify = true;
- Debug.LogFormat("{0} 娲诲姩澶╃粨鏉�", (Operation)i);
+ Debug.LogFormat("{0} 娲诲姩澶╃粨鏉�", (OperationType)i);
if (operationEndEvent != null)
{
- operationEndEvent((Operation)i, 1);
+ operationEndEvent((OperationType)i, 1);
}
}
if (!operation.inTimeNotify && operation.SatisfyOpenCondition()
@@ -69,10 +69,10 @@
{
operation.inTimeNotify = true;
operation.stepTimeNotify = false;
- Debug.LogFormat("{0} 娲诲姩鏃堕棿寮�濮�", (Operation)i);
+ Debug.LogFormat("{0} 娲诲姩鏃堕棿寮�濮�", (OperationType)i);
if (operationStartEvent != null)
{
- operationStartEvent((Operation)i, 0);
+ operationStartEvent((OperationType)i, 0);
}
}
else if (!operation.stepTimeNotify && !operation.InTime(TimeUtility.ServerNow))
@@ -80,10 +80,10 @@
operation.inTimeNotify = false;
operation.stepTimeNotify = true;
operation.inAdvanceNotify = false;
- Debug.LogFormat("{0} 娲诲姩鏃堕棿缁撴潫", (Operation)i);
+ Debug.LogFormat("{0} 娲诲姩鏃堕棿缁撴潫", (OperationType)i);
if (operationEndEvent != null)
{
- operationEndEvent((Operation)i, 0);
+ operationEndEvent((OperationType)i, 0);
}
}
@@ -91,10 +91,10 @@
&& operation.InAdvanceTime(TimeUtility.ServerNow))
{
operation.inAdvanceNotify = true;
- Debug.LogFormat("{0} 娲诲姩鎻愬墠寮�鍚�", (Operation)i);
+ Debug.LogFormat("{0} 娲诲姩鎻愬墠寮�鍚�", (OperationType)i);
if (operationAdvanceEvent != null)
{
- operationAdvanceEvent((Operation)i);
+ operationAdvanceEvent((OperationType)i);
}
}
}
@@ -684,7 +684,7 @@
// }
// }
- public void ForceStopOperation(Operation operationType)
+ public void ForceStopOperation(OperationType operationType)
{
if (operationDict.ContainsKey(operationType))
{
@@ -701,12 +701,12 @@
}
}
- public bool TryGetOperationTime(Operation type, out OperationBase operation)
+ public bool TryGetOperationTime(OperationType type, out OperationBase operation)
{
return operationDict.TryGetValue(type, out operation);
}
- public bool TryGetOperation<T>(Operation type, out T operation) where T : OperationBase
+ public bool TryGetOperation<T>(OperationType type, out T operation) where T : OperationBase
{
operation = null;
if (operationDict.ContainsKey(type))
@@ -717,7 +717,7 @@
return false;
}
- public bool InOperationTime(Operation type)
+ public bool InOperationTime(OperationType type)
{
OperationBase operation;
if (TryGetOperationTime(type, out operation))
@@ -727,7 +727,7 @@
return false;
}
- public bool InOperationTime(Operation type, DateTime time)
+ public bool InOperationTime(OperationType type, DateTime time)
{
OperationBase operation;
if (TryGetOperationTime(type, out operation))
@@ -737,7 +737,7 @@
return false;
}
- public bool InOperationJoinTime(Operation type, DateTime time)
+ public bool InOperationJoinTime(OperationType type, DateTime time)
{
OperationBase operation;
if (TryGetOperationTime(type, out operation))
@@ -747,7 +747,7 @@
return false;
}
- public bool InOperationDay(Operation type)
+ public bool InOperationDay(OperationType type)
{
OperationBase operation;
if (TryGetOperationTime(type, out operation))
@@ -757,7 +757,7 @@
return false;
}
- public int GetOperationSurplusTime(Operation type)
+ public int GetOperationSurplusTime(OperationType type)
{
OperationBase operation;
if (TryGetOperationTime(type, out operation))
@@ -767,7 +767,7 @@
return 0;
}
- public bool InOperationAdvance(Operation type)
+ public bool InOperationAdvance(OperationType type)
{
OperationBase operation;
if (TryGetOperationTime(type, out operation))
@@ -777,7 +777,7 @@
return false;
}
- public int GetOperationSecondsBeforeStart(Operation type)
+ public int GetOperationSecondsBeforeStart(OperationType type)
{
OperationBase operation;
if (TryGetOperationTime(type, out operation))
@@ -787,7 +787,7 @@
return 0;
}
- public bool SatisfyOpenCondition(Operation type)
+ public bool SatisfyOpenCondition(OperationType type)
{
OperationBase operation;
if (TryGetOperationTime(type, out operation))
@@ -797,7 +797,7 @@
return false;
}
- public bool SatisfyOpenCondition(Operation type, DateTime time)
+ public bool SatisfyOpenCondition(OperationType type, DateTime time)
{
OperationBase operation;
if (TryGetOperationTime(type, out operation))
@@ -808,7 +808,7 @@
}
//娲诲姩寮�鍚腑锛屾湁鍙備笌杩涜鏃堕棿娈�
- public bool SatisfyJoinCondition(Operation type, DateTime time)
+ public bool SatisfyJoinCondition(OperationType type, DateTime time)
{
OperationBase operation;
if (TryGetOperationTime(type, out operation))
@@ -818,7 +818,7 @@
return false;
}
- public bool IsPrepareTime(Operation type, DateTime time)
+ public bool IsPrepareTime(OperationType type, DateTime time)
{
OperationBase operation;
if (TryGetOperationTime(type, out operation))
@@ -828,7 +828,7 @@
return false;
}
- public bool SatisfyAdvanceCondition(Operation type)
+ public bool SatisfyAdvanceCondition(OperationType type)
{
OperationBase operation;
if (TryGetOperationTime(type, out operation))
@@ -838,7 +838,7 @@
return false;
}
- public void ProcessConditionError(Operation type)
+ public void ProcessConditionError(OperationType type)
{
if (SatisfyOpenCondition(type))
{
@@ -1043,7 +1043,7 @@
}
}
-public enum Operation
+public enum OperationType
{
MultipleExp,
ConsumeRebate,
diff --git a/Main/System/Store/StoreModel.cs b/Main/System/Store/StoreModel.cs
index 93d17e5..63460e9 100644
--- a/Main/System/Store/StoreModel.cs
+++ b/Main/System/Store/StoreModel.cs
@@ -63,7 +63,7 @@
//鎺掕姒滄椿鍔ㄧ殑鍟嗗簵
public int rankActStore_MoneyType;
public int rankActStore_StoreType;
- public Operation rankActStore_ActType;
+ public OperationType rankActStore_ActType;
public override void Init()
{
diff --git a/Main/System/Team/TeamBase.cs b/Main/System/Team/TeamBase.cs
index f578df0..30933ec 100644
--- a/Main/System/Team/TeamBase.cs
+++ b/Main/System/Team/TeamBase.cs
@@ -226,6 +226,18 @@
return false;
}
+ public bool HasHeroInServer(string guid)
+ {
+ foreach (var hero in serverHeroes)
+ {
+ if (hero != null && hero.guid == guid)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
//瀹㈡埛绔粠0寮�濮嬶紝鏈嶅姟绔粠1寮�濮�
public int GetEmptyPosition()
{
@@ -270,17 +282,7 @@
return;
}
- TeamHero targetHero = tempHeroes[targetPosition];
-
- if (null == targetHero)
- {
- TeamHero newHero = new TeamHero(heroInfo, targetPosition, this);
- SetTeamHero(targetPosition, newHero);
- }
- else
- {
- SetTeamHero(targetPosition, new TeamHero(heroInfo, targetPosition, this));
- }
+ SetTeamHero(targetPosition, new TeamHero(heroInfo, targetPosition, this));
}
diff --git a/Main/System/Team/TeamHero.cs b/Main/System/Team/TeamHero.cs
index c5af4ad..f28f8b9 100644
--- a/Main/System/Team/TeamHero.cs
+++ b/Main/System/Team/TeamHero.cs
@@ -1,5 +1,4 @@
using UnityEngine;
-using UnityEngine.PlayerLoop;
public partial class TeamHero
{
@@ -79,6 +78,7 @@
heroId = heroInfo.itemHero.config.ID;
SkinID = heroInfo.SkinID;
skinConfig = heroInfo.skinConfig;
+ Country = heroInfo.heroCountry;
teamBase = _teamBase;
diff --git a/Main/System/Tip/PowerAddWin.cs b/Main/System/Tip/PowerAddWin.cs
index 10c3b7b..3bd2e58 100644
--- a/Main/System/Tip/PowerAddWin.cs
+++ b/Main/System/Tip/PowerAddWin.cs
@@ -140,9 +140,9 @@
sequence.Append(txtBase.DOText(DisplayBasePowerNum(nowValue), rollTime).SetEase(rollEaseType).OnComplete(() => { SetInitPosition(nowValue, changePower, isAdd); }));
}
}
-#if UNITY_EDITOR
- Debug.Log($"count {i} changeValue {changeValue} nowValue {nowValue} isAdd {isAdd} basePower {basePower} changePower {changePower} nowPower {nowPower} rollTime {rollTime}");
-#endif
+// #if UNITY_EDITOR
+// Debug.Log($"count {i} changeValue {changeValue} nowValue {nowValue} isAdd {isAdd} basePower {basePower} changePower {changePower} nowPower {nowPower} rollTime {rollTime}");
+// #endif
}
sequence.Join(textChangeSequence);
diff --git a/Main/System/UIBase/UIBase.cs b/Main/System/UIBase/UIBase.cs
index 5266c16..e81b824 100644
--- a/Main/System/UIBase/UIBase.cs
+++ b/Main/System/UIBase/UIBase.cs
@@ -121,7 +121,7 @@
}
catch (Exception e)
{
- Debug.LogError($"{uiName}鐣岄潰鐨処nitComponentInternal鎶ラ敊: {e.Message}");
+ Debug.LogError($"{uiName}鐣岄潰鐨処nitComponentInternal鎶ラ敊: {e.StackTrace}");
}
try
@@ -130,7 +130,7 @@
}
catch (Exception e)
{
- Debug.LogError($"{uiName}鐣岄潰鐨処nitComponent鎶ラ敊: {e.Message}");
+ Debug.LogError($"{uiName}鐣岄潰鐨処nitComponent鎶ラ敊: {e.StackTrace}");
}
// 淇濆瓨鍘熷鍊肩敤浜庡姩鐢�
@@ -285,7 +285,7 @@
}
catch (Exception e)
{
- Debug.LogError($"{uiName}鐣岄潰鐨凮nPreOpen鎶ラ敊: {e.Message}");
+ Debug.LogError($"{uiName}鐣岄潰鐨凮nPreOpen鎶ラ敊: {e.StackTrace}");
}
StopCurrentAnimation();
@@ -306,7 +306,7 @@
}
catch (Exception e)
{
- Debug.LogError($"{uiName}鐣岄潰鐨凮nOpen鎶ラ敊: {e.Message}");
+ Debug.LogError($"{uiName}鐣岄潰鐨凮nOpen鎶ラ敊: {e.StackTrace}");
}
ApplyClickEmptySpaceClose();
@@ -319,7 +319,7 @@
}
catch (Exception e)
{
- Debug.LogError($"{uiName}鐣岄潰鐨凬extFrameAfterOpen鎶ラ敊: {e.Message}");
+ Debug.LogError($"{uiName}鐣岄潰鐨凬extFrameAfterOpen鎶ラ敊: {e.StackTrace}");
}
});
}
@@ -344,7 +344,7 @@
}
catch (Exception e)
{
- Debug.LogError($"{uiName}鐣岄潰鐨凮nPreClose鎶ラ敊: {e.Message}");
+ Debug.LogError($"{uiName}鐣岄潰鐨凮nPreClose鎶ラ敊: {e.StackTrace}");
}
StopCurrentAnimation();
@@ -365,7 +365,7 @@
}
catch (Exception e)
{
- Debug.LogError($"{uiName}鐣岄潰鐨凮nClose鎶ラ敊: {e.Message}");
+ Debug.LogError($"{uiName}鐣岄潰鐨凮nClose鎶ラ敊: {e.StackTrace}");
}
if (closeAnimationType == UIAnimationType.None)
@@ -376,7 +376,7 @@
}
catch (Exception e)
{
- Debug.LogError($"{uiName}鐣岄潰鐨凜ompleteClose鎶ラ敊: {e.Message}");
+ Debug.LogError($"{uiName}鐣岄潰鐨凜ompleteClose鎶ラ敊: {e.StackTrace}");
}
}
// 鍚﹀垯鍦ㄥ姩鐢诲畬鎴愬悗绂佺敤娓告垙瀵硅薄锛堝湪PlayCloseAnimation涓鐞嗭級
@@ -628,7 +628,7 @@
}
catch (System.Exception e)
{
- Debug.LogError($"鎾斁鎵撳紑鍔ㄧ敾鏃跺嚭閿�: {e.Message}");
+ Debug.LogError($"鎾斁鎵撳紑鍔ㄧ敾鏃跺嚭閿�: {e.StackTrace}");
// 鍑洪敊鏃剁‘淇漊I鍙骞跺彲浜や簰
if (canvasGroup != null)
@@ -751,7 +751,7 @@
}
catch (Exception e)
{
- Debug.LogError($"{uiName}鐣岄潰鐨凜ompleteClose鎶ラ敊: {e.Message}");
+ Debug.LogError($"{uiName}鐣岄潰鐨凜ompleteClose鎶ラ敊: {e.StackTrace}");
}
}
});
@@ -760,7 +760,7 @@
}
catch (System.Exception e)
{
- Debug.LogError($"鎾斁鍏抽棴鍔ㄧ敾鏃跺嚭閿�: {e.Message}");
+ Debug.LogError($"鎾斁鍏抽棴鍔ㄧ敾鏃跺嚭閿�: {e.StackTrace}");
// 鍑洪敊鏃剁洿鎺ュ畬鎴愬叧闂�
isAnimating = false;
diff --git a/Main/Utility/JaceCalculator.cs b/Main/Utility/JaceCalculator.cs
new file mode 100644
index 0000000..545b595
--- /dev/null
+++ b/Main/Utility/JaceCalculator.cs
@@ -0,0 +1,36 @@
+using Jace;
+using System;
+using System.Collections.Generic;
+
+public static class JaceCalculator
+{
+ private static readonly CalculationEngine Engine = new CalculationEngine();
+
+ /// <summary>
+ /// 瑙f瀽骞惰绠楁暟瀛﹁〃杈惧紡
+ /// </summary>
+ /// <param name="formula">鏁板琛ㄨ揪寮忓瓧绗︿覆</param>
+ /// <param name="variables">鍙橀噺瀛楀吀</param>
+ /// <returns>璁$畻缁撴灉</returns>
+ public static double Calculate(string formula, Dictionary<string, double> variables)
+ {
+ if (string.IsNullOrEmpty(formula))
+ {
+ throw new ArgumentException("Formula cannot be null or empty.");
+ }
+
+ if (variables == null || variables.Count == 0)
+ {
+ throw new ArgumentException("Variables dictionary cannot be null or empty.");
+ }
+
+ try
+ {
+ return Engine.Calculate(formula, variables);
+ }
+ catch (Exception ex)
+ {
+ throw new InvalidOperationException($"Failed to calculate formula: {ex.Message}", ex);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Main/System/Hero/HeroInfo.Quality.cs.meta b/Main/Utility/JaceCalculator.cs.meta
similarity index 83%
copy from Main/System/Hero/HeroInfo.Quality.cs.meta
copy to Main/Utility/JaceCalculator.cs.meta
index e37f87e..50a6ca1 100644
--- a/Main/System/Hero/HeroInfo.Quality.cs.meta
+++ b/Main/Utility/JaceCalculator.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 8540c5ed5104dfe40b0bff4aaf9a080b
+guid: ebee4528e9596394886463d65c214b23
MonoImporter:
externalObjects: {}
serializedVersion: 2
--
Gitblit v1.8.0