Passed
Pull Request — master (#206)
by Vincent
12:05
created

applyCastTarget(CastScope)   B

Complexity

Conditions 6

Size

Total Lines 26
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 12
c 0
b 0
f 0
dl 0
loc 26
ccs 11
cts 11
cp 1
crap 6
rs 8.6666
1
/*
2
 * This file is part of Araknemu.
3
 *
4
 * Araknemu is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU Lesser General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * Araknemu is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public License
15
 * along with Araknemu.  If not, see <https://www.gnu.org/licenses/>.
16
 *
17
 * Copyright (c) 2017-2019 Vincent Quatrevieux
18
 */
19
20
package fr.quatrevieux.araknemu.game.fight.castable.effect;
21
22
import fr.quatrevieux.araknemu.game.fight.castable.CastScope;
23
import fr.quatrevieux.araknemu.game.fight.castable.effect.handler.EffectHandler;
24
import fr.quatrevieux.araknemu.game.fight.fighter.PassiveFighter;
25
26
import java.util.Collections;
27
import java.util.HashMap;
28
import java.util.Map;
29
import java.util.Set;
30
31
/**
32
 * Handle fight effects
33
 */
34 1
public final class EffectsHandler {
35 1
    private final Map<Integer, EffectHandler> handlers = new HashMap<>();
36
37
    public void register(int effectId, EffectHandler applier) {
38 1
        handlers.put(effectId, applier);
39 1
    }
40
41
    /**
42
     * Apply a cast to the fight
43
     */
44
    public void apply(CastScope cast) {
45 1
        applyCastTarget(cast);
46
47 1
        for (CastScope.EffectScope effect : cast.effects()) {
48
            // @todo Warning if handler is not found
0 ignored issues
show
introduced by
Comment matches to-do format '(TODO:)|(@todo )'.
Loading history...
49 1
            if (handlers.containsKey(effect.effect().effect())) {
50 1
                final EffectHandler handler = handlers.get(effect.effect().effect());
51
52 1
                if (effect.effect().duration() == 0) {
53 1
                    handler.handle(cast, effect);
54
                } else {
55 1
                    handler.buff(cast, effect);
56
                }
57
            }
58 1
        }
59 1
    }
60
61
    /**
62
     * Call {@link fr.quatrevieux.araknemu.game.fight.castable.effect.buff.Buffs#onCastTarget(CastScope)}
63
     * on each target.
64
     *
65
     * If a target is changed (by calling {@link CastScope#replaceTarget(PassiveFighter, PassiveFighter)}),
66
     * new targets will also be called
67
     */
68
    private void applyCastTarget(CastScope cast) {
69 1
        Set<PassiveFighter> visitedTargets = Collections.emptySet();
70
71
        for (;;) {
72 1
            final Set<PassiveFighter> currentTargets = cast.targets();
73
74 1
            boolean hasChanged = false;
75
76 1
            for (PassiveFighter target : currentTargets) {
77
                // Ignore already called targets
78 1
                if (!visitedTargets.contains(target)) {
79 1
                    if (!target.buffs().onCastTarget(cast)) {
80
                        // The hook notify a target change
81 1
                        hasChanged = true;
82
                    }
83
                }
84 1
            }
85
86
            // There is no new targets, we can stop here
87 1
            if (!hasChanged) {
88 1
                return;
89
            }
90
91
            // cast#targets() always contains all resolved targets, including removed ones
92
            // so simple change visitedTargets by this value is enough to keep track of all already called fighters
93 1
            visitedTargets = currentTargets;
94 1
        }
95
    }
96
}
97