From b5a66dcdc631b4acceb6528a3fdd2ae0d83c1e9c Mon Sep 17 00:00:00 2001 From: punchready Date: Sun, 2 May 2021 00:03:03 +0200 Subject: [PATCH] wip: start implementing GameLogic.checkRequest --- .../gamelibrary/entities/Character.java | 2 + .../gamelibrary/entities/Entity.java | 14 ++ .../gamelibrary/entities/EntityID.java | 11 ++ .../gamelibrary/entities/InfinityStone.java | 2 + .../marvelous/gamelibrary/entities/NPC.java | 2 + .../marvelous/gamelibrary/entities/Rock.java | 2 + .../gamelibrary/gamelogic/EntityManager.java | 33 ++++ .../gamelibrary/gamelogic/GameLogic.java | 142 +++++++++++++++++- 8 files changed, 207 insertions(+), 1 deletion(-) diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Character.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Character.java index 2328a90..de5db8e 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Character.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Character.java @@ -42,6 +42,8 @@ public class Character extends Entity { */ public Character(EntityID id, IntVector2 position, String name, int hp, int mp, int ap, int attackRange, int rangedDamage, int meleeDamage) { super(id, position); + solid = false; + opaque = true; this.name = name; this.hp = new Stat(StatType.HP, hp); this.mp = new Stat(StatType.MP, mp); diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Entity.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Entity.java index 1be2176..4b24e6c 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Entity.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Entity.java @@ -7,6 +7,12 @@ public abstract class Entity { /** Whether or not the entity is currently active in the game */ protected boolean active = true; + /** Whether or not the entity blocks movement */ + protected boolean solid = false; + + /** Whether or not the entity blocks vision */ + protected boolean opaque = false; + /** The position of the entity */ protected IntVector2 position; @@ -33,6 +39,14 @@ public abstract class Entity { return active; } + public boolean blocksMovement() { + return solid; + } + + public boolean blocksVision() { + return opaque; + } + public void setActive(boolean active) { this.active = active; } diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/EntityID.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/EntityID.java index 9b629d7..23993dd 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/EntityID.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/EntityID.java @@ -27,6 +27,17 @@ public class EntityID { return type == other; } + @Override + public boolean equals(Object obj){ + if(this == obj) return true; + + if(!(obj instanceof EntityID)) return false; + + EntityID other = (EntityID)obj; + + return this.id == other.id && this.type == other.type; + } + /** * Clones this entity id. * @return The cloned {@link EntityID} diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/InfinityStone.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/InfinityStone.java index 3b8a8a4..0b6089a 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/InfinityStone.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/InfinityStone.java @@ -15,6 +15,8 @@ public class InfinityStone extends Entity { */ public InfinityStone(EntityID id, IntVector2 position, StoneType type) { super(id, position); + solid = false; + opaque = false; this.type = type; } diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/NPC.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/NPC.java index 06b72c2..5218942 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/NPC.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/NPC.java @@ -17,6 +17,8 @@ public class NPC extends Entity { */ public NPC(EntityID id, IntVector2 position, ArrayList inventory) { super(id, position); + solid = false; + opaque = true; this.inventory = new Inventory(inventory); } diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Rock.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Rock.java index 1b2c3b7..0c73035 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Rock.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/entities/Rock.java @@ -18,6 +18,8 @@ public class Rock extends Entity { */ public Rock(EntityID id, IntVector2 position, int hp) { super(id, position); + solid = true; + opaque = true; this.maxHP = hp; this.hp = hp; } 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 f25bd97..da1a774 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/EntityManager.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/EntityManager.java @@ -1,7 +1,11 @@ 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 java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; @@ -53,6 +57,35 @@ public class EntityManager { return entities.remove(entity); } + /** + * Finds an entity with an {@link EntityID}. + * @param id The id to search for + * @return The found {@link Entity} or null if none found + */ + public Entity findEntity(EntityID id) { + for(Entity entity: entities) { + if(entity.id == id) { + return entity; + } + } + return null; + } + + /** + * Finds all entities with a position. + * @param pos The position to check on + * @return The found {@link Entity}s matching the position + */ + public ArrayList findByPosition(IntVector2 pos) { + ArrayList found = new ArrayList<>(); + for(Entity entity: entities) { + if(entity.getPosition() == pos) { + found.add(entity); + } + } + return found; + } + /** * Iterates over all entities inside the list. * @return An iterator over every {@link Entity} 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 49d9062..f8b239b 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameLogic.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/gamelogic/GameLogic.java @@ -1,6 +1,8 @@ package uulm.teamname.marvelous.gamelibrary.gamelogic; import uulm.teamname.marvelous.gamelibrary.Tuple; +import uulm.teamname.marvelous.gamelibrary.entities.Entity; +import uulm.teamname.marvelous.gamelibrary.entities.Character; import uulm.teamname.marvelous.gamelibrary.events.*; import uulm.teamname.marvelous.gamelibrary.requests.CharacterRequest; import uulm.teamname.marvelous.gamelibrary.requests.Request; @@ -84,7 +86,145 @@ class GameLogic { * @return Whether or not the request is valid */ public static boolean checkRequest(GameState state, Request request) { - //TODO: implement GameLogic.checkRequest + //TODO: refactor this using errors + try { + switch(request.type) { + case MeleeAttackRequest, RangedAttackRequest -> { + CharacterRequest data = (CharacterRequest)request; + + Entity originEntity = state.entities.findEntity(data.originEntity); + if(originEntity == null || originEntity.getPosition() != data.originField || !(originEntity instanceof Character)) { + return false; + } + Character origin = (Character)originEntity; + Entity targetEntity = state.entities.findEntity(data.targetEntity); + if(targetEntity == null || targetEntity.getPosition() != data.targetField || !(targetEntity instanceof Character)) { + return false; + } + Character target = (Character)targetEntity; + + if(origin.hp.getValue() <= 0 || !origin.isActive()) { + return false; + } + if(origin.ap.getValue() < 1) { + return false; + } + if(request.type == RequestType.MeleeAttackRequest && origin.meleeDamage != data.value) { + return false; + }else if(request.type == RequestType.RangedAttackRequest && origin.rangedDamage != data.value) { + return false; + } + if(target.hp.getValue() <= 0 || !target.isActive()) { + return false; + } + + if(request.type == RequestType.RangedAttackRequest && origin.getPosition().distance(target.getPosition()) > origin.attackRange) { + return false; + } + + //TODO: check line of sight in GameLogic.checkRequest + + return true; + } + case MoveRequest -> { + CharacterRequest data = (CharacterRequest)request; + + Entity originEntity = state.entities.findEntity(data.originEntity); + if(originEntity == null || originEntity.getPosition() != data.originField || !(originEntity instanceof Character)) { + return false; + } + Character origin = (Character)originEntity; + + if(data.targetField.getX() < 0 || data.targetField.getX() >= state.mapSize.getX() || data.targetField.getY() < 0 || data.targetField.getY() >= state.mapSize.getY()) { + return false; + } + + for(Entity entity: state.entities.findByPosition(data.targetField)) { + if(entity.blocksMovement()) { + return false; + } + } + + if(origin.hp.getValue() <= 0 || !origin.isActive()) { + return false; + } + if(origin.mp.getValue() < 1) { + return false; + } + + return true; + } + case ExchangeInfinityStoneRequest -> { + CharacterRequest data = (CharacterRequest)request; + + Entity originEntity = state.entities.findEntity(data.originEntity); + if(originEntity == null || originEntity.getPosition() != data.originField || !(originEntity instanceof Character)) { + return false; + } + Character origin = (Character)originEntity; + Entity targetEntity = state.entities.findEntity(data.targetEntity); + if(targetEntity == null || targetEntity.getPosition() != data.targetField || !(targetEntity instanceof Character)) { + return false; + } + Character target = (Character)targetEntity; + + if(origin.hp.getValue() <= 0 || !origin.isActive()) { + return false; + } + if(origin.ap.getValue() < 1) { + return false; + } + if(target.hp.getValue() <= 0 || !target.isActive()) { + return false; + } + + if(!origin.inventory.hasStone(data.stoneType)) { + return false; + } + + return true; + } + case UseInfinityStoneRequest -> { + CharacterRequest data = (CharacterRequest)request; + + Entity originEntity = state.entities.findEntity(data.originEntity); + if(originEntity == null || originEntity.getPosition() != data.originField || !(originEntity instanceof Character)) { + return false; + } + Character origin = (Character)originEntity; + Entity targetEntity = state.entities.findEntity(data.targetEntity); + if(targetEntity == null || targetEntity.getPosition() != data.targetField || !(targetEntity instanceof Character)) { + return false; + } + Character target = (Character)targetEntity; + + if(origin.hp.getValue() <= 0 || !origin.isActive()) { + return false; + } + if(origin.ap.getValue() < 1) { + return false; + } + if(!target.isActive()) { + return false; + } + + if(!origin.inventory.hasStone(data.stoneType)) { + return false; + } + + return true; + + } + case DisconnectRequest -> { + //TODO: add check for DisconnectRequest in GameLogic.checkRequest + + return true; + } + } + }catch(Exception e) { + return false; + } + return false; }