Skip to content

Commit

Permalink
feat(fight): Handle default close combat #43
Browse files Browse the repository at this point in the history
  • Loading branch information
vincent4vx committed Jan 6, 2024
1 parent 50fa1f8 commit aab5fb4
Show file tree
Hide file tree
Showing 41 changed files with 453 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import fr.arakne.utils.value.constant.Race;
import fr.quatrevieux.araknemu.data.value.BoostStatsData;
import fr.quatrevieux.araknemu.data.value.Position;
import fr.quatrevieux.araknemu.data.world.entity.SpellTemplate;
import fr.quatrevieux.araknemu.game.world.creature.characteristics.Characteristics;
import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.index.qual.Positive;
Expand All @@ -44,8 +45,9 @@ public final class PlayerRace {
private final Position startPosition;
private final Position astrubPosition;
private final int[] spells;
private final SpellTemplate.Level closeCombat;

public PlayerRace(Race race, String name, SortedMap<@Positive Integer, Characteristics> baseStats, int startDiscernment, @Positive int startPods, @Positive int startLife, @NonNegative int perLevelLife, BoostStatsData boostStats, Position startPosition, Position astrubPosition, int[] spells) {
public PlayerRace(Race race, String name, SortedMap<@Positive Integer, Characteristics> baseStats, int startDiscernment, @Positive int startPods, @Positive int startLife, @NonNegative int perLevelLife, BoostStatsData boostStats, Position startPosition, Position astrubPosition, int[] spells, SpellTemplate.Level closeCombat) {
this.race = race;
this.name = name;
this.baseStats = baseStats;
Expand All @@ -57,10 +59,11 @@ public PlayerRace(Race race, String name, SortedMap<@Positive Integer, Character
this.startPosition = startPosition;
this.astrubPosition = astrubPosition;
this.spells = spells;
this.closeCombat = closeCombat;
}

public PlayerRace(Race race) {
this(race, null, null, 0, 0, 0, 0, null, null, null, null);
this(race, null, null, 0, 0, 0, 0, null, null, null, null, null);
}

public Race race() {
Expand Down Expand Up @@ -140,4 +143,14 @@ public Position astrubPosition() {
public int[] spells() {
return spells;
}

/**
* Get the effect of the default close combat action
* This value is formatted like a spell effect
*
* Use this when the fighter has no equipped weapon
*/
public SpellTemplate.Level closeCombat() {
return closeCombat;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import fr.quatrevieux.araknemu.data.transformer.Transformer;
import fr.quatrevieux.araknemu.data.value.BoostStatsData;
import fr.quatrevieux.araknemu.data.value.Position;
import fr.quatrevieux.araknemu.data.world.entity.SpellTemplate;
import fr.quatrevieux.araknemu.data.world.entity.character.PlayerRace;
import fr.quatrevieux.araknemu.data.world.repository.character.PlayerRaceRepository;
import fr.quatrevieux.araknemu.game.world.creature.characteristics.Characteristics;
Expand All @@ -45,10 +46,12 @@ final class SqlPlayerRaceRepository implements PlayerRaceRepository {
private final RepositoryUtils<PlayerRace> utils;
private final Transformer<SortedMap<@Positive Integer, Characteristics>> characteristicsTransformer;
private final Transformer<BoostStatsData> boostStatsDataTransformer;
private final Transformer<SpellTemplate.Level> closeCombatTransformer;

public SqlPlayerRaceRepository(QueryExecutor executor, Transformer<SortedMap<@Positive Integer, Characteristics>> characteristicsTransformer, Transformer<BoostStatsData> boostStatsDataTransformer) {
public SqlPlayerRaceRepository(QueryExecutor executor, Transformer<SortedMap<@Positive Integer, Characteristics>> characteristicsTransformer, Transformer<BoostStatsData> boostStatsDataTransformer, Transformer<SpellTemplate.Level> closeCombatTransformer) {
this.characteristicsTransformer = characteristicsTransformer;
this.boostStatsDataTransformer = boostStatsDataTransformer;
this.closeCombatTransformer = closeCombatTransformer;

this.executor = executor;
utils = new RepositoryUtils<>(executor, new Loader());
Expand All @@ -71,7 +74,8 @@ public void initialize() throws RepositoryException {
"MAP_ID INTEGER," +
"CELL_ID INTEGER," +
"ASTRUB_MAP_ID INTEGER," +
"ASTRUB_CELL_ID INTEGER" +
"ASTRUB_CELL_ID INTEGER," +
"DEFAULT_CLOSE_COMBAT TEXT" +
")"
);
} catch (SQLException e) {
Expand Down Expand Up @@ -134,7 +138,8 @@ public PlayerRace create(Record record) throws SQLException {
record.getNonNegativeInt("ASTRUB_MAP_ID"),
record.getNonNegativeInt("ASTRUB_CELL_ID")
),
record.getIntArray("RACE_SPELLS", '|')
record.getIntArray("RACE_SPELLS", '|'),
record.unserialize("DEFAULT_CLOSE_COMBAT", closeCombatTransformer)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ public void configure(ContainerConfigurator configurator) {
new SqlPlayerRaceRepository(
executor,
container.get(RaceBaseStatsTransformer.class),
container.get(BoostStatsDataTransformer.class)
container.get(BoostStatsDataTransformer.class),
container.get(SpellTemplateLevelTransformer.class)
)
)
);
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/fr/quatrevieux/araknemu/game/GameModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@
import fr.quatrevieux.araknemu.game.fight.builder.PvmBuilderFactory;
import fr.quatrevieux.araknemu.game.fight.castable.effect.Element;
import fr.quatrevieux.araknemu.game.fight.castable.spell.SpellConstraintsValidator;
import fr.quatrevieux.araknemu.game.fight.castable.weapon.WeaponConstraintsValidator;
import fr.quatrevieux.araknemu.game.fight.castable.closeCombat.CloseCombatValidator;
import fr.quatrevieux.araknemu.game.fight.ending.reward.drop.action.AddExperience;
import fr.quatrevieux.araknemu.game.fight.ending.reward.drop.action.AddItems;
import fr.quatrevieux.araknemu.game.fight.ending.reward.drop.action.AddKamas;
Expand Down Expand Up @@ -615,7 +615,8 @@ private void configureServices(ContainerConfigurator configurator) {
PlayerRaceService.class,
container -> new PlayerRaceService(
container.get(PlayerRaceRepository.class),
container.get(SpellService.class)
container.get(SpellService.class),
container.get(SpellEffectService.class)
)
);

Expand Down Expand Up @@ -654,7 +655,7 @@ private void configureServices(ContainerConfigurator configurator) {
container.get(CriticalityStrategy.class)
),
new CloseCombatFactory(
new WeaponConstraintsValidator(fight),
new CloseCombatValidator(fight),
container.get(CriticalityStrategy.class)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* Copyright (c) 2017-2019 Vincent Quatrevieux
*/

package fr.quatrevieux.araknemu.game.fight.castable.weapon;
package fr.quatrevieux.araknemu.game.fight.castable.closeCombat;

import fr.quatrevieux.araknemu.game.fight.castable.Castable;
import fr.quatrevieux.araknemu.game.item.type.Weapon;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* Copyright (c) 2017-2019 Vincent Quatrevieux
*/

package fr.quatrevieux.araknemu.game.fight.castable.weapon;
package fr.quatrevieux.araknemu.game.fight.castable.closeCombat;

import fr.quatrevieux.araknemu.game.item.effect.WeaponEffect;
import fr.quatrevieux.araknemu.game.item.type.Weapon;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
* Copyright (c) 2017-2020 Vincent Quatrevieux
*/

package fr.quatrevieux.araknemu.game.fight.castable.weapon;
package fr.quatrevieux.araknemu.game.fight.castable.closeCombat;

import fr.quatrevieux.araknemu.game.fight.Fight;
import fr.quatrevieux.araknemu.game.fight.castable.Castable;
import fr.quatrevieux.araknemu.game.fight.castable.validator.ApCostValidator;
import fr.quatrevieux.araknemu.game.fight.castable.validator.CastConstraintValidator;
import fr.quatrevieux.araknemu.game.fight.castable.validator.ConstraintsAggregateValidator;
Expand All @@ -33,13 +34,16 @@
import org.checkerframework.checker.nullness.qual.Nullable;

/**
* Validate weapon cast constraints
* Validate weapon or default close combat cast constraints
*
* @see CastableWeapon
* @see fr.quatrevieux.araknemu.game.player.race.DefaultCloseCombat
*/
public final class WeaponConstraintsValidator implements CastConstraintValidator<CastableWeapon> {
private final CastConstraintValidator<CastableWeapon> validator;
public final class CloseCombatValidator implements CastConstraintValidator<Castable> {
private final CastConstraintValidator<Castable> validator;

@SuppressWarnings("unchecked")
public WeaponConstraintsValidator(Fight fight) {
public CloseCombatValidator(Fight fight) {
this(new CastConstraintValidator[] {
new ApCostValidator(),
new TargetCellValidator(),
Expand All @@ -50,17 +54,17 @@ public WeaponConstraintsValidator(Fight fight) {
});
}

public WeaponConstraintsValidator(CastConstraintValidator<? super CastableWeapon>[] validators) {
public CloseCombatValidator(CastConstraintValidator<? super Castable>[] validators) {
this.validator = new ConstraintsAggregateValidator<>(validators);
}

@Override
public boolean check(Turn turn, CastableWeapon castable, BattlefieldCell target) {
public boolean check(Turn turn, Castable castable, BattlefieldCell target) {
return validator.check(turn, castable, target);
}

@Override
public @Nullable Object validate(Turn turn, CastableWeapon weapon, BattlefieldCell target) {
public @Nullable Object validate(Turn turn, Castable weapon, BattlefieldCell target) {
return validator.validate(turn, weapon, target);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* Copyright (c) 2017-2020 Vincent Quatrevieux
*/

package fr.quatrevieux.araknemu.game.fight.castable.weapon;
package fr.quatrevieux.araknemu.game.fight.castable.closeCombat;

import fr.arakne.utils.value.Interval;
import fr.quatrevieux.araknemu.game.item.type.Weapon;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* Copyright (c) 2017-2019 Vincent Quatrevieux
*/

package fr.quatrevieux.araknemu.game.fight.castable.weapon;
package fr.quatrevieux.araknemu.game.fight.castable.closeCombat;

import fr.quatrevieux.araknemu.game.fight.fighter.FighterData;
import fr.quatrevieux.araknemu.game.spell.effect.target.EffectTarget;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
import fr.quatrevieux.araknemu.core.event.Dispatcher;
import fr.quatrevieux.araknemu.game.fight.Fight;
import fr.quatrevieux.araknemu.game.fight.FighterSprite;
import fr.quatrevieux.araknemu.game.fight.castable.Castable;
import fr.quatrevieux.araknemu.game.fight.castable.effect.buff.BuffList;
import fr.quatrevieux.araknemu.game.fight.castable.weapon.CastableWeapon;
import fr.quatrevieux.araknemu.game.fight.castable.closeCombat.CastableWeapon;
import fr.quatrevieux.araknemu.game.fight.fighter.operation.FighterOperation;
import fr.quatrevieux.araknemu.game.fight.map.FightCell;
import fr.quatrevieux.araknemu.game.fight.team.FightTeam;
Expand Down Expand Up @@ -87,11 +88,12 @@ public default boolean dead() {
public void setHidden(Fighter caster, boolean hidden);

/**
* Get the weapon
* Get the close combat action
* Usually, this method will return the {@link CastableWeapon} of the fighter
*
* @throws fr.quatrevieux.araknemu.game.fight.exception.FightException When cannot get any weapon on the fighter
*/
public CastableWeapon weapon();
public Castable closeCombat();

/**
* Does the current fighter can play ?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
package fr.quatrevieux.araknemu.game.fight.fighter.invocation;

import fr.quatrevieux.araknemu.game.fight.FighterSprite;
import fr.quatrevieux.araknemu.game.fight.castable.weapon.CastableWeapon;
import fr.quatrevieux.araknemu.game.fight.castable.Castable;
import fr.quatrevieux.araknemu.game.fight.exception.FightException;
import fr.quatrevieux.araknemu.game.fight.fighter.AbstractPlayableFighter;
import fr.quatrevieux.araknemu.game.fight.fighter.BaseFighterLife;
Expand Down Expand Up @@ -82,7 +82,7 @@ public FightTeam team() {
}

@Override
public CastableWeapon weapon() {
public Castable closeCombat() {
throw new FightException("The fighter do not have any weapon");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
package fr.quatrevieux.araknemu.game.fight.fighter.invocation;

import fr.quatrevieux.araknemu.game.fight.FighterSprite;
import fr.quatrevieux.araknemu.game.fight.castable.weapon.CastableWeapon;
import fr.quatrevieux.araknemu.game.fight.castable.Castable;
import fr.quatrevieux.araknemu.game.fight.exception.FightException;
import fr.quatrevieux.araknemu.game.fight.fighter.AbstractPlayableFighter;
import fr.quatrevieux.araknemu.game.fight.fighter.BaseFighterLife;
Expand Down Expand Up @@ -88,7 +88,7 @@ public FightTeam team() {
}

@Override
public CastableWeapon weapon() {
public Castable closeCombat() {
throw new FightException("The fighter do not have any weapon");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
package fr.quatrevieux.araknemu.game.fight.fighter.invocation;

import fr.quatrevieux.araknemu.game.fight.FighterSprite;
import fr.quatrevieux.araknemu.game.fight.castable.weapon.CastableWeapon;
import fr.quatrevieux.araknemu.game.fight.castable.Castable;
import fr.quatrevieux.araknemu.game.fight.exception.FightException;
import fr.quatrevieux.araknemu.game.fight.fighter.AbstractFighter;
import fr.quatrevieux.araknemu.game.fight.fighter.BaseFighterLife;
Expand Down Expand Up @@ -86,7 +86,7 @@ public FightTeam team() {
}

@Override
public CastableWeapon weapon() {
public Castable closeCombat() {
throw new FightException("The fighter do not have any weapon");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
package fr.quatrevieux.araknemu.game.fight.fighter.monster;

import fr.quatrevieux.araknemu.game.fight.FighterSprite;
import fr.quatrevieux.araknemu.game.fight.castable.weapon.CastableWeapon;
import fr.quatrevieux.araknemu.game.fight.castable.Castable;
import fr.quatrevieux.araknemu.game.fight.exception.FightException;
import fr.quatrevieux.araknemu.game.fight.fighter.AbstractPlayableFighter;
import fr.quatrevieux.araknemu.game.fight.fighter.BaseFighterLife;
Expand Down Expand Up @@ -85,7 +85,7 @@ public FighterSpellList spells() {
}

@Override
public CastableWeapon weapon() {
public Castable closeCombat() {
throw new FightException("The fighter do not have any weapon");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
package fr.quatrevieux.araknemu.game.fight.fighter.player;

import fr.quatrevieux.araknemu.game.fight.FighterSprite;
import fr.quatrevieux.araknemu.game.fight.castable.weapon.CastableWeapon;
import fr.quatrevieux.araknemu.game.fight.castable.Castable;
import fr.quatrevieux.araknemu.game.fight.castable.closeCombat.CastableWeapon;
import fr.quatrevieux.araknemu.game.fight.event.FighterReadyStateChanged;
import fr.quatrevieux.araknemu.game.fight.exception.FightException;
import fr.quatrevieux.araknemu.game.fight.fighter.AbstractPlayableFighter;
import fr.quatrevieux.araknemu.game.fight.fighter.BaseFighterSpellList;
import fr.quatrevieux.araknemu.game.fight.fighter.FighterCharacteristics;
Expand Down Expand Up @@ -51,7 +51,7 @@ public final class PlayerFighter extends AbstractPlayableFighter implements Play
private final FighterSpellList spells;

private boolean ready = false;
private @MonotonicNonNull CastableWeapon weapon;
private @MonotonicNonNull Castable closeCombat;
private @MonotonicNonNull FightTeam team;

@SuppressWarnings({"assignment", "argument", "method.invocation"})
Expand Down Expand Up @@ -136,17 +136,17 @@ public void unregister(GameSession session) {
}

@Override
public CastableWeapon weapon() {
if (weapon != null) {
return weapon;
public Castable closeCombat() {
if (closeCombat != null) {
return closeCombat;
}

return weapon = player.inventory()
return closeCombat = player.inventory()
.bySlot(WeaponSlot.SLOT_ID)
.map(InventoryEntry::item)
.map(Weapon.class::cast)
.map(CastableWeapon::new)
.orElseThrow(() -> new FightException("The fighter do not have any weapon"))
.<Castable>map(CastableWeapon::new)
.orElse(player.race().closeCombat())
;
}

Expand Down
Loading

0 comments on commit aab5fb4

Please sign in to comment.