diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/ai/Board.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/ai/Board.java index 222202d..9483cbe 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/ai/Board.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/ai/Board.java @@ -65,6 +65,9 @@ class Board { Rock rock = (Rock)entity; data[y][x] = new Piece(PieceType.Rock, entity.id, rock.getHp(), rock.maxHP); } + case Portals -> { + data[y][x] = new Piece(PieceType.Portal, entity.id); + } case InfinityStones -> { InfinityStone stone = (InfinityStone)entity; data[y][x] = new Piece(PieceType.InfinityStone, entity.id, stone.type); diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/ai/Piece.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/ai/Piece.java index 153e83f..2aef2a8 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/ai/Piece.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/ai/Piece.java @@ -28,6 +28,16 @@ class Piece { this.stone = null; } + public Piece(PieceType type, EntityID id) { + this.type = type; + this.id = id; + this.hp = null; + this.mp = null; + this.ap = null; + this.inventory = null; + this.stone = null; + } + public Piece(PieceType type, EntityID id, int hp, int maxHP) { this.type = type; this.id = id; diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/ai/PieceType.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/ai/PieceType.java index 3026c3a..2d92a40 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/ai/PieceType.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/ai/PieceType.java @@ -6,5 +6,6 @@ enum PieceType { Character, InfinityStone, Thanos, - NPC + NPC, + Portal } diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/config/FieldType.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/config/FieldType.java index c06264c..5d8ae3c 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/config/FieldType.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/config/FieldType.java @@ -6,4 +6,5 @@ package uulm.teamname.marvelous.gamelibrary.config; public enum FieldType { GRASS, ROCK, + PORTAL } diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Portal.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Portal.java new file mode 100644 index 0000000..a704271 --- /dev/null +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Portal.java @@ -0,0 +1,46 @@ +package uulm.teamname.marvelous.gamelibrary.entities; + +import uulm.teamname.marvelous.gamelibrary.IntVector2; + +import java.util.Objects; + +/** Represents a portal on the map. */ +public class Portal extends Entity { + /** + * Constructs a new {@link Portal}. + * @param id The {@link EntityID} of the portal + * @param position The position of the portal + */ + public Portal(EntityID id, IntVector2 position) { + super(id, position); + solid = false; + opaque = true; + } + + @Override + public Portal clone() { + return new Portal(id, position); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + return super.equals(o); + } + + + + @Override + public int hashCode() { + return Objects.hash(super.hashCode()); + } + + + @Override + public String toString() { + return "Portal{" + + "position=" + position + + '}'; + } +} diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/EntityManager.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/EntityManager.java index 43e9693..d371609 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/EntityManager.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/EntityManager.java @@ -1,17 +1,14 @@ package uulm.teamname.marvelous.gamelibrary.gamelogic; import uulm.teamname.marvelous.gamelibrary.IntVector2; -import uulm.teamname.marvelous.gamelibrary.entities.Entity; -import uulm.teamname.marvelous.gamelibrary.entities.EntityID; -import uulm.teamname.marvelous.gamelibrary.entities.EntityType; -import uulm.teamname.marvelous.gamelibrary.entities.Rock; +import uulm.teamname.marvelous.gamelibrary.entities.*; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; /** Represents a managed list of {@link Entity Entities}. */ -public class EntityManager { +public class EntityManager implements Iterable { /** The internal collection of {@link Entity Entities} */ private final HashSet entities = new HashSet<>(); @@ -149,11 +146,9 @@ public class EntityManager { return false; } - /** - * Iterates over all entities inside the list. - * @return An iterator over every {@link Entity} - */ - public Iterator getEntities() { + /** Iterates over all entities inside the list. */ + @Override + public Iterator iterator() { return entities.iterator(); } 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 367db06..d16b481 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameLogic.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameLogic.java @@ -351,17 +351,49 @@ public class GameLogic { .buildEntityEvent()); for(Entity entity: state.entities.findByPosition(data.targetField)) { if(entity instanceof Character) { + result.add(new EventBuilder(EventType.MoveEvent) .withOriginEntity(entity.id) .withOriginField(data.targetField) .withTargetField(data.originField) .buildCharacterEvent()); + break; //we should only have one entity per field anyways }else if(entity instanceof InfinityStone) { + result.add(new EventBuilder(EventType.DestroyedEntityEvent) .withTargetField(data.targetField) .withTargetEntity(entity.id) .buildEntityEvent()); + + break; //we should only have one entity per field anyways + }else if(entity instanceof Portal) { + + List targets = new ArrayList<>(); + for(Entity e: state.entities) { + if(e.id.type == EntityType.Portals && !e.id.equals(entity.id)) { + targets.add(e); + } + } + if(targets.isEmpty()) { + break; + } + Entity target = targets.get(rand.nextInt(targets.size())); + + List fields = getFreeNeighbour(state, target.getPosition()); + if(fields.isEmpty()) { + break; + } + IntVector2 field = fields.get(rand.nextInt(fields.size())); + + result.add(new EventBuilder(EventType.TeleportedEvent) + .withTeleportedEntity(data.originEntity) + .withOriginField(data.targetField) + .withTargetField(field) + .withOriginPortal(entity.id) + .withTargetPortal(target.id) + .buildTeleportedEvent()); + break; //we should only have one entity per field anyways } } @@ -596,6 +628,12 @@ public class GameLogic { target.setPosition(data.targetField); } } + case TeleportedEvent -> { + TeleportedEvent data = (TeleportedEvent)event; + + Character target = (Character)state.entities.findEntity(data.teleportedEntity); + target.setPosition(data.targetField); + } case UseInfinityStoneEvent -> { state.stoneCooldown.setCooldown(((CharacterEvent)event).stoneType); } @@ -721,10 +759,13 @@ public class GameLogic { ArrayList free = new ArrayList<>(); int rockIndex = 0; + int portalIndex = 0; for(int x = 0; x < state.mapSize.getX(); x++) { for(int y = 0; y < state.mapSize.getY(); y++) { if(state.scenarioConfig.scenario[y][x] == FieldType.ROCK) { state.entities.addEntity(new Rock(new EntityID(EntityType.Rocks, rockIndex++), new IntVector2(x, y), 100)); + }else if(state.scenarioConfig.scenario[y][x] == FieldType.PORTAL) { + state.entities.addEntity(new Portal(new EntityID(EntityType.Portals, portalIndex++), new IntVector2(x, y))); }else { free.add(new IntVector2(x, y)); } @@ -1062,6 +1103,15 @@ public class GameLogic { .withEntity(thanosNPC) .buildEntityEvent()); + for(Entity e: state.entities) { + if(e.id.type == EntityType.Portals) { + result.add(new EventBuilder(EventType.DestroyedEntityEvent) + .withTargetEntity(e.id) + .withTargetField(e.getPosition()) + .buildEntityEvent()); + } + } + state.turnOrder.add(thanos); state.entities.addEntity(thanosNPC); diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameState.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameState.java index fe560a4..0688c55 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameState.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameState.java @@ -153,6 +153,9 @@ class GameState { sb.append(entities.get(0).id.equals(activeCharacter) ? "'" : " "); } case Rocks -> { + sb.append("M "); + } + case Portals -> { sb.append("O "); } case InfinityStones -> { diff --git a/src/test/java/uulm/teamname/marvelous/gamelibrary/gamelogic/BaseGameLogicTest.java b/src/test/java/uulm/teamname/marvelous/gamelibrary/gamelogic/BaseGameLogicTest.java index 22376a2..691aaba 100644 --- a/src/test/java/uulm/teamname/marvelous/gamelibrary/gamelogic/BaseGameLogicTest.java +++ b/src/test/java/uulm/teamname/marvelous/gamelibrary/gamelogic/BaseGameLogicTest.java @@ -36,7 +36,10 @@ public class BaseGameLogicTest { scenarioConfig.scenario = new FieldType[20][20]; for(int x = 0; x < scenarioConfig.scenario[0].length; x++) { for(int y = 0; y < scenarioConfig.scenario.length; y++) { - if(Math.abs(randomIntegers.next() % 100) < 10) { + int r = Math.abs(randomIntegers.next() % 100); + if(r < 2) { + scenarioConfig.scenario[y][x] = FieldType.PORTAL; + }else if(r < 10) { scenarioConfig.scenario[y][x] = FieldType.ROCK; }else { scenarioConfig.scenario[y][x] = FieldType.GRASS; diff --git a/src/test/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameLogicTest.java b/src/test/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameLogicTest.java index 83089b2..d2310e0 100644 --- a/src/test/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameLogicTest.java +++ b/src/test/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameLogicTest.java @@ -83,10 +83,10 @@ class GameLogicTest extends BaseGameLogicTest { snapshot.turnNumber = 10; assertEquals(0, state.turnNumber, "Original's turn number should remain unchanged"); - assertTrue(snapshot.entities.getEntities().hasNext(), "Snapshot should contain cloned entities"); + assertTrue(snapshot.entities.iterator().hasNext(), "Snapshot should contain cloned entities"); - ((Rock)snapshot.entities.getEntities().next()).decreaseHp(5); - assertEquals(100, ((Rock)state.entities.getEntities().next()).getHp(), "Original's rock entity hp should remain unchanged"); + ((Rock)snapshot.entities.iterator().next()).decreaseHp(5); + assertEquals(100, ((Rock)state.entities.iterator().next()).getHp(), "Original's rock entity hp should remain unchanged"); }