Skip to content

Commit

Permalink
feat(fight): Order cell of effect area by distance from center
Browse files Browse the repository at this point in the history
  • Loading branch information
vincent4vx committed Jan 12, 2024
1 parent 3e704d3 commit c949def
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import fr.quatrevieux.araknemu.data.value.EffectArea;
import org.checkerframework.checker.index.qual.NonNegative;

import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;

Expand All @@ -43,9 +42,9 @@ public CircularArea(EffectArea area, Predicate<Integer> distanceChecker) {

@Override
public <C extends MapCell> Set<C> resolve(C target, C source) {
final Set<C> cells = new HashSet<>();
final DofusMap<C> map = target.map();
final CoordinateCell<C> center = target.coordinate();
final Set<C> cells = Util.createOrderedSet(target);

for (int i = 0; i < map.size(); ++i) {
final CoordinateCell<C> cell = map.get(i).coordinate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import fr.quatrevieux.araknemu.data.value.EffectArea;
import org.checkerframework.checker.index.qual.NonNegative;

import java.util.HashSet;
import java.util.Set;

/**
Expand All @@ -39,7 +38,7 @@ public CrossArea(EffectArea area) {

@Override
public <C extends MapCell> Set<C> resolve(C target, C source) {
final Set<C> cells = new HashSet<>(area.size() * 4 + 1);
final Set<C> cells = Util.createOrderedSet(target);

cells.add(target);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import org.checkerframework.checker.index.qual.NonNegative;

import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

/**
Expand All @@ -47,7 +47,7 @@ public <C extends MapCell> Set<C> resolve(C target, C source) {
}

final Direction direction = source.coordinate().directionTo(target.coordinate());
final Set<C> cells = new HashSet<>(area.size() + 1);
final Set<C> cells = new LinkedHashSet<>(area.size() + 1); // Cell are added in order, so no need to sort using a TreeSet

cells.add(target);
addCells(cells, target, direction, area.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import fr.quatrevieux.araknemu.data.value.EffectArea;
import org.checkerframework.checker.index.qual.NonNegative;

import java.util.HashSet;
import java.util.Set;

/**
Expand All @@ -39,7 +38,7 @@ public PerpendicularLineArea(EffectArea area) {

@Override
public <C extends MapCell> Set<C> resolve(C target, C source) {
final Set<C> cells = new HashSet<>(area.size() * 2 + 1);
final Set<C> cells = Util.createOrderedSet(target);
final Direction direction = source.coordinate().directionTo(target).orthogonal();

cells.add(target);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
public interface SpellEffectArea {
/**
* Resolve the cells from an effect area
* Cells must be sorted by distance from the target cell, nearest cells first
*
* @param target The target cell
* @param source The source cell (caster cell)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* This file is part of Araknemu.
*
* Araknemu is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Araknemu is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Araknemu. If not, see <https://www.gnu.org/licenses/>.
*
* Copyright (c) 2017-2024 Vincent Quatrevieux
*/

package fr.quatrevieux.araknemu.game.spell.effect.area;

import fr.arakne.utils.maps.CoordinateCell;
import fr.arakne.utils.maps.MapCell;

import java.util.Set;
import java.util.TreeSet;

/**
* Utility methods for resolving effect areas
*/
final class Util {
private Util() {
// Disable constructor
}

/**
* Create a set with cells ordered by distance from target cell
*/
public static <C extends MapCell> Set<C> createOrderedSet(C target) {
final CoordinateCell<C> center = target.coordinate();

return new TreeSet<>((o1, o2) -> {
final int firstDistance = center.distance(o1);
final int secondDistance = center.distance(o2);

if (firstDistance == secondDistance) {
return o1.id() - o2.id();
}

return firstDistance - secondDistance;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@
import fr.quatrevieux.araknemu.data.value.EffectArea;
import fr.quatrevieux.araknemu.data.world.repository.environment.MapTemplateRepository;
import fr.quatrevieux.araknemu.game.GameBaseCase;
import fr.quatrevieux.araknemu.game.fight.map.FightCell;
import fr.quatrevieux.araknemu.game.fight.map.FightMap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Collections;
import java.util.Set;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;

class CircleAreaTest extends GameBaseCase {
Expand Down Expand Up @@ -80,4 +83,24 @@ void resolve() {
map.get(94)
);
}
}

@Test
void resolveShouldSortByDistanceFromCenter() {
assertCellIds(map.get(152), 0, new int[] {152});
assertCellIds(map.get(152), 1, new int[] {152, 137, 138, 166, 167});
assertCellIds(map.get(152), 2, new int[] {
152,
137, 138, 166, 167,
122, 123, 124, 151, 153, 180, 181, 182
});
}

private void assertCellIds(FightCell center, int size, int[] cellIds) {
Set<FightCell> cells = new CircleArea(new EffectArea(EffectArea.Type.CIRCLE, size)).resolve(center, center);

assertArrayEquals(
cellIds,
cells.stream().mapToInt(FightCell::id).toArray()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@
import fr.quatrevieux.araknemu.data.value.EffectArea;
import fr.quatrevieux.araknemu.data.world.repository.environment.MapTemplateRepository;
import fr.quatrevieux.araknemu.game.GameBaseCase;
import fr.quatrevieux.araknemu.game.fight.map.FightCell;
import fr.quatrevieux.araknemu.game.fight.map.FightMap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Collections;
import java.util.Set;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;

class CrossAreaTest extends GameBaseCase {
Expand Down Expand Up @@ -82,4 +85,30 @@ void resolve() {
map.get(78)
);
}

@Test
void resolveShouldSortByDistanceFromCenter() {
assertCellIds(map.get(152), map.get(152), 0, new int[] {152});
assertCellIds(map.get(152), map.get(152), 1, new int[] {152, 137, 138, 166, 167});
assertCellIds(map.get(152), map.get(152), 2, new int[] {
152,
137, 138, 166, 167,
122, 124, 180, 182
});
assertCellIds(map.get(152), map.get(152), 3, new int[] {
152,
137, 138, 166, 167,
122, 124, 180, 182,
107, 110, 194, 197,
});
}

private void assertCellIds(FightCell from, FightCell center, int size, int[] cellIds) {
Set<FightCell> cells = new CrossArea(new EffectArea(EffectArea.Type.CROSS, size)).resolve(center, from);

assertArrayEquals(
cellIds,
cells.stream().mapToInt(FightCell::id).toArray()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@
import fr.quatrevieux.araknemu.data.value.EffectArea;
import fr.quatrevieux.araknemu.data.world.repository.environment.MapTemplateRepository;
import fr.quatrevieux.araknemu.game.GameBaseCase;
import fr.quatrevieux.araknemu.game.fight.map.FightCell;
import fr.quatrevieux.araknemu.game.fight.map.FightMap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Collections;
import java.util.Set;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;

class LineAreaTest extends GameBaseCase {
Expand Down Expand Up @@ -97,4 +100,21 @@ void resolveWithOutlineCell() {
map.get(420)
);
}

@Test
void resolveShouldSortByDistanceFromCenter() {
assertCellIds(map.get(152), map.get(167), 0, new int[] {167});
assertCellIds(map.get(152), map.get(167), 1, new int[] {167, 182});
assertCellIds(map.get(152), map.get(167), 2, new int[] {167, 182, 197});
assertCellIds(map.get(152), map.get(167), 3, new int[] {167, 182, 197, 212});
}

private void assertCellIds(FightCell from, FightCell center, int size, int[] cellIds) {
Set<FightCell> cells = new LineArea(new EffectArea(EffectArea.Type.LINE, size)).resolve(center, from);

assertArrayEquals(
cellIds,
cells.stream().mapToInt(FightCell::id).toArray()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@
import fr.quatrevieux.araknemu.data.value.EffectArea;
import fr.quatrevieux.araknemu.data.world.repository.environment.MapTemplateRepository;
import fr.quatrevieux.araknemu.game.GameBaseCase;
import fr.quatrevieux.araknemu.game.fight.map.FightCell;
import fr.quatrevieux.araknemu.game.fight.map.FightMap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Collections;
import java.util.Set;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;

class PerpendicularLineAreaTest extends GameBaseCase {
Expand Down Expand Up @@ -74,4 +77,20 @@ void resolve() {
map.get(78)
);
}

@Test
void resolveShouldSortByDistanceFromCenter() {
assertCellIds(map.get(152), map.get(167), 0, new int[] {167});
assertCellIds(map.get(152), map.get(167), 1, new int[] {167, 153, 181});
assertCellIds(map.get(152), map.get(167), 2, new int[] {167, 153, 181, 139, 195});
}

private void assertCellIds(FightCell from, FightCell center, int size, int[] cellIds) {
Set<FightCell> cells = new PerpendicularLineArea(new EffectArea(EffectArea.Type.PERPENDICULAR_LINE, size)).resolve(center, from);

assertArrayEquals(
cellIds,
cells.stream().mapToInt(FightCell::id).toArray()
);
}
}

0 comments on commit c949def

Please sign in to comment.