diff --git a/src/Persistence/Initialization/Updates/AddElfSoldierBuffPlugIn.cs b/src/Persistence/Initialization/Updates/AddElfSoldierBuffPlugIn.cs index ef6b7ba82..7e47d3b9a 100644 --- a/src/Persistence/Initialization/Updates/AddElfSoldierBuffPlugIn.cs +++ b/src/Persistence/Initialization/Updates/AddElfSoldierBuffPlugIn.cs @@ -62,41 +62,46 @@ protected override async ValueTask ApplyAsync(IContext context, GameConfiguratio return; } - var buffEffect = context.CreateNew(); - gameConfiguration.MagicEffects.Add(buffEffect); - buffEffect.Number = (short)MagicEffectNumber.ElfSoldierBuff; - buffEffect.Name = "Elf Soldier Buff"; - buffEffect.InformObservers = true; - buffEffect.StopByDeath = true; - - // Duration: 60 minutes - buffEffect.Duration = context.CreateNew(); - buffEffect.Duration.ConstantValue.Value = 3600; - - // Defense boost: 50 + (Level / 5) - var defensePowerUp = context.CreateNew(); - defensePowerUp.TargetAttribute = Stats.DefenseFinal.GetPersistent(gameConfiguration); - defensePowerUp.Boost = context.CreateNew(); - defensePowerUp.Boost.ConstantValue.Value = 50; - defensePowerUp.Boost.ConstantValue.AggregateType = AggregateType.AddFinal; - var defensePerLevel = context.CreateNew(); - defensePerLevel.InputAttribute = Stats.Level.GetPersistent(gameConfiguration); - defensePerLevel.InputOperand = 1f / 5; - defensePerLevel.InputOperator = InputOperator.Multiply; - defensePowerUp.Boost.RelatedValues.Add(defensePerLevel); - buffEffect.PowerUpDefinitions.Add(defensePowerUp); - - // Damage boost: 45 + (Level / 3) - var damagePowerUp = context.CreateNew(); - damagePowerUp.TargetAttribute = Stats.GreaterDamageBonus.GetPersistent(gameConfiguration); - damagePowerUp.Boost = context.CreateNew(); - damagePowerUp.Boost.ConstantValue.Value = 45; - var damagePerLevel = context.CreateNew(); - damagePerLevel.InputAttribute = Stats.Level.GetPersistent(gameConfiguration); - damagePerLevel.InputOperand = 1f / 3; - damagePerLevel.InputOperator = InputOperator.Multiply; - damagePowerUp.Boost.RelatedValues.Add(damagePerLevel); - buffEffect.PowerUpDefinitions.Add(damagePowerUp); + var buffEffect = gameConfiguration.MagicEffects.FirstOrDefault(e => e.Number == (short)MagicEffectNumber.ElfSoldierBuff); + if (buffEffect is null) + { + buffEffect = context.CreateNew(); + gameConfiguration.MagicEffects.Add(buffEffect); + buffEffect.Number = (short)MagicEffectNumber.ElfSoldierBuff; + buffEffect.Name = "Elf Soldier Buff"; + buffEffect.InformObservers = true; + buffEffect.StopByDeath = true; + + // Duration: 60 minutes + buffEffect.Duration = context.CreateNew(); + buffEffect.Duration.ConstantValue.Value = 3600; + + // Defense boost: 50 + (Level / 5) + var defensePowerUp = context.CreateNew(); + defensePowerUp.TargetAttribute = Stats.DefenseFinal.GetPersistent(gameConfiguration); + defensePowerUp.Boost = context.CreateNew(); + defensePowerUp.Boost.ConstantValue.Value = 50; + defensePowerUp.Boost.ConstantValue.AggregateType = AggregateType.AddFinal; + var defensePerLevel = context.CreateNew(); + defensePerLevel.InputAttribute = Stats.Level.GetPersistent(gameConfiguration); + defensePerLevel.InputOperand = 1f / 5; + defensePerLevel.InputOperator = InputOperator.Multiply; + defensePowerUp.Boost.RelatedValues.Add(defensePerLevel); + buffEffect.PowerUpDefinitions.Add(defensePowerUp); + + // Damage boost: 45 + (Level / 3) + var damagePowerUp = context.CreateNew(); + damagePowerUp.TargetAttribute = Stats.GreaterDamageBonus.GetPersistent(gameConfiguration); + damagePowerUp.Boost = context.CreateNew(); + damagePowerUp.Boost.ConstantValue.Value = 45; + damagePowerUp.Boost.ConstantValue.AggregateType = AggregateType.AddRaw; + var damagePerLevel = context.CreateNew(); + damagePerLevel.InputAttribute = Stats.Level.GetPersistent(gameConfiguration); + damagePerLevel.InputOperand = 1f / 3; + damagePerLevel.InputOperator = InputOperator.Multiply; + damagePowerUp.Boost.RelatedValues.Add(damagePerLevel); + buffEffect.PowerUpDefinitions.Add(damagePowerUp); + } var buff = context.CreateNew(); buff.MagicEffectDefinition = buffEffect; diff --git a/src/Persistence/Initialization/VersionSeasonSix/NpcInitialization.cs b/src/Persistence/Initialization/VersionSeasonSix/NpcInitialization.cs index 5c3eed168..ba77909fe 100644 --- a/src/Persistence/Initialization/VersionSeasonSix/NpcInitialization.cs +++ b/src/Persistence/Initialization/VersionSeasonSix/NpcInitialization.cs @@ -151,6 +151,7 @@ public override void Initialize() damagePowerUp.TargetAttribute = Stats.GreaterDamageBonus.GetPersistent(this.GameConfiguration); damagePowerUp.Boost = this.Context.CreateNew(); damagePowerUp.Boost.ConstantValue.Value = 45; + damagePowerUp.Boost.ConstantValue.AggregateType = AggregateType.AddRaw; var damagePerLevel = this.Context.CreateNew(); damagePerLevel.InputAttribute = Stats.Level.GetPersistent(this.GameConfiguration); damagePerLevel.InputOperand = 1f / 3; diff --git a/src/Persistence/Json/ReferenceResolvingConverter.cs b/src/Persistence/Json/ReferenceResolvingConverter.cs index 35eda046b..9b6897610 100644 --- a/src/Persistence/Json/ReferenceResolvingConverter.cs +++ b/src/Persistence/Json/ReferenceResolvingConverter.cs @@ -47,11 +47,14 @@ static ReferenceResolvingConverter() else if (x.CollectionInterface != null && x.Property.Name.StartsWith("Raw")) { propertyType = x.CollectionInterface.GetGenericArguments()[0]; + + var collectionExpr = Expression.Convert(Expression.Property(tParam, x.Property), x.CollectionInterface); + var itemExpr = Expression.Convert(objParam, propertyType); + var containsCall = Expression.Call(collectionExpr, x.CollectionInterface.GetMethod("Contains")!, itemExpr); + var addCall = Expression.Call(collectionExpr, x.CollectionInterface.GetMethod("Add")!, itemExpr); + adder = Expression.Lambda>( - Expression.Call( - Expression.Property(tParam, x.Property), - x.CollectionInterface.GetMethod("Add")!, - Expression.Convert(objParam, propertyType)), + Expression.IfThen(Expression.Not(containsCall), addCall), tParam, objParam) .Compile(); @@ -66,11 +69,15 @@ static ReferenceResolvingConverter() propertyType = propertyType.GetProperties().First(p => p.PropertyType.BaseType == baseType).PropertyType; jsonPropertyName = basePropertyName; + + var baseCollectionInterface = DetermineCollectionInterface(baseCollectionProperty)!; + var collectionExpr = Expression.Convert(Expression.Property(tParam, baseCollectionProperty), baseCollectionInterface); + var itemExpr = Expression.Convert(objParam, propertyType); + var containsCall = Expression.Call(collectionExpr, baseCollectionInterface.GetMethod("Contains")!, itemExpr); + var addCall = Expression.Call(collectionExpr, baseCollectionInterface.GetMethod("Add")!, itemExpr); + adder = Expression.Lambda>( - Expression.Call( - Expression.Property(tParam, baseCollectionProperty), - baseCollectionProperty.PropertyType.GetMethod("Add")!, - Expression.Convert(objParam, propertyType)), + Expression.IfThen(Expression.Not(containsCall), addCall), tParam, objParam) .Compile();