feat(frost-shard): quadruple base-plus-INT damage (#16)
Implements OpenProject #177; tested tree 52b88b562e, 2535 passing local tests.
This commit was merged in pull request #16.
This commit is contained in:
commit
9896194932
4 files changed
+96
-35
No files matched your search
@@ -151,7 +151,7 @@ public final class FrostShard implements AbilityEffect, Listener, AutoCloseable
|
||||
var current = settings;
|
||||
return new AbilityDefinition("frost_shard", "Frost Shard", Material.PRISMARINE_SHARD,
|
||||
List.of("Launch a frost projectile with a " + BigDecimal.valueOf(current.range()).stripTrailingZeros().toPlainString() + "-block travel limit.",
|
||||
"Deals " + current.baseDamage() + " + INT modifier damage and Slowness "
|
||||
"Deals 4 * (" + current.baseDamage() + " + INT modifier) damage and Slowness "
|
||||
+ level(current.slownessAmplifier()) + " for " + seconds(current.slownessDuration()) + "s."),
|
||||
"Use the equipped shard; a miss still spends the cooldown.",
|
||||
Map.of(Stat.INT, BigInteger.valueOf(12), Stat.WIS, BigInteger.TEN), BigInteger.ONE, AbilityDefinition.Category.ATK,
|
||||
@@ -187,7 +187,7 @@ public final class FrostShard implements AbilityEffect, Listener, AutoCloseable
|
||||
BigInteger[] divided = delta.divideAndRemainder(BigInteger.TWO);
|
||||
BigInteger modifier = divided[0];
|
||||
if (delta.signum() < 0 && divided[1].signum() != 0) modifier = modifier.subtract(BigInteger.ONE);
|
||||
return base.add(modifier);
|
||||
return base.add(modifier).multiply(BigInteger.valueOf(4));
|
||||
}
|
||||
|
||||
@Override public void activate(AbilityExecution execution) {
|
||||
|
||||
@@ -73,6 +73,8 @@ class FrostShardNativeTest {
|
||||
var target = mock(org.bukkit.entity.LivingEntity.class);
|
||||
when(target.getUniqueId()).thenReturn(java.util.UUID.randomUUID());
|
||||
when(target.getType()).thenReturn(org.bukkit.entity.EntityType.ZOMBIE);
|
||||
when(target.getPersistentDataContainer()).thenReturn(new org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer(
|
||||
new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry()));
|
||||
when(target.getLocation()).thenReturn(new org.bukkit.Location(a.world, 10, 65.6, 0));
|
||||
when(target.addPotionEffect(any())).thenReturn(true);
|
||||
var vanilla = new org.bukkit.event.entity.EntityDamageByEntityEvent(projectile, target,
|
||||
@@ -89,7 +91,7 @@ class FrostShardNativeTest {
|
||||
var hit = new org.bukkit.event.entity.ProjectileHitEvent(projectile, target);
|
||||
f.dispatcher.accept(hit);
|
||||
assertFalse(hit.isCancelled(), "Eligible hostile Frost Shard hit was unexpectedly cancelled");
|
||||
assertEquals(1, damages.size()); assertEquals(5.0, damages.getFirst().getDamage());
|
||||
assertEquals(1, damages.size()); assertEquals(20.0, damages.getFirst().getDamage());
|
||||
var effect = org.mockito.ArgumentCaptor.forClass(org.bukkit.potion.PotionEffect.class);
|
||||
verify(target).addPotionEffect(effect.capture());
|
||||
assertEquals(org.bukkit.potion.PotionEffectType.SLOWNESS, effect.getValue().getType());
|
||||
@@ -121,8 +123,8 @@ class FrostShardNativeTest {
|
||||
.findFirst().orElseThrow().getAsJsonObject("data");
|
||||
assertEquals(resolution.get("projectile_id").getAsString(), damage.get("projectile_id").getAsString());
|
||||
assertTrue(damage.getAsJsonObject("impact_location").has("world_id"));
|
||||
assertEquals(5, damage.get("requested_amount").getAsDouble());
|
||||
assertEquals(5, damage.get("actual_amount").getAsDouble());
|
||||
assertEquals(20, damage.get("requested_amount").getAsDouble());
|
||||
assertEquals(20, damage.get("actual_amount").getAsDouble());
|
||||
assertTrue(damage.getAsJsonObject("target_location").has("world_id"));
|
||||
assertTrue(damage.has("direct_entity_id"));
|
||||
}
|
||||
@@ -150,8 +152,23 @@ class FrostShardNativeTest {
|
||||
frost.close();
|
||||
}
|
||||
|
||||
@Test void pendingCastUsesItsCapturedDefinitionEvenIfConfigurationChangesBeforeLaunch() throws Exception {
|
||||
static java.util.stream.Stream<org.junit.jupiter.params.provider.Arguments> pendingDamageCases() {
|
||||
return java.util.stream.Stream.of(
|
||||
org.junit.jupiter.params.provider.Arguments.of(BigInteger.ZERO, -4.0),
|
||||
org.junit.jupiter.params.provider.Arguments.of(BigInteger.valueOf(12), 20.0),
|
||||
org.junit.jupiter.params.provider.Arguments.of(BigInteger.valueOf(20), 36.0),
|
||||
org.junit.jupiter.params.provider.Arguments.of(BigInteger.TEN.pow(500), Double.MAX_VALUE));
|
||||
}
|
||||
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.MethodSource("pendingDamageCases")
|
||||
void pendingCastUsesItsCapturedDefinitionEvenIfConfigurationChangesBeforeLaunch(BigInteger intelligence, double expectedDamage) throws Exception {
|
||||
var actor = new FantasyStickLifecycleNativeTest.Actor(data);
|
||||
var base = actor.core.record; var stats = new java.util.EnumMap<>(base.stats());
|
||||
stats.put(games.dmg.fantasystick.progression.Stat.INT, intelligence);
|
||||
var record = new games.dmg.fantasystick.persistence.CharacterRecord(base.id(), base.name(), base.revision(), stats,
|
||||
base.level(), base.experience(), base.unspentPoints(), base.health(), base.learned(), base.loadout(), base.cooldowns(),
|
||||
base.restrictedKills(), false, null, null);
|
||||
var particles = mock(games.dmg.fantasystick.presentation.ParticleDelivery.class);
|
||||
var frost = new games.dmg.fantasystick.ability.FrostShard(
|
||||
games.dmg.fantasystick.ability.FrostShard.Settings.defaults(), particles);
|
||||
@@ -164,7 +181,7 @@ class FrostShardNativeTest {
|
||||
when(execution.stillCurrent()).thenReturn(true);
|
||||
when(execution.definition()).thenReturn(captured);
|
||||
when(execution.input()).thenReturn(input);
|
||||
when(execution.character()).thenReturn(actor.core.record);
|
||||
when(execution.character()).thenReturn(record);
|
||||
when(input.player()).thenReturn(actor.player);
|
||||
var eye = new org.bukkit.Location(actor.world, 0, 65.6, 0);
|
||||
eye.setDirection(new org.bukkit.util.Vector(1, 0, 0));
|
||||
@@ -181,8 +198,8 @@ class FrostShardNativeTest {
|
||||
frost.hit(new org.bukkit.event.entity.ProjectileHitEvent(arrow, target));
|
||||
var amount = org.mockito.ArgumentCaptor.forClass(double.class);
|
||||
verify(execution).damage(eq(target), amount.capture(), any(org.bukkit.damage.DamageSource.class));
|
||||
assertEquals(games.dmg.fantasystick.ability.FrostShard.damage(actor.core.record.stats()
|
||||
.get(games.dmg.fantasystick.progression.Stat.INT)).doubleValue(), amount.getValue());
|
||||
assertEquals(expectedDamage, amount.getValue());
|
||||
assertTrue(Double.isFinite(amount.getValue()), "uncapped INT must convert to finite native damage");
|
||||
frost.close();
|
||||
}
|
||||
|
||||
@@ -652,12 +669,18 @@ class FrostShardNativeTest {
|
||||
.contains("Unavailable:requirements"));
|
||||
assertThrows(AssertionError.class, () -> abilityButton(unavailable, "[Learn]", "frost_shard"));
|
||||
}
|
||||
assertEquals(BigInteger.valueOf(4), games.dmg.fantasystick.ability.FrostShard.damage(BigInteger.TEN));
|
||||
assertEquals(BigInteger.valueOf(5), games.dmg.fantasystick.ability.FrostShard.damage(BigInteger.valueOf(12)));
|
||||
assertEquals(BigInteger.TEN.pow(500).subtract(BigInteger.TEN).divide(BigInteger.TWO).add(BigInteger.valueOf(4)),
|
||||
assertEquals(BigInteger.valueOf(16), games.dmg.fantasystick.ability.FrostShard.damage(BigInteger.TEN));
|
||||
assertEquals(BigInteger.valueOf(20), games.dmg.fantasystick.ability.FrostShard.damage(BigInteger.valueOf(12)));
|
||||
assertEquals(BigInteger.TEN.pow(500).subtract(BigInteger.TEN).divide(BigInteger.TWO).add(BigInteger.valueOf(4)).multiply(BigInteger.valueOf(4)),
|
||||
games.dmg.fantasystick.ability.FrostShard.damage(BigInteger.TEN.pow(500)));
|
||||
}
|
||||
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.CsvSource({"0,-4", "1,-4", "9,12", "10,16", "11,16", "12,20", "13,20", "20,36", "21,36"})
|
||||
void fourfoldDamagePreservesMathematicalFloor(int intelligence, int expected) {
|
||||
assertEquals(BigInteger.valueOf(expected), games.dmg.fantasystick.ability.FrostShard.damage(BigInteger.valueOf(intelligence)));
|
||||
}
|
||||
|
||||
@Test void invalidPackagedFrostSettingsFailBeforeInstallingGameplay() throws Exception {
|
||||
for (String configuration : java.util.List.of("frost-shard-base-damage: -1\n",
|
||||
"frost-shard-cooldown-seconds: 31536001\n", "frost-shard-range-blocks: 0\n",
|
||||
@@ -787,7 +810,9 @@ class FrostShardNativeTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test void acknowledgedUpdatesAffectFutureCastsButNotAnActiveProjectileSnapshot() throws Exception {
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.ValueSource(booleans = {false, true})
|
||||
void acknowledgedUpdatesAffectFutureCastsButNotPendingOrInFlightSnapshots(boolean pending) throws Exception {
|
||||
java.nio.file.Files.writeString(data.resolve("config.yml"), "frost-shard-cooldown-seconds: 0\n");
|
||||
try (var f = new FantasyStickLifecycleNativeTest.Fixture(data)) {
|
||||
f.plugin.setEnabled(true);
|
||||
@@ -795,23 +820,39 @@ class FrostShardNativeTest {
|
||||
f.players.put(a.core.id, a.player); f.activate(a); when(a.world.getUID()).thenReturn(java.util.UUID.randomUUID());
|
||||
var oldProjectile = projectile(a, new org.bukkit.Location(a.world, 2, 65.6, 0));
|
||||
var newProjectile = projectile(a, new org.bukkit.Location(a.world, 2, 65.6, 0));
|
||||
prepareLaunches(f, a, oldProjectile, newProjectile); cast(f, a);
|
||||
|
||||
prepareLaunches(f, a, oldProjectile, newProjectile);
|
||||
Runnable pendingLaunch = null;
|
||||
if (pending) {
|
||||
a.core.inventory.getInventory().setSelectedSlot(2);
|
||||
f.dispatcher.accept(new org.bukkit.event.player.PlayerInteractEvent(a.player,
|
||||
org.bukkit.event.block.Action.RIGHT_CLICK_AIR, a.core.inventory.getItem(2), null,
|
||||
org.bukkit.block.BlockFace.SELF, org.bukkit.inventory.EquipmentSlot.HAND));
|
||||
pendingLaunch = f.tasks.poll(5, java.util.concurrent.TimeUnit.SECONDS); assertNotNull(pendingLaunch);
|
||||
verify(a.player, never()).launchProjectile(eq(org.bukkit.entity.Arrow.class), any(org.bukkit.util.Vector.class));
|
||||
} else cast(f, a);
|
||||
var repository = new games.dmg.fantasystick.persistence.YamlCharacterRepository(data);
|
||||
var deadlines = repository.load(a.core.record.id()).orElseThrow().cooldowns();
|
||||
var sender = new EquipmentAdminCommandNativeTest.Sender();
|
||||
f.command.execute(sender.port, "fantasystick", new String[]{"config", "frost-shard-base-damage", "9"});
|
||||
f.command.execute(sender.port, "fstickadmin", new String[]{"config", "frost-shard-base-damage", "9"});
|
||||
var response = f.tasks.poll(5, java.util.concurrent.TimeUnit.SECONDS); assertNotNull(response); response.run();
|
||||
assertEquals(deadlines, repository.load(a.core.record.id()).orElseThrow().cooldowns());
|
||||
if (pendingLaunch != null) pendingLaunch.run();
|
||||
var target = mock(org.bukkit.entity.LivingEntity.class); when(target.getUniqueId()).thenReturn(java.util.UUID.randomUUID());
|
||||
when(target.getType()).thenReturn(org.bukkit.entity.EntityType.ZOMBIE); when(target.getWorld()).thenReturn(a.world);
|
||||
when(target.getName()).thenReturn("Snapshot hostile");
|
||||
when(target.getPersistentDataContainer()).thenReturn(new org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer(
|
||||
new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry()));
|
||||
when(target.getLocation()).thenReturn(new org.bukkit.Location(a.world, 2, 65.6, 0)); when(target.addPotionEffect(any())).thenReturn(true);
|
||||
var damages = new java.util.ArrayList<Double>();
|
||||
doAnswer(call -> {
|
||||
damages.add(call.getArgument(0)); var source = call.getArgument(1, org.bukkit.damage.DamageSource.class);
|
||||
f.dispatcher.accept(new org.bukkit.event.entity.EntityDamageByEntityEvent(source.getDirectEntity(), target,
|
||||
f.dispatcher.accept(new org.bukkit.event.entity.EntityDamageByEntityEvent(damages.size() == 1 ? oldProjectile : newProjectile, target,
|
||||
org.bukkit.event.entity.EntityDamageEvent.DamageCause.PROJECTILE, source, (Double) call.getArgument(0)));
|
||||
return null;
|
||||
}).when(target).damage(anyDouble(), any(org.bukkit.damage.DamageSource.class));
|
||||
f.dispatcher.accept(new org.bukkit.event.entity.ProjectileHitEvent(oldProjectile, target));
|
||||
cast(f, a); f.dispatcher.accept(new org.bukkit.event.entity.ProjectileHitEvent(newProjectile, target));
|
||||
assertEquals(java.util.List.of(5.0, 10.0), damages);
|
||||
assertEquals(java.util.List.of(20.0, 40.0), damages);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,25 +47,32 @@ class FrostShardRangeNativeTest {
|
||||
|
||||
static java.util.stream.Stream<org.junit.jupiter.params.provider.Arguments> distantCases() {
|
||||
return java.util.stream.Stream.of(
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "", "hit"),
|
||||
org.junit.jupiter.params.provider.Arguments.of(48.0, "", "hit"),
|
||||
org.junit.jupiter.params.provider.Arguments.of(48.01, "", "miss"),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "retained", "expired"),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "snapshot", "expired"),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "cancelled", "cancelled"),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "obstructed", "miss"),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "empty", "expired"));
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "", "hit", 12, 4, 20),
|
||||
org.junit.jupiter.params.provider.Arguments.of(48.0, "", "hit", 12, 4, 20),
|
||||
org.junit.jupiter.params.provider.Arguments.of(48.01, "", "miss", 12, 4, 20),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "retained", "expired", 12, 4, 20),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "snapshot", "expired", 12, 4, 20),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "cancelled", "cancelled", 12, 4, 20),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "obstructed", "miss", 12, 4, 20),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "empty", "expired", 12, 4, 20),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "", "hit", 20, 4, 36),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "", "hit", 21, 4, 36),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "", "hit", 12, 9, 40),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "mitigated", "hit", 20, 9, 56),
|
||||
org.junit.jupiter.params.provider.Arguments.of(36.0, "zero", "miss", 12, 4, 20));
|
||||
}
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.MethodSource("distantCases")
|
||||
void bookEquippedRealArrowFlightNativeDistantImpactSlowAndTruthfulJsonl(double distance, String mode, String outcome) throws Exception {
|
||||
void bookEquippedRealArrowFlightNativeDistantImpactSlowAndTruthfulJsonl(double distance, String mode, String outcome,
|
||||
int intelligence, int base, double requestedDamage) throws Exception {
|
||||
boolean retained = mode.equals("retained") || mode.equals("snapshot");
|
||||
java.nio.file.Files.writeString(data.resolve("config.yml"), "adventure-daily-site-count: 0\n"
|
||||
String retainedConfiguration = "adventure-daily-site-count: 0\nfrost-shard-base-damage: " + base + "\n"
|
||||
+ (retained ? "frost-shard-range-blocks: 32\n" : "")
|
||||
+ (mode.equals("snapshot") ? "frost-shard-cooldown-seconds: 0\n" : ""));
|
||||
+ (mode.equals("snapshot") ? "frost-shard-cooldown-seconds: 0\n" : "");
|
||||
java.nio.file.Files.writeString(data.resolve("config.yml"), retainedConfiguration);
|
||||
try (var f = new FantasyStickLifecycleNativeTest.Fixture(data)) {
|
||||
f.plugin.setEnabled(true);
|
||||
var actor = new FantasyStickLifecycleNativeTest.Actor(data); seed(actor);
|
||||
var actor = new FantasyStickLifecycleNativeTest.Actor(data); seed(actor, intelligence);
|
||||
f.players.put(actor.core.id, actor.player); f.activate(actor);
|
||||
actor.core.inventory.getInventory().setSelectedSlot(0); PartyBookNativeTest.open(f, actor);
|
||||
String book = PartyBookNativeTest.text(actor).replaceAll("\\s+", "");
|
||||
@@ -121,6 +128,8 @@ class FrostShardRangeNativeTest {
|
||||
var event = new org.bukkit.event.entity.EntityDamageByEntityEvent(source.getDirectEntity(), target,
|
||||
org.bukkit.event.entity.EntityDamageEvent.DamageCause.PROJECTILE, source, (Double) call.getArgument(0));
|
||||
damageEvents.add(event); if (mode.equals("cancelled")) event.setCancelled(true);
|
||||
if (mode.equals("mitigated")) event.setDamage(event.getDamage() / 2);
|
||||
if (mode.equals("zero")) event.setDamage(0);
|
||||
f.dispatcher.accept(event); return null;
|
||||
}).when(target).damage(anyDouble(), any(org.bukkit.damage.DamageSource.class));
|
||||
nativeArrow.delivery = result -> {
|
||||
@@ -162,11 +171,14 @@ class FrostShardRangeNativeTest {
|
||||
}
|
||||
assertTrue(nativeArrow.isRemoved(), "impact or captured range expiry must physically discard owned Arrow");
|
||||
boolean accepted = outcome.equals("hit");
|
||||
assertEquals(accepted || mode.equals("cancelled") ? 1 : 0, damageEvents.size(), "only actual in-range native collision may attempt damage");
|
||||
assertEquals(accepted || mode.equals("cancelled") || mode.equals("zero") ? 1 : 0, damageEvents.size(),
|
||||
"only actual in-range native collision may attempt damage");
|
||||
double finalDamage = mode.equals("mitigated") ? requestedDamage / 2 : requestedDamage;
|
||||
if (!damageEvents.isEmpty()) verify(target, times(1)).damage(eq(requestedDamage), any(org.bukkit.damage.DamageSource.class));
|
||||
if (accepted) {
|
||||
assertNotNull(nativeArrow.hit); assertEquals(HitResult.Type.ENTITY, nativeArrow.hit.getType());
|
||||
assertEquals(distance, nativeArrow.position().distanceTo(origin), 1e-9);
|
||||
assertEquals(5, damageEvents.getFirst().getFinalDamage()); assertFalse(damageEvents.getFirst().isCancelled());
|
||||
assertEquals(finalDamage, damageEvents.getFirst().getFinalDamage()); assertFalse(damageEvents.getFirst().isCancelled());
|
||||
assertSame(actor.player, damageEvents.getFirst().getDamageSource().getCausingEntity());
|
||||
assertSame(bukkit, damageEvents.getFirst().getDamageSource().getDirectEntity());
|
||||
assertNotNull(slow.get()); assertEquals(40, slow.get().getDuration()); assertEquals(0, slow.get().getAmplifier());
|
||||
@@ -187,12 +199,18 @@ class FrostShardRangeNativeTest {
|
||||
var capture = rows("ability.cast").getFirst().getAsJsonObject("data");
|
||||
assertEquals(retained ? "32" : "48", capture.getAsJsonObject("captured_settings").get("range").getAsString());
|
||||
assertTrue(book.contains((retained ? "32" : "48") + "-blocktravellimit"), "real book must explain captured effective reach");
|
||||
assertEquals(Integer.toString(intelligence), capture.get("captured_int").getAsString());
|
||||
assertEquals(Integer.toString(base), capture.getAsJsonObject("captured_settings").get("base-damage").getAsString());
|
||||
assertTrue(book.contains("4*(" + base + "+INTmodifier)"), "book must expose the effective full fourfold formula");
|
||||
if (!mode.equals("snapshot")) assertEquals(retainedConfiguration, java.nio.file.Files.readString(data.resolve("config.yml")),
|
||||
"loading and casting must not rewrite retained configured bases");
|
||||
if (accepted) {
|
||||
var damage = rows("combat.damage").getFirst().getAsJsonObject("data");
|
||||
assertEquals(capture.get("execution_id"), damage.get("execution_id"));
|
||||
assertEquals(bukkit.getUniqueId().toString(), damage.get("projectile_id").getAsString());
|
||||
assertEquals(nativeArrow.getX(), damage.getAsJsonObject("impact_location").get("x").getAsDouble(), 1e-9);
|
||||
assertEquals(5, damage.get("actual_amount").getAsDouble());
|
||||
assertEquals(requestedDamage, damage.get("requested_amount").getAsDouble());
|
||||
assertEquals(finalDamage, damage.get("actual_amount").getAsDouble());
|
||||
}
|
||||
if (mode.equals("snapshot")) {
|
||||
var next = new CollisionArrow(actor.world.getHandle());
|
||||
@@ -282,10 +300,10 @@ class FrostShardRangeNativeTest {
|
||||
throw new AssertionError("bounded actual native flight cannot reach fixture collision face");
|
||||
} finally { oracle.discard(); }
|
||||
}
|
||||
private void seed(FantasyStickLifecycleNativeTest.Actor actor) throws Exception {
|
||||
private void seed(FantasyStickLifecycleNativeTest.Actor actor, int intelligence) throws Exception {
|
||||
var repository = new games.dmg.fantasystick.persistence.YamlCharacterRepository(data); var old = repository.load(actor.core.record.id()).orElseThrow();
|
||||
var stats = new java.util.EnumMap<>(old.stats());
|
||||
stats.put(games.dmg.fantasystick.progression.Stat.INT, java.math.BigInteger.valueOf(12));
|
||||
stats.put(games.dmg.fantasystick.progression.Stat.INT, java.math.BigInteger.valueOf(intelligence));
|
||||
stats.put(games.dmg.fantasystick.progression.Stat.WIS, java.math.BigInteger.TEN);
|
||||
repository.replace(new games.dmg.fantasystick.persistence.CharacterRecord(old.id(), old.name(), old.revision().add(java.math.BigInteger.ONE), stats,
|
||||
old.level(), old.experience(), java.math.BigInteger.valueOf(40), old.health(), old.learned(), old.loadout(), old.cooldowns(), old.restrictedKills(), false, null, null), old.revision());
|
||||
|
||||
@@ -227,6 +227,8 @@ class TrainingDummyEventsNativeTest {
|
||||
var event = new org.bukkit.event.entity.EntityDamageByEntityEvent(arrow, ports.entity(),
|
||||
org.bukkit.event.entity.EntityDamageEvent.DamageCause.PROJECTILE, (org.bukkit.damage.DamageSource) call.getArgument(1), (Double) call.getArgument(0));
|
||||
assertSame(arrow, event.getDamageSource().getDirectEntity(), "The typed native source must retain the actual owned projectile");
|
||||
assertEquals(abilityId.equals("frost_shard") ? 20.0 : 7.0, event.getDamage(),
|
||||
"Frost Shard multiplies once before native modification; Fireball and Longbow remain unchanged");
|
||||
event.setDamage(4.875); hits.add(event); f.dispatcher.accept(event); return null;
|
||||
}).when(ports.entity()).damage(anyDouble(), any(org.bukkit.damage.DamageSource.class));
|
||||
clearInvocations(ports.entity()); player.core.inventory.getInventory().setSelectedSlot(2);
|
||||
|
||||
Reference in new issue
Block a user