MapsFile(URL,SwfFileLoader)   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 3
cts 3
cp 1
crap 1
rs 10
1
/*
2
 * This file is part of ArakneLangLoader.
3
 *
4
 * ArakneLangLoader 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
 * ArakneLangLoader 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 ArakneLangLoader.  If not, see <https://www.gnu.org/licenses/>.
16
 *
17
 * Copyright (c) 2020 Vincent Quatrevieux
18
 */
19
20
package fr.arakne.swflangloader.lang.maps;
21
22
import fr.arakne.swflangloader.loader.AbstractSwfFile;
23
import fr.arakne.swflangloader.loader.SwfFileLoader;
24
import fr.arakne.swflangloader.parser.mapper.MapperHydrator;
25
import fr.arakne.swflangloader.parser.mapper.SwfVariable;
26
27
import java.io.File;
28
import java.io.IOException;
29
import java.net.URL;
30
import java.util.*;
31
import java.util.stream.Collectors;
32
33
/**
34
 * The maps lang file, containing map positions, subareas, areas, and super areas
35
 *
36
 * Usage:
37
 * <pre>{@code
38
 * MapsFile maps = new MapsFile(new URL("http://my-lang.example.com/dofus/lang/swf/maps_fr_366.swf"));
39
 *
40
 * MapPosition pos = maps.position(1547);
41
 *
42
 * pos.x(); // ...
43
 * pos.subArea(); // ...
44
 * }</pre>
45
 */
46
final public class MapsFile extends AbstractSwfFile {
47 1
    final static private MapperHydrator<MapsFile> HYDRATOR = MapperHydrator.parseAnnotations(MapsFile.class);
48
49
    final static private class Position {
50
        final private int x;
51
        final private int y;
52
53 1
        public Position(int x, int y) {
54 1
            this.x = x;
55 1
            this.y = y;
56 1
        }
57
58
        @Override
59
        public boolean equals(Object o) {
60 1
            if (this == o) return true;
61 1
            Position position = (Position) o;
62 1
            return x == position.x && y == position.y;
63
        }
64
65
        @Override
66
        public int hashCode() {
67 1
            return Objects.hash(x, y);
68
        }
69
    }
70
71 1
    @SwfVariable("MA.m")
72
    final private Map<Integer, MapPosition> mapPosById = new HashMap<>();
73 1
    private Map<Position, List<MapPosition>> mapPosByPosition = null;
74
75 1
    @SwfVariable("MA.sua")
76
    final private Map<Integer, String> superAreas = new HashMap<>();
77
78 1
    @SwfVariable("MA.a")
79
    final private Map<Integer, MapArea> areasById = new HashMap<>();
80
81 1
    @SwfVariable("MA.sa")
82
    final private Map<Integer, MapSubArea> subAreasById = new HashMap<>();
83
84 1
    public MapsFile(URL file, SwfFileLoader loader) throws IOException, InterruptedException {
85 1
        loader.load(file, this, HYDRATOR);
86 1
        init();
87 1
    }
88
89
    public MapsFile(URL file) throws IOException, InterruptedException {
90 1
        this(file, new SwfFileLoader());
91 1
    }
92
93
    public MapsFile(File file) throws IOException, InterruptedException {
94
        this(file.toURI().toURL(), new SwfFileLoader());
95
    }
96
97
    /**
98
     * Get a simple map position by its id
99
     *
100
     * @param id The map id
101
     *
102
     * @return The map position, or null is not found
103
     */
104
    public MapPosition position(int id) {
105 1
        return mapPosById.get(id);
106
    }
107
108
    /**
109
     * @return All available map positions
110
     */
111
    public Collection<MapPosition> allMapPositions() {
112 1
        return mapPosById.values();
113
    }
114
115
    /**
116
     * Get available maps positions at the given coordinates
117
     *
118
     * @param x X coordinate
119
     * @param y Y coordinate
120
     *
121
     * @return The matching positions. If not found, an empty collection is returned
122
     */
123
    public Collection<MapPosition> positions(int x, int y) {
124 1
        final Position position = new Position(x, y);
125
126 1
        if (mapPosByPosition == null) {
127 1
            mapPosByPosition = mapPosById.values().stream().collect(Collectors.groupingBy(pos -> new Position(pos.x(), pos.y())));
128
        }
129
130 1
        final List<MapPosition> positions = mapPosByPosition.get(position);
131
132 1
        if (positions == null) {
133 1
            return Collections.emptyList();
134
        }
135
136 1
        return Collections.unmodifiableCollection(positions);
137
    }
138
139
    /**
140
     * Get a subarea by its id
141
     *
142
     * @param id The subarea id
143
     *
144
     * @return The subarea, or null if not found
145
     */
146
    public MapSubArea subArea(int id) {
147 1
        return subAreasById.get(id);
148
    }
149
150
    /**
151
     * @return All available subareas
152
     */
153
    public Collection<MapSubArea> allSubAreas() {
154 1
        return subAreasById.values();
155
    }
156
157
    /**
158
     * Get an area by its id
159
     *
160
     * @param id The area id
161
     *
162
     * @return The area, or null if not found
163
     */
164
    public MapArea area(int id) {
165 1
        return areasById.get(id);
166
    }
167
168
    /**
169
     * @return All available areas
170
     */
171
    public Collection<MapArea> allAreas() {
172 1
        return areasById.values();
173
    }
174
175
    /**
176
     * Get a super area name by its id
177
     *
178
     * @param id The super area id
179
     *
180
     * @return The name, or null if not found
181
     */
182
    public String superArea(int id) {
183 1
        return superAreas.get(id);
184
    }
185
186
    private void init() {
187 1
        mapPosById.forEach((id, mapPosition) -> {
188 1
            mapPosition.setId(id);
189 1
            mapPosition.setMaps(this);
190 1
        });
191
192 1
        subAreasById.forEach((id, subArea) -> {
193 1
            subArea.setId(id);
194 1
            subArea.setMaps(this);
195 1
        });
196
197 1
        areasById.forEach((id, area) -> {
198 1
            area.setId(id);
199 1
            area.setMaps(this);
200 1
        });
201 1
    }
202
}
203