Passed
Push — master ( f51b57...4bee7d )
by Vincent
04:18 queued 11s
created

fr.quatrevieux.araknemu.game.monster.environment.LivingMonsterGroupPosition   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 105
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 44
dl 0
loc 105
ccs 32
cts 32
cp 1
rs 10
c 1
b 0
f 0
wmc 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A spawn() 0 2 1
A fixed() 0 2 1
A groupStream() 0 5 1
A LivingMonsterGroupPosition(MonsterGroupFactory,MonsterEnvironmentService,FightService,MonsterGroupData,SpawnCellSelector,boo 0 7 1
A startFight(MonsterGroup,ExplorationPlayer) 0 10 1
A available() 0 6 2
A cell() 0 2 1
A populate(ExplorationMap) 0 6 2
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.monster.environment;
21
22
import fr.quatrevieux.araknemu.data.world.entity.monster.MonsterGroupData;
23
import fr.quatrevieux.araknemu.data.world.entity.monster.MonsterGroupPosition;
24
import fr.quatrevieux.araknemu.game.exploration.ExplorationPlayer;
25
import fr.quatrevieux.araknemu.game.exploration.map.ExplorationMap;
26
import fr.quatrevieux.araknemu.game.exploration.map.cell.ExplorationMapCell;
27
import fr.quatrevieux.araknemu.game.fight.Fight;
28
import fr.quatrevieux.araknemu.game.fight.FightService;
29
import fr.quatrevieux.araknemu.game.fight.builder.PvmBuilder;
30
import fr.quatrevieux.araknemu.game.monster.group.MonsterGroup;
31
import fr.quatrevieux.araknemu.game.monster.group.MonsterGroupFactory;
32
33
import java.util.Collections;
34
import java.util.List;
35
import java.util.stream.Collectors;
36
import java.util.stream.Stream;
37
38
/**
39
 * Handle a monster group configuration on map and cell
40
 */
41
public final class LivingMonsterGroupPosition {
42
    private final MonsterGroupFactory factory;
43
    private final FightService fightService;
44
    private final MonsterEnvironmentService environmentService;
45
    private final boolean fixed;
46
47
    private final MonsterGroupData data;
48
    private final SpawnCellSelector cellSelector;
49
50
    private ExplorationMap map;
51
52 1
    public LivingMonsterGroupPosition(MonsterGroupFactory factory, MonsterEnvironmentService environmentService, FightService fightService, MonsterGroupData data, SpawnCellSelector cellSelector, boolean fixed) {
53 1
        this.factory = factory;
54 1
        this.fightService = fightService;
55 1
        this.environmentService = environmentService;
56 1
        this.data = data;
57 1
        this.cellSelector = cellSelector;
58 1
        this.fixed = fixed;
59 1
    }
60
61
    /**
62
     * Link the group to the map and populate (spawn) with configured group data
63
     * This method should be called once, when exploration map is loaded
64
     *
65
     * @see fr.quatrevieux.araknemu.game.exploration.map.event.MapLoaded
66
     */
67
    public void populate(ExplorationMap map) {
68 1
        this.map = map;
69 1
        this.cellSelector.setMap(map);
70
71 1
        for (long i = groupStream().count(); i < data.maxCount(); ++i) {
72 1
            spawn();
73
        }
74 1
    }
75
76
    /**
77
     * Spawn a new group on the map
78
     *
79
     * Note: this method will not check the max count of monsters : if called manually, the group count can exceed max count
80
     */
81
    public void spawn() {
82 1
        map.add(factory.create(data, this));
83 1
    }
84
85
    /**
86
     * Get list of available monster groups on the map
87
     */
88
    public List<MonsterGroup> available() {
89 1
        if (map == null) {
90 1
            return Collections.emptyList();
91
        }
92
93 1
        return groupStream().collect(Collectors.toList());
94
    }
95
96
    /**
97
     * Find the group spawn cell
98
     *
99
     * If the cell is fixed (not -1 on {@link MonsterGroupPosition#position() cell}), this cell is returned
100
     * If not, a random free (without creatures, objects, and walkable) cell is returned
101
     *
102
     * @see fr.quatrevieux.araknemu.game.exploration.map.cell.ExplorationMapCell#free()
103
     * @see SpawnCellSelector#cell()
104
     */
105
    public ExplorationMapCell cell() {
106 1
        return cellSelector.cell();
107
    }
108
109
    /**
110
     * Does the current monster group is fixed ?
111
     * If true, the group cannot move
112
     */
113
    public boolean fixed() {
114 1
        return fixed;
115
    }
116
117
    /**
118
     * Start a fight with the group
119
     *
120
     * @param group The monster group. Must be handled by the current instance
121
     * @param player The player
122
     *
123
     * @return The created fight
124
     */
125
    public Fight startFight(MonsterGroup group, ExplorationPlayer player) {
126 1
        map.remove(group);
127 1
        environmentService.respawn(this, data.respawnTime());
128
129 1
        return fightService.handler(PvmBuilder.class).start(
130 1
            builder -> builder
131 1
                .randomize(!data.fixedTeamNumber())
132 1
                .map(map)
133 1
                .initiator(player.player())
134 1
                .monsterGroup(group)
135
        );
136
    }
137
138
    /**
139
     * Get stream of groups related to the current group position
140
     */
141
    private Stream<MonsterGroup> groupStream() {
142 1
        return map.creatures().stream()
143 1
            .filter(MonsterGroup.class::isInstance)
144 1
            .map(creature -> (MonsterGroup) creature)
145 1
            .filter(group -> this.equals(group.handler()))
146
        ;
147
    }
148
}
149