Skip to content

Commit

Permalink
feat(fight): Handle trap damage boost (Arakne#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
vincent4vx committed May 30, 2023
1 parent ace8f43 commit dae1e31
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,13 @@ private Damage computeDamage(Fighter caster, SpellEffect effect, Fighter target)
.fixed(caster.characteristics().get(Characteristic.FIXED_DAMAGE))
;

if (effect.trap()) {
value
.fixed(caster.characteristics().get(Characteristic.TRAP_BOOST))
.percent(caster.characteristics().get(Characteristic.PERCENT_TRAP_BOOST))
;
}

return createDamage(caster, target, value.value());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@
import fr.quatrevieux.araknemu.game.fight.map.BattlefieldObject;
import fr.quatrevieux.araknemu.game.fight.map.FightCell;
import fr.quatrevieux.araknemu.game.spell.Spell;
import fr.quatrevieux.araknemu.game.spell.effect.SpellEffect;
import fr.quatrevieux.araknemu.game.spell.effect.area.SpellEffectArea;
import fr.quatrevieux.araknemu.game.spell.effect.target.EffectTarget;
import fr.quatrevieux.araknemu.game.world.util.Sender;
import fr.quatrevieux.araknemu.network.game.out.fight.action.ActionEffect;
import fr.quatrevieux.araknemu.network.game.out.fight.battlefield.AddZones;
import fr.quatrevieux.araknemu.network.game.out.fight.battlefield.RemoveZone;
import fr.quatrevieux.araknemu.network.game.out.game.UpdateCells;
import org.checkerframework.checker.index.qual.GTENegativeOne;
import org.checkerframework.checker.index.qual.NonNegative;

import java.util.List;

/**
* Trap object, created by {@link AddTrapHandler}
*
Expand Down Expand Up @@ -102,7 +108,7 @@ public void onEnterInArea(Fighter fighter) {
caster,
cell,
cell,
effectSpell.effects()
TrapSpellEffect.convert(effectSpell.effects())
);

fight.send(ActionEffect.trapTriggered(caster, fighter, cell, trapSpell));
Expand Down Expand Up @@ -152,4 +158,77 @@ public void sendPackets(Sender destination, Fighter caster) {
destination.send(ActionEffect.packet(caster, new AddZones(this)));
destination.send(ActionEffect.packet(caster, new UpdateCells(UpdateCells.Data.fromProperties(cell.id(), true, cellsProperties()))));
}

private static class TrapSpellEffect implements SpellEffect {
private final SpellEffect effect;

public TrapSpellEffect(SpellEffect effect) {
this.effect = effect;
}

@Override
public int effect() {
return effect.effect();
}

@Override
public @NonNegative int min() {
return effect.min();
}

@Override
public @NonNegative int max() {
return effect.max();
}

@Override
public int boost() {
return effect.boost();
}

@Override
public int special() {
return effect.special();
}

@Override
public @GTENegativeOne int duration() {
return effect.duration();
}

@Override
public @NonNegative int probability() {
return effect.probability();
}

@Override
public String text() {
return effect.text();
}

@Override
public SpellEffectArea area() {
return effect.area();
}

@Override
public EffectTarget target() {
return effect.target();
}

@Override
public boolean trap() {
return true;
}

/**
* Convert raw spell effects to trap spell effects
*/
public static List<SpellEffect> convert(List<SpellEffect> effects) {
return effects.stream()
.map(TrapSpellEffect::new)
.collect(java.util.stream.Collectors.toList())
;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,14 @@ public default int boost() {
* Get the effect target
*/
public EffectTarget target();

/**
* Does the current effect is from a triggered trap ?
*
* If true, {@link fr.quatrevieux.araknemu.data.constant.Characteristic#TRAP_BOOST} and {@link fr.quatrevieux.araknemu.data.constant.Characteristic#PERCENT_TRAP_BOOST}
* should be used to compute the final effect value
*/
public default boolean trap() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,24 @@ void applyWithBoost() {
assertEquals(-27, value);
}

@Test
void applyWithTrapBoost() {
SpellEffect effect = Mockito.mock(SpellEffect.class);

Mockito.when(effect.min()).thenReturn(10);

DamageApplier applier = new DamageApplier(Element.AIR, fight);

player.properties().characteristics().base().set(Characteristic.AGILITY, 50);
player.properties().characteristics().base().set(Characteristic.PERCENT_TRAP_BOOST, 25);
player.properties().characteristics().base().set(Characteristic.TRAP_BOOST, 10);

assertEquals(-15, applier.apply(caster, effect, target)); // Without trap boost

Mockito.when(effect.trap()).thenReturn(true);
assertEquals(-27, applier.apply(caster, effect, target)); // With trap boost
}

@Test
void applyWithResistance() {
SpellEffect effect = Mockito.mock(SpellEffect.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package fr.quatrevieux.araknemu.game.fight.castable.effect.handler.object;

import fr.quatrevieux.araknemu.data.constant.Characteristic;
import fr.quatrevieux.araknemu.game.fight.Fight;
import fr.quatrevieux.araknemu.game.fight.FightBaseCase;
import fr.quatrevieux.araknemu.game.fight.fighter.player.PlayerFighter;
Expand Down Expand Up @@ -167,6 +168,68 @@ void onEnterInArea() {
);
}

@Test
void trapDamageShouldBeUsed() {
caster.characteristics().alter(Characteristic.TRAP_BOOST, 10);

requestStack.clear();
Trap trap = new Trap(
fight,
fight.map().get(123),
caster,
2,
4,
container.get(SpellService.class).get(65).level(3),
container.get(SpellService.class).get(183).level(3)
);
fight.map().objects().add(trap);

trap.onEnterInArea(target);

int damage = target.life().max() - target.life().current();

assertBetween(19, 25, damage);
assertEquals(0, fight.map().objects().stream().count());

requestStack.assertAll(
ActionEffect.trapTriggered(caster, target, fight.map().get(123), container.get(SpellService.class).get(65).level(3)),
new RemoveZone(trap),
new UpdateCells(UpdateCells.Data.reset(123)),
ActionEffect.alterLifePoints(caster, target, -damage)
);
}

@Test
void trapPercentDamageShouldBeUsed() {
caster.characteristics().alter(Characteristic.PERCENT_TRAP_BOOST, 150);

requestStack.clear();
Trap trap = new Trap(
fight,
fight.map().get(123),
caster,
2,
4,
container.get(SpellService.class).get(65).level(3),
container.get(SpellService.class).get(183).level(3)
);
fight.map().objects().add(trap);

trap.onEnterInArea(target);

int damage = target.life().max() - target.life().current();

assertBetween(18, 30, damage);
assertEquals(0, fight.map().objects().stream().count());

requestStack.assertAll(
ActionEffect.trapTriggered(caster, target, fight.map().get(123), container.get(SpellService.class).get(65).level(3)),
new RemoveZone(trap),
new UpdateCells(UpdateCells.Data.reset(123)),
ActionEffect.alterLifePoints(caster, target, -damage)
);
}

@Test
void isOnArea() {
Trap trap = new Trap(
Expand Down

0 comments on commit dae1e31

Please sign in to comment.