Skip to content

Commit

Permalink
feat(fight): Fix invocation effect (Arakne#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
vincent4vx committed Sep 15, 2022
1 parent 00b6bbc commit 1a2feb6
Show file tree
Hide file tree
Showing 46 changed files with 1,401 additions and 428 deletions.
2 changes: 1 addition & 1 deletion checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@
<!-- Ignore fight classes -->
<module name="SuppressionSingleFilter">
<property name="checks" value="MethodCountCheck" />
<property name="files" value="game.fight.Fight" />
<property name="files" value="(game.fight.Fight|out.fight.action.ActionEffect)" />
</module>
<module name="SuppressionSingleFilter">
<property name="checks" value="ParameterNumberCheck" />
Expand Down
45 changes: 23 additions & 22 deletions src/main/java/fr/quatrevieux/araknemu/game/fight/Fight.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
import fr.quatrevieux.araknemu.game.fight.event.FightStopped;
import fr.quatrevieux.araknemu.game.fight.exception.InvalidFightStateException;
import fr.quatrevieux.araknemu.game.fight.fighter.Fighter;
import fr.quatrevieux.araknemu.game.fight.fighter.monster.InvocationFighterFactory;
import fr.quatrevieux.araknemu.game.fight.map.FightCell;
import fr.quatrevieux.araknemu.game.fight.map.FightMap;
import fr.quatrevieux.araknemu.game.fight.module.FightModule;
import fr.quatrevieux.araknemu.game.fight.spectator.Spectators;
Expand All @@ -57,6 +55,7 @@
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* Handle fight
Expand Down Expand Up @@ -96,7 +95,7 @@ public Fight(int id, FightType type, FightMap map, List<FightTeam> teams, States
this.spectators = new Spectators(this);
this.actions = actions;

teams.forEach(team -> team.setFight(this));
teams.forEach(team -> team.setFight(this)); // @todo team factory ?
}

/**
Expand Down Expand Up @@ -135,9 +134,12 @@ public FightTeam team(int number) {
* Get all fighters on the fight
*/
public List<Fighter> fighters() {
return teams
.stream()
.flatMap(fightTeam -> fightTeam.fighters().stream())
final Stream<Fighter> fighterStream = turnList.isInitialized()
? turnList.fighters().stream()
: teams.stream().flatMap(fightTeam -> fightTeam.fighters().stream())
;

return fighterStream
.filter(Fighter::isOnFight)
.collect(Collectors.toList())
;
Expand All @@ -153,6 +155,10 @@ public List<Fighter> fighters(boolean onlyInitialized) {
return fighters();
}

if (turnList.isInitialized()) {
return turnList.fighters();
}

return teams
.stream()
.flatMap(fightTeam -> fightTeam.fighters().stream())
Expand Down Expand Up @@ -252,10 +258,17 @@ public void dispatch(Object event) {
* @see Fight#dispatch(Object) To dispatch on the Fight's listeners
*/
public void dispatchToAll(Object event) {
for (FightTeam team : teams) {
for (Fighter fighter : team.fighters()) {
if (fighter.isOnFight()) {
fighter.dispatch(event);
if (turnList.isInitialized()) {
turnList.fighters().stream()
.filter(Fighter::isOnFight)
.forEach(fighter -> fighter.dispatch(event))
;
} else {
for (FightTeam team : teams) {
for (Fighter fighter : team.fighters()) {
if (fighter.isOnFight()) {
fighter.dispatch(event);
}
}
}
}
Expand Down Expand Up @@ -428,16 +441,4 @@ public void run() {
}
}
}

public Fighter addInvocation(InvocationFighterFactory factory, FightCell cell) {
final Fighter invocation = factory.create(fighters().stream().mapToInt(Fighter::id).min().getAsInt() - 1);

invocation.joinFight(this, cell);
turnList.currentFighter().team().join(invocation);
turnList.add(invocation);

invocation.init();

return invocation;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import fr.quatrevieux.araknemu.game.fight.ai.AI;
import fr.quatrevieux.araknemu.game.fight.fighter.Fighter;
import fr.quatrevieux.araknemu.game.fight.fighter.invocation.InvocationFighter;
import fr.quatrevieux.araknemu.game.fight.fighter.monster.MonsterFighter;
import fr.quatrevieux.araknemu.game.fight.fighter.operation.FighterOperation;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
Expand Down Expand Up @@ -49,20 +50,29 @@ class ResolveAi implements FighterOperation {

@Override
public void onMonster(MonsterFighter fighter) {
final AiFactory<Fighter> factory = factories.get(fighter.monster().ai());
resolve(fighter, fighter.monster().ai());
}

@Override
public void onInvocation(InvocationFighter fighter) {
resolve(fighter, fighter.monster().ai());
}

public Optional<AI<Fighter>> get() {
return Optional.ofNullable(ai);
}

private void resolve(Fighter fighter, String type) {
final AiFactory<Fighter> factory = factories.get(type);

if (factory == null) {
throw new IllegalArgumentException("Unsupported AI type " + fighter.monster().ai());
throw new IllegalArgumentException("Unsupported AI type " + type);
}

factory
.create(fighter)
.ifPresent(ai -> this.ai = ai)
;
}

public Optional<AI<Fighter>> get() {
return Optional.ofNullable(ai);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
import fr.quatrevieux.araknemu.game.fight.turn.Turn;
import org.checkerframework.checker.index.qual.NonNegative;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.WeakHashMap;
import java.util.stream.Stream;

/**
Expand All @@ -44,7 +44,7 @@ public final class ProxyAI implements AI<ActiveFighter> {
private ProxyActiveFighter fighter;
private ProxyTurn turn;

private final Map<PassiveFighter, PassiveFighter> fighters = new HashMap<>();
private final Map<PassiveFighter, PassiveFighter> fighters = new WeakHashMap<>();

public ProxyAI(AI<?> ai) {
this.ai = ai;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public Fight build(int fightId) {
startPlaces,
number
));
builder.addTeam((number, startPlaces) -> new MonsterGroupTeam(group, startPlaces, number));
builder.addTeam((number, startPlaces) -> new MonsterGroupTeam(group, startPlaces, number, fighterFactory));

return builder.build(fightId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,50 +19,60 @@

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

import java.util.Collections;

import fr.quatrevieux.araknemu.game.fight.Fight;
import fr.quatrevieux.araknemu.game.fight.castable.CastScope;
import fr.quatrevieux.araknemu.game.fight.castable.CastScope.EffectScope;
import fr.quatrevieux.araknemu.game.fight.castable.effect.handler.EffectHandler;
import fr.quatrevieux.araknemu.game.fight.fighter.Fighter;
import fr.quatrevieux.araknemu.game.fight.fighter.monster.InvocationFighter;
import fr.quatrevieux.araknemu.game.fight.fighter.monster.MonsterFighter;
import fr.quatrevieux.araknemu.game.fight.fighter.FighterFactory;
import fr.quatrevieux.araknemu.game.fight.fighter.invocation.InvocationFighter;
import fr.quatrevieux.araknemu.game.fight.team.FightTeam;
import fr.quatrevieux.araknemu.game.monster.MonsterService;
import fr.quatrevieux.araknemu.network.game.out.fight.action.ActionEffect;
import fr.quatrevieux.araknemu.network.game.out.fight.turn.FighterTurnOrder;
import fr.quatrevieux.araknemu.network.game.out.game.AddSprites;

final public class MonsterInvocationHandler implements EffectHandler {
final private MonsterService monsterService;
final private Fight fight;
/**
* Handle monster invocation
*
* A new fighter will be created and added to fight and timeline (turn list)
*
* Effect parameters :
* - #1 (min) : monster id
* - #2 (max) : grade number
*
* @see InvocationFighter Invoked fighter
*/
public final class MonsterInvocationHandler implements EffectHandler {
private final MonsterService monsterService;
private final FighterFactory fighterFactory;
private final Fight fight;

public MonsterInvocationHandler(MonsterService monsterService, Fight fight) {
public MonsterInvocationHandler(MonsterService monsterService, FighterFactory fighterFactory, Fight fight) {
this.monsterService = monsterService;
this.fighterFactory = fighterFactory;
this.fight = fight;
}

@Override
public void buff(CastScope cast, EffectScope effect) {
addMonsterToFight(cast, effect); // sadida lvl 100 puppet hit here
handle(cast, effect);
}

@Override
public void handle(CastScope cast, EffectScope effect) {
addMonsterToFight(cast, effect); // normal invocations
}

private void addMonsterToFight(CastScope cast, EffectScope effect) {
final Fighter invocation = fight.addInvocation((id) -> new InvocationFighter(
new MonsterFighter(
id,
monsterService.load(effect.effect().min()).get(effect.effect().max()),
fight.turnList().currentFighter().team()
),
final Fighter invocation = fighterFactory.generate(id -> new InvocationFighter(
id,
monsterService.load(effect.effect().min()).get(effect.effect().max()),
(FightTeam) cast.caster().team(),
cast.caster()
), cast.target());
));

invocation.joinFight(fight, cast.target());
fight.turnList().add(invocation);

invocation.init();

fight.send(new ActionEffect(181, cast.caster(), (new AddSprites(Collections.singleton(invocation.sprite()))).toString()));
fight.send(new ActionEffect(999, cast.caster(), (new FighterTurnOrder(fight.turnList())).toString()));
fight.send(ActionEffect.addInvocation(cast.caster(), invocation));
fight.send(ActionEffect.packet(cast.caster(), new FighterTurnOrder(fight.turnList())));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@

import fr.quatrevieux.araknemu.core.event.Dispatcher;
import fr.quatrevieux.araknemu.game.fight.fighter.event.PlayerFighterCreated;
import fr.quatrevieux.araknemu.game.fight.fighter.monster.MonsterFighter;
import fr.quatrevieux.araknemu.game.fight.fighter.player.PlayerFighter;
import fr.quatrevieux.araknemu.game.fight.team.FightTeam;
import fr.quatrevieux.araknemu.game.listener.fight.SendFightJoined;
import fr.quatrevieux.araknemu.game.listener.fight.fighter.ApplyEndFightReward;
import fr.quatrevieux.araknemu.game.listener.fight.fighter.ApplyLeaveReward;
Expand All @@ -30,16 +32,28 @@
import fr.quatrevieux.araknemu.game.listener.fight.fighter.SendSpellBoosted;
import fr.quatrevieux.araknemu.game.listener.fight.fighter.SendStats;
import fr.quatrevieux.araknemu.game.listener.fight.fighter.StopFightSession;
import fr.quatrevieux.araknemu.game.monster.Monster;
import fr.quatrevieux.araknemu.game.player.GamePlayer;

import java.util.concurrent.atomic.AtomicInteger;

/**
* Default implementation of the fighter factory
*/
public final class DefaultFighterFactory implements FighterFactory {
private static final int MIN_ID = -1_000_000_000;

private final Dispatcher dispatcher;
private final AtomicInteger lastId = new AtomicInteger();
private final int minId;

public DefaultFighterFactory(Dispatcher dispatcher) {
this(dispatcher, MIN_ID);
}

public DefaultFighterFactory(Dispatcher dispatcher, int minId) {
this.dispatcher = dispatcher;
this.minId = minId;
}

@Override
Expand All @@ -59,4 +73,20 @@ public PlayerFighter create(GamePlayer player) {

return fighter;
}

@Override
public Fighter create(Monster monster, FightTeam team) {
return generate(id -> new MonsterFighter(id, monster, team));
}

@Override
public Fighter generate(FighterGenerator generator) {
final int id = lastId.updateAndGet(last -> {
final int next = last - 1;

return next < minId ? -1 : next;
});

return generator.create(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
package fr.quatrevieux.araknemu.game.fight.fighter;

import fr.quatrevieux.araknemu.game.fight.fighter.player.PlayerFighter;
import fr.quatrevieux.araknemu.game.fight.team.FightTeam;
import fr.quatrevieux.araknemu.game.fight.team.MonsterGroupTeam;
import fr.quatrevieux.araknemu.game.monster.Monster;
import fr.quatrevieux.araknemu.game.player.GamePlayer;

/**
Expand All @@ -34,4 +37,23 @@ public interface FighterFactory {
* @return The PlayerFighter
*/
public PlayerFighter create(GamePlayer player);

/**
* Create a monster fighter
* An unique ID will be generated for the fighter
*/
public Fighter create(Monster monster, FightTeam team);

/**
* Generate a fighter with a unique ID
* The generated ID will be a negative integer
*/
public Fighter generate(FighterGenerator generator);

public static interface FighterGenerator {
/**
* Create a fighter with a generated ID
*/
public Fighter create(int id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,10 @@ public default boolean dead() {
return life().dead();
}

/**
* Get the invoker fighter
*
* @todo nullable not optional
*/
public Optional<PassiveFighter> invoker();
}
Loading

0 comments on commit 1a2feb6

Please sign in to comment.