Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ private static CombatStats ApplyBuffs(CombatStats stats, IReadOnlyCollection<Buf
int defenceAll = 0, defenceMelee = 0, defenceRanged = 0, defenceMagical = 0;
int hitRateFlat = 0, dodgeFlat = 0;
int moraleFlat = 0;
int resistAll = 0, resistFire = 0, resistWater = 0, resistLight = 0, resistDark = 0;
int elementAll = 0, elementFire = 0, elementWater = 0, elementLight = 0, elementDark = 0;

foreach (var buff in buffs)
Expand Down Expand Up @@ -243,6 +244,22 @@ private static CombatStats ApplyBuffs(CombatStats stats, IReadOnlyCollection<Buf
else if (sub == (byte)AdditionalTypes.Element.DarkIncreased) elementDark += first;
else if (sub == (byte)AdditionalTypes.Element.DarkDecreased) elementDark -= first;
break;
// Type 13, the defender's side of the elemental exchange. Not to be
// confused with type 7 below, which is the attacker's element rate: these
// four are read in ComputeElementalDamage as a percentage taken off the
// incoming elemental damage.
case BCardType.CardType.ElementResistance:
if (sub == (byte)AdditionalTypes.ElementResistance.AllIncreased) resistAll += first;
else if (sub == (byte)AdditionalTypes.ElementResistance.AllDecreased) resistAll -= first;
else if (sub == (byte)AdditionalTypes.ElementResistance.FireIncreased) resistFire += first;
else if (sub == (byte)AdditionalTypes.ElementResistance.FireDecreased) resistFire -= first;
else if (sub == (byte)AdditionalTypes.ElementResistance.WaterIncreased) resistWater += first;
else if (sub == (byte)AdditionalTypes.ElementResistance.WaterDecreased) resistWater -= first;
else if (sub == (byte)AdditionalTypes.ElementResistance.LightIncreased) resistLight += first;
else if (sub == (byte)AdditionalTypes.ElementResistance.LightDecreased) resistLight -= first;
else if (sub == (byte)AdditionalTypes.ElementResistance.DarkIncreased) resistDark += first;
else if (sub == (byte)AdditionalTypes.ElementResistance.DarkDecreased) resistDark -= first;
break;
}
}
}
Expand Down Expand Up @@ -276,6 +293,13 @@ private static CombatStats ApplyBuffs(CombatStats stats, IReadOnlyCollection<Buf
MagicDefence = stats.MagicDefence + defenceAll + defenceMagical,
DefenceDodge = stats.DefenceDodge + dodgeFlat,
DistanceDefenceDodge = stats.DistanceDefenceDodge + dodgeFlat,
// "All" adds to each of the four rather than living in a fifth field: the
// damage step reads one resistance, picked by the attacker's element, and a
// separate total would have to be remembered at every one of those reads.
FireResistance = stats.FireResistance + resistAll + resistFire,
WaterResistance = stats.WaterResistance + resistAll + resistWater,
LightResistance = stats.LightResistance + resistAll + resistLight,
DarkResistance = stats.DarkResistance + resistAll + resistDark,
ElementRate = stats.ElementRate + elementFlatBonus,
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// __ _ __ __ ___ __ ___ ___
// | \| |/__\ /' _/ / _//__\| _ \ __|
// | | ' | \/ |`._`.| \_| \/ | v / _|
// |_|\__|\__/ |___/ \__/\__/|_|_\___|
//

using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using NodaTime;
using NosCore.Data.Enumerations.Buff;
using NosCore.Data.StaticEntities;
using NosCore.GameObject.Ecs.Interfaces;
using NosCore.GameObject.Services.BattleService;
using NosCore.GameObject.Services.BattleService.Model;

namespace NosCore.GameObject.Tests.Services.BattleService
{
// BCard type 13, "Changes elemental resistance". 561 declarations - 408 on items, 153 on
// cards - and the fold did not have a case for it, so a resistance buff changed nothing.
//
// The four fields it feeds are read in ComputeElementalDamage as a percentage taken off the
// incoming elemental damage, so getting them wrong moves numbers and raises nothing.
[TestClass]
public class ElementResistanceTests
{
private const short BaseFire = 10;

private static BCardDto Resistance(AdditionalTypes.ElementResistance subType, short value) =>
new()
{
Type = (byte)BCardType.CardType.ElementResistance,
SubType = (byte)subType,
FirstData = value
};

private static CombatStats StatsWith(params BCardDto[] bCards)
{
var monster = new NpcMonsterDto
{
FireResistance = BaseFire,
WaterResistance = 0,
LightResistance = 0,
DarkResistance = 0
};

var entity = new Mock<INonPlayableEntity>();
entity.SetupGet(e => e.NpcMonster).Returns(monster);
entity.SetupGet(e => e.Level).Returns((byte)1);
entity.SetupGet(e => e.HeroLevel).Returns((byte)0);

var buffs = new Mock<IBuffService>();
buffs.Setup(b => b.GetActiveBuffs(It.IsAny<IAliveEntity>())).Returns(new List<BuffInstance>
{
new(CardId: 1, BuffType: BuffType.Good, Caster: null,
StartedAt: Instant.MinValue, ExpiresAt: Instant.MaxValue, BCards: bCards)
});

return new BattleStatsProvider(buffs.Object).GetStats(entity.Object);
}

[TestMethod]
public void AFireResistanceBuffAddsToTheMonstersOwn()
{
var stats = StatsWith(Resistance(AdditionalTypes.ElementResistance.FireIncreased, 25));

Assert.AreEqual(BaseFire + 25, stats.FireResistance);
Assert.AreEqual(0, stats.WaterResistance, "only fire was named");
}

// "All elemental resistance is increased by %s" reaches every one of the four. Keeping it
// in a fifth field would mean remembering to add it at each of the four reads.
[TestMethod]
public void TheAllSubtypeReachesEveryElement()
{
var stats = StatsWith(Resistance(AdditionalTypes.ElementResistance.AllIncreased, 15));

Assert.AreEqual(BaseFire + 15, stats.FireResistance);
Assert.AreEqual(15, stats.WaterResistance);
Assert.AreEqual(15, stats.LightResistance);
Assert.AreEqual(15, stats.DarkResistance);
}

[TestMethod]
public void AllAndOneElementAddUpOnThatElement()
{
var stats = StatsWith(
Resistance(AdditionalTypes.ElementResistance.AllIncreased, 15),
Resistance(AdditionalTypes.ElementResistance.WaterIncreased, 10));

Assert.AreEqual(25, stats.WaterResistance);
Assert.AreEqual(15, stats.LightResistance);
}

// The X1/X2 pairs of this type carry different sentences - "increased by" against
// "decreased by" - so X2 really is the negation, unlike the types where the file repeats
// the same line in both slots.
[TestMethod]
public void TheDecreasingSubtypeTakesAway()
{
var stats = StatsWith(Resistance(AdditionalTypes.ElementResistance.FireDecreased, 4));

Assert.AreEqual(BaseFire - 4, stats.FireResistance);
}

[TestMethod]
public void WithoutAnyOfTheseTheMonsterKeepsItsOwn()
{
var stats = StatsWith();

Assert.AreEqual(BaseFire, stats.FireResistance);
Assert.AreEqual(0, stats.DarkResistance);
}
}
}
Loading