From 9e7a5252a8538b45f107c8108f245fd47eab012b Mon Sep 17 00:00:00 2001 From: Toni Helenius Date: Wed, 17 Jul 2024 17:36:13 +0300 Subject: [PATCH] Initial spell casting --- .../game/controller/CreaturesController.java | 42 ++++++++---- .../game/controller/GameController.java | 1 + .../game/controller/GameWorldController.java | 68 ++++++++++++------- .../game/controller/ICreaturesController.java | 11 ++- 4 files changed, 83 insertions(+), 39 deletions(-) diff --git a/src/toniarts/openkeeper/game/controller/CreaturesController.java b/src/toniarts/openkeeper/game/controller/CreaturesController.java index 312b7a6d..db7acd81 100644 --- a/src/toniarts/openkeeper/game/controller/CreaturesController.java +++ b/src/toniarts/openkeeper/game/controller/CreaturesController.java @@ -36,6 +36,7 @@ import toniarts.openkeeper.game.component.CreatureComponent; import toniarts.openkeeper.game.component.CreatureEfficiency; import toniarts.openkeeper.game.component.CreatureExperience; +import toniarts.openkeeper.game.component.CreatureFall; import toniarts.openkeeper.game.component.CreatureHunger; import toniarts.openkeeper.game.component.CreatureImprisoned; import toniarts.openkeeper.game.component.CreatureMeleeAttack; @@ -73,7 +74,6 @@ import toniarts.openkeeper.tools.convert.map.Variable; import toniarts.openkeeper.utils.Utils; import toniarts.openkeeper.utils.WorldUtils; -import toniarts.openkeeper.view.map.MapViewController; /** * This is a controller that controls all the game objects in the world TODO: @@ -214,30 +214,30 @@ public EntityId spawnCreature(Thing.Creature creature, Vector2f position) { ownerId = deadBody.getPlayerId(); } return loadCreature(creature.getCreatureId(), ownerId, level, position.getX(), position.getY(), 0f, healthPercentage, creature.getGoldHeld(), - triggerId != null && triggerId != 0 ? triggerId : null, false, objective, objectiveTargetPlayerId, objectiveTargetActionPointId); + triggerId != null && triggerId != 0 ? triggerId : null, SpawnType.PLACE, objective, objectiveTargetPlayerId, objectiveTargetActionPointId); } @Override - public EntityId spawnCreature(short creatureId, short playerId, int level, Vector2f position, boolean entrance) { - return loadCreature(creatureId, playerId, level, position.x, position.y, 0, 100, 0, null, entrance, null, (short) 0, 0); + public EntityId spawnCreature(short creatureId, short playerId, int level, Vector2f position, SpawnType spawnType) { + return loadCreature(creatureId, playerId, level, position.x, position.y, 0, 100, 0, null, spawnType, null, (short) 0, 0); } private EntityId loadCreature(short creatureId, short ownerId, int level, float x, float y, float rotation, Integer healthPercentage, int money, - Integer triggerId, boolean entrance, Thing.HeroParty.Objective objective, short objectiveTargetPlayerId, int objectiveTargetActionPointId) { + Integer triggerId, SpawnType spawnType, Thing.HeroParty.Objective objective, short objectiveTargetPlayerId, int objectiveTargetActionPointId) { EntityId entity = entityData.createEntity(); Creature creature = kwdFile.getCreature(creatureId); - return loadCreature(entity, creature, healthPercentage, money, level, entrance, x, y, ownerId, rotation, objective, objectiveTargetPlayerId, objectiveTargetActionPointId, triggerId); + return loadCreature(entity, creature, healthPercentage, money, level, spawnType, x, y, ownerId, rotation, objective, objectiveTargetPlayerId, objectiveTargetActionPointId, triggerId); } - private EntityId loadCreature(EntityId entity, Creature creature, Integer healthPercentage, int money, int level, boolean entrance, float x, float y, short ownerId, float rotation, Thing.HeroParty.Objective objective, short objectiveTargetPlayerId, int objectiveTargetActionPointId, Integer triggerId) { + private EntityId loadCreature(EntityId entity, Creature creature, Integer healthPercentage, int money, int level, SpawnType spawnType, float x, float y, short ownerId, float rotation, Thing.HeroParty.Objective objective, short objectiveTargetPlayerId, int objectiveTargetActionPointId, Integer triggerId) { String name = Utils.generateCreatureName(); String bloodType = Utils.generateBloodType(); - return loadCreature(entity, creature, name, bloodType, healthPercentage, money, level, entrance, x, y, ownerId, rotation, objective, objectiveTargetPlayerId, objectiveTargetActionPointId, triggerId); + return loadCreature(entity, creature, name, bloodType, healthPercentage, money, level, spawnType, x, y, ownerId, rotation, objective, objectiveTargetPlayerId, objectiveTargetActionPointId, triggerId); } - private EntityId loadCreature(EntityId entity, Creature creature, String name, String bloodType, Integer healthPercentage, int money, int level, boolean entrance, float x, float y, short ownerId, float rotation, Thing.HeroParty.Objective objective, short objectiveTargetPlayerId, int objectiveTargetActionPointId, Integer triggerId) { + private EntityId loadCreature(EntityId entity, Creature creature, String name, String bloodType, Integer healthPercentage, int money, int level, SpawnType spawnType, float x, float y, short ownerId, float rotation, Thing.HeroParty.Objective objective, short objectiveTargetPlayerId, int objectiveTargetActionPointId, Integer triggerId) { short creatureId = creature.getId(); // Create health, unless dead body @@ -279,8 +279,24 @@ private EntityId loadCreature(EntityId entity, Creature creature, String name, S entityData.setComponent(entity, new CreatureHunger(gameTimer.getGameTime(), 0)); } - CreatureState creatureState = entrance ? CreatureState.ENTERING_DUNGEON : getCreatureStateByMapLocation(WorldUtils.vectorToPoint(x, y), ownerId, entity); - entityData.setComponent(entity, new CreatureAi(gameTimer.getGameTime(), creatureState, creatureId)); + CreatureState creatureState; + switch (spawnType) { + case ENTRANCE -> { + creatureState = CreatureState.ENTERING_DUNGEON; + } + case PLACE -> { + creatureState = getCreatureStateByMapLocation(WorldUtils.vectorToPoint(x, y), ownerId, entity); + } + case CONJURE -> { + creatureState = null; + entityData.setComponent(entity, new CreatureFall()); + } + default -> + throw new RuntimeException("SpawnType " + spawnType + " not handled!"); + } + if (creatureState != null) { + entityData.setComponent(entity, new CreatureAi(gameTimer.getGameTime(), creatureState, creatureId)); + } // Regeneration Regeneration regeneration = new Regeneration(); @@ -320,7 +336,7 @@ private EntityId loadCreature(EntityId entity, Creature creature, String name, S // Position // FIXME: no floor height - entityData.setComponent(entity, new Position(rotation, new Vector3f(x, MapViewController.FLOOR_HEIGHT, y))); + entityData.setComponent(entity, new Position(rotation, new Vector3f(x, spawnType == SpawnType.CONJURE ? WorldUtils.DROP_HEIGHT : WorldUtils.FLOOR_HEIGHT, y))); // Mobility entityData.setComponent(entity, new Mobile(creature.getFlags().contains(Creature.CreatureFlag.CAN_FLY), @@ -568,7 +584,7 @@ public void turnCreatureIntoAnother(EntityId entityId, short playerId, short cre EntityId newEntityId = entityData.createEntity(); // Load the creature anew - loadCreature(newEntityId, kwdFile.getCreature(creatureId), creatureComponent.name, creatureComponent.bloodType, 100, 0, 1, false, position.position.x, position.position.z, playerId, position.rotation, null, (short) 0, 0, trigger != null ? trigger.triggerId : null); + loadCreature(newEntityId, kwdFile.getCreature(creatureId), creatureComponent.name, creatureComponent.bloodType, 100, 0, 1, SpawnType.PLACE, position.position.x, position.position.z, playerId, position.rotation, null, (short) 0, 0, trigger != null ? trigger.triggerId : null); } } diff --git a/src/toniarts/openkeeper/game/controller/GameController.java b/src/toniarts/openkeeper/game/controller/GameController.java index b2788e9d..eab5756b 100644 --- a/src/toniarts/openkeeper/game/controller/GameController.java +++ b/src/toniarts/openkeeper/game/controller/GameController.java @@ -218,6 +218,7 @@ public void createNewGame() { gameWorldController.createNewGame(this, this); positionSystem = new PositionSystem(gameWorldController.getMapController(), entityData, gameWorldController.getCreaturesController(), gameWorldController.getDoorsController(), gameWorldController.getObjectsController()); + gameWorldController.setEntityPositionLookup(positionSystem); // Navigation navigationService = new NavigationService(gameWorldController.getMapController(), positionSystem); diff --git a/src/toniarts/openkeeper/game/controller/GameWorldController.java b/src/toniarts/openkeeper/game/controller/GameWorldController.java index dd1fbd3b..fd10593c 100644 --- a/src/toniarts/openkeeper/game/controller/GameWorldController.java +++ b/src/toniarts/openkeeper/game/controller/GameWorldController.java @@ -68,6 +68,7 @@ import toniarts.openkeeper.game.controller.room.storage.IRoomObjectControl; import toniarts.openkeeper.game.controller.room.storage.RoomGoldControl; import toniarts.openkeeper.game.data.Keeper; +import toniarts.openkeeper.game.data.ResearchableEntity; import toniarts.openkeeper.game.listener.PlayerActionListener; import toniarts.openkeeper.game.logic.IEntityPositionLookup; import toniarts.openkeeper.game.map.IMapTileController; @@ -79,6 +80,7 @@ import toniarts.openkeeper.tools.convert.map.KwdFile; import toniarts.openkeeper.tools.convert.map.Player; import toniarts.openkeeper.tools.convert.map.Room; +import toniarts.openkeeper.tools.convert.map.Shot; import toniarts.openkeeper.tools.convert.map.Terrain; import toniarts.openkeeper.tools.convert.map.Tile; import toniarts.openkeeper.tools.convert.map.Trap; @@ -92,7 +94,7 @@ */ public class GameWorldController implements IGameWorldController, IPlayerActions { - private static final Logger LOGGER = Logger.getLogger(GameWorldController.class.getName()); + private static final Logger logger = Logger.getLogger(GameWorldController.class.getName()); /** * When dealing with gold... We currently better lock it. Logic stuff @@ -126,7 +128,6 @@ public GameWorldController(KwdFile kwdFile, EntityData entityData, Map { + } + case NONE -> { return; - case ALL_CREATURES: { + } + case ALL_CREATURES -> { if (creature == null) { return; } - break; } - case ENEMY_CREATURES: { + case ENEMY_CREATURES -> { if (owner == null) { return; } if (!player.isEnemy(owner)) { return; } - break; } - case OWN_CREATURES: - case POSESSION: { + case OWN_CREATURES, POSESSION -> { if (creature == null || owner == null || owner != playerId) { return; } } } + // Cast the spell + Shot shot = kwdFile.getShotById(keeperSpell.getShotTypeId()); + int shotData1 = researchableEntity.isUpgraded() ? keeperSpell.getBonusShotData1() : keeperSpell.getShotData1(); + int shotData2 = researchableEntity.isUpgraded() ? keeperSpell.getBonusShotData2() : keeperSpell.getShotData2(); + switch (shot.getProcessType()) { + case CREATE_CREATURE -> { + creaturesController.spawnCreature((short) shotData1, playerId, shotData2, position, ICreaturesController.SpawnType.CONJURE); + } + case MODIFY_HEALTH -> { + + } + default -> + logger.log(Level.WARNING, "Shot type {0} not implemented", shot.getProcessType()); + } } @Override public void placeDoor(short doorId, Point tile, short playerId) { Door door = kwdFile.getDoorById(doorId); if (door == null) { - LOGGER.log(Level.WARNING, "Invalid door ID for door placement received, was: {0}", door); + logger.log(Level.WARNING, "Invalid door ID for door placement received, was: {0}", door); return; } IMapTileInformation mapTile = mapController.getMapData().getTile(tile); if (mapTile == null) { - LOGGER.log(Level.WARNING, "Invalid map location for door placement received, was: {0}", tile); + logger.log(Level.WARNING, "Invalid map location for door placement received, was: {0}", tile); return; } Keeper player = players.get(playerId); if (player == null) { - LOGGER.log(Level.WARNING, "Invalid player for door placement received, was: {0}", playerId); + logger.log(Level.WARNING, "Invalid player for door placement received, was: {0}", playerId); return; } @@ -1016,19 +1034,19 @@ public void placeDoor(short doorId, Point tile, short playerId) { public void placeTrap(short trapId, Point tile, short playerId) { Trap trap = kwdFile.getTrapById(trapId); if (trap == null) { - LOGGER.log(Level.WARNING, "Invalid trap ID for trap placement received, was: {0}", trap); + logger.log(Level.WARNING, "Invalid trap ID for trap placement received, was: {0}", trap); return; } IMapTileInformation mapTile = mapController.getMapData().getTile(tile); if (mapTile == null) { - LOGGER.log(Level.WARNING, "Invalid map location for trap placement received, was: {0}", tile); + logger.log(Level.WARNING, "Invalid map location for trap placement received, was: {0}", tile); return; } Keeper player = players.get(playerId); if (player == null) { - LOGGER.log(Level.WARNING, "Invalid player for trap placement received, was: {0}", playerId); + logger.log(Level.WARNING, "Invalid player for trap placement received, was: {0}", playerId); return; } @@ -1052,4 +1070,8 @@ public IObjectsController getObjectsController() { public ITrapsController getTrapsController() { return trapsController; } + + public void setEntityPositionLookup(IEntityPositionLookup entityPositionLookup) { + this.entityPositionLookup = entityPositionLookup; + } } diff --git a/src/toniarts/openkeeper/game/controller/ICreaturesController.java b/src/toniarts/openkeeper/game/controller/ICreaturesController.java index b17bb781..f3d16939 100644 --- a/src/toniarts/openkeeper/game/controller/ICreaturesController.java +++ b/src/toniarts/openkeeper/game/controller/ICreaturesController.java @@ -30,6 +30,12 @@ */ public interface ICreaturesController extends IEntityWrapper { + public enum SpawnType { + PLACE, + ENTRANCE, + CONJURE + } + /** * Spawn a creature * @@ -46,11 +52,10 @@ public interface ICreaturesController extends IEntityWrapper