diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameLogic.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameLogic.java index c79d38e..af5a1c9 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameLogic.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameLogic.java @@ -12,6 +12,7 @@ import uulm.teamname.marvelous.gamelibrary.requests.RequestType; import java.awt.*; import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; import java.util.*; /** Contains game logic handling. */ @@ -97,20 +98,14 @@ class GameLogic { } case MindStone -> { EntityType target = data.originEntity.type == EntityType.P1 ? EntityType.P2 : EntityType.P1; - Line2D line = new Line2D.Float(data.originField.getX(), data.originField.getY(), data.targetField.getX(), data.targetField.getY()); - for(int i = data.originField.getX(); i <= data.targetField.getX(); i++) { - for(int j = data.originField.getY(); j <= data.targetField.getY(); j++) { - var cell = new Rectangle.Float(i - 0.5f, j - 0.5f, 1, 1); - if(line.intersects(cell)) { - for(Entity entity: state.entities.findByPosition(data.targetField)) { - if(entity.id.isSameType(target)) { - result.add(new EventBuilder(EventType.TakenDamageEvent) - .withTargetEntity(entity.id) - .withTargetField(new IntVector2(i, j)) - .withAmount(data.value) - .buildEntityEvent()); - } - } + for(IntVector2 pos: rasterize(data.originField, data.targetField)) { + for(Entity entity: state.entities.findByPosition(pos)) { + if(entity.id.isSameType(target)) { + result.add(new EventBuilder(EventType.TakenDamageEvent) + .withTargetEntity(entity.id) + .withTargetField(pos) + .withAmount(data.value) + .buildEntityEvent()); } } } @@ -441,18 +436,9 @@ class GameLogic { * @return Whether or not the light of sight exists */ private static boolean checkLineOfSight(GameState state, IntVector2 start, IntVector2 end) { - //naive code for the win!!! \o/ - //at least its early exit and probably only O(ln(n*m)) - //TODO: implement proper line rasterization algorithm in GameLogic.checkLineOfSight - Line2D line = new Line2D.Float(start.getX(), start.getY(), end.getX(), end.getY()); - for(int i = start.getX(); i <= end.getX(); i++) { - for(int j = start.getY(); j <= end.getY(); j++) { - var cell = new Rectangle.Float(i - 0.5f, j - 0.5f, 1, 1); - if(line.intersects(cell)) { - if(state.entities.blocksVision(new IntVector2(i, j))) { - return false; - } - } + for(IntVector2 pos: rasterize(start, end)) { + if(state.entities.blocksVision(pos)) { + return false; } } return true; @@ -866,4 +852,30 @@ class GameLogic { return result; } + + /** + * Computes all fields which intersect the line between the center points of the given two fields. + * @return The list of intersecting positions + */ + public static ArrayList rasterize(IntVector2 a, IntVector2 b) { + ArrayList result = new ArrayList<>(); + + //TODO: implement proper line rasterization algorithm in GameLogic.rasterize + + int x1 = Math.min(a.getX(), b.getX()); + int x2 = Math.max(a.getX(), b.getX()); + int y1 = Math.min(a.getY(), b.getY()); + int y2 = Math.max(a.getY(), b.getY()); + Line2D line = new Line2D.Float(x1 + 0.5f, y1 + 0.5f, x2 + 0.5f, y2 + 0.5f); + for(int i = x1; i <= x2; i++) { + for(int j = y1; j <= y2; j++) { + Rectangle2D cell = new Rectangle.Float(i, j, 1, 1); + if(line.intersects(cell)) { + result.add(new IntVector2(i, j)); + } + } + } + + return result; + } }