build(Builder)   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 11
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 10
dl 0
loc 11
ccs 8
cts 8
cp 1
crap 1
rs 9.9
c 1
b 0
f 0
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-2021 Vincent Quatrevieux
18
 */
19
20
package fr.quatrevieux.araknemu.game.admin.debug;
21
22
import fr.arakne.utils.maps.CoordinateCell;
23
import fr.arakne.utils.maps.MapCell;
24
import fr.arakne.utils.maps.sight.CellSight;
25
import fr.quatrevieux.araknemu.common.account.Permission;
26
import fr.quatrevieux.araknemu.data.world.repository.environment.MapTemplateRepository;
27
import fr.quatrevieux.araknemu.game.admin.AbstractCommand;
28
import fr.quatrevieux.araknemu.game.admin.AdminPerformer;
29
import fr.quatrevieux.araknemu.game.admin.AdminUser;
30
import fr.quatrevieux.araknemu.game.admin.formatter.Link;
31
import fr.quatrevieux.araknemu.game.fight.map.BattlefieldCell;
32
import fr.quatrevieux.araknemu.game.fight.map.FightMap;
33
import fr.quatrevieux.araknemu.network.game.out.game.FightStartPositions;
34
import org.checkerframework.checker.index.qual.NonNegative;
35
import org.kohsuke.args4j.Argument;
36
37
import java.util.ArrayList;
38
import java.util.Iterator;
39
import java.util.List;
40
41
/**
42
 * Display accessible cells by line of sight
43
 */
44
public final class LineOfSight extends AbstractCommand<LineOfSight.Arguments> {
45
    private final MapTemplateRepository repository;
46
47 1
    public LineOfSight(MapTemplateRepository repository) {
48 1
        this.repository = repository;
49 1
    }
50
51
    @Override
52
    protected void build(Builder builder) {
53 1
        builder
54 1
            .help(
55 1
                formatter -> formatter
56 1
                    .description("Highlight accessible cells by line of sight")
57 1
                    .synopsis("lineofsight [target cell id]")
58 1
                    .option("target cell id", "Optional. The target cell id for dump the line of sight to this cell")
59 1
                    .seeAlso(":fightpos hide", "For hide the cells", Link.Type.EXECUTE)
60
            )
61 1
            .requires(Permission.DEBUG)
62
        ;
63 1
    }
64
65
    @Override
66
    public String name() {
67 1
        return "lineofsight";
68
    }
69
70
    @Override
71
    @SuppressWarnings("argument") // the cell is valid
72
    public void execute(AdminPerformer performer, Arguments arguments) {
73 1
        final AdminUser user = AdminUser.class.cast(performer);
74 1
        final FightMap map = new FightMap(repository.get(user.player().position().map()));
75
76 1
        final CoordinateCell<BattlefieldCell> current = map.get(user.player().position().cell()).coordinate();
77 1
        final CellSight<BattlefieldCell> sight = new CellSight<>(current);
78
79
        final List<BattlefieldCell> accessible;
80
        final List<BattlefieldCell> blocked;
81
82 1
        if (!arguments.hasTargetCell()) {
83 1
            accessible = new ArrayList<>(sight.accessible());
84 1
            blocked = new ArrayList<>(sight.blocked());
85
        } else {
86 1
            final Iterator<BattlefieldCell> los = sight.to(map.get(arguments.cellId()));
87
88 1
            accessible = new ArrayList<>();
89 1
            blocked = new ArrayList<>();
90
91 1
            boolean isFree = true;
92
93 1
            while (los.hasNext()) {
94 1
                final BattlefieldCell cell = los.next();
95
96 1
                if (isFree) {
97 1
                    accessible.add(cell);
98 1
                    isFree = !cell.sightBlocking();
99
                } else {
100 1
                    blocked.add(cell);
101
                }
102 1
            }
103
        }
104
105 1
        user.send(new FightStartPositions(new MapCell[][] {
106 1
            blocked.toArray(new MapCell[0]),
107 1
            accessible.toArray(new MapCell[0]),
108
        }, 0));
109 1
    }
110
111
    @Override
112
    public Arguments createArguments() {
113 1
        return new Arguments();
114
    }
115
116
    @SuppressWarnings("initialization.field.uninitialized")
117 1
    public static final class Arguments {
118
        @Argument(metaVar = "target cell id")
119
        private @NonNegative Integer cellId;
120
121
        public void setCellId(@NonNegative Integer cellId) {
122
            this.cellId = cellId;
123
        }
124
125
        public @NonNegative int cellId() {
126 1
            return cellId;
127
        }
128
129
        public boolean hasTargetCell() {
130 1
            return cellId != null;
131
        }
132
    }
133
}
134