diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java index 1aea5b9f0..40e3f9dac 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java @@ -263,7 +263,7 @@ public final class CombatController implements VisualEffectCompletedCallback { } world.model.player.nextPosition.set(dest); - controllers.movementController.moveToNextIfPossible(false); + controllers.movementController.moveToNextIfPossible(); playerActionCompleted(); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ConversationController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ConversationController.java index 3987b1df2..d5d8438a7 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ConversationController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ConversationController.java @@ -14,6 +14,7 @@ import com.gpl.rpg.AndorsTrail.model.item.Loot; import com.gpl.rpg.AndorsTrail.model.quest.QuestLogEntry; import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress; import com.gpl.rpg.AndorsTrail.util.ConstRange; +import com.gpl.rpg.AndorsTrail.util.L; import java.util.ArrayList; @@ -268,11 +269,21 @@ public final class ConversationController { } private void endConversationWithRemovingNPC() { + if (npc == null) { + if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) L.log("Tried to remove NPC from conversation without having a valid npc target!"); + listener.onConversationEnded(); + return; + } controllers.monsterSpawnController.remove(world.model.currentMap, npc); listener.onConversationEndedWithRemoval(npc); } private void endConversationWithCombat() { + if (npc == null) { + if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) L.log("Tried to enter combat from conversation without having a valid npc target!"); + listener.onConversationEnded(); + return; + } npc.forceAggressive(); controllers.combatController.setCombatSelection(npc); controllers.combatController.enterCombat(CombatController.BeginTurnAs.player); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/GameRoundController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/GameRoundController.java index d43cc65a4..bfdf4a7d2 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/GameRoundController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/GameRoundController.java @@ -3,6 +3,7 @@ package com.gpl.rpg.AndorsTrail.controller; import com.gpl.rpg.AndorsTrail.context.ControllerContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.listeners.GameRoundListeners; +import com.gpl.rpg.AndorsTrail.model.map.MapObject; import com.gpl.rpg.AndorsTrail.util.TimedMessageTask; public final class GameRoundController implements TimedMessageTask.Callback { @@ -81,6 +82,7 @@ public final class GameRoundController implements TimedMessageTask.Callback { public void onNewPlayerRound() { controllers.actorStatsController.applyConditionsToPlayer(world.model.player, false); controllers.actorStatsController.applySkillEffectsForNewRound(world.model.player, world.model.currentMap); + controllers.mapController.handleMapEvents(world.model.currentMap, world.model.player.position, MapObject.MapObjectEvaluationType.afterEveryRound); } public void onNewMonsterRound() { controllers.actorStatsController.applyConditionsToMonsters(world.model.currentMap, false); @@ -91,6 +93,7 @@ public final class GameRoundController implements TimedMessageTask.Callback { controllers.monsterSpawnController.maybeSpawn(world.model.currentMap, world.model.currentTileMap); controllers.monsterMovementController.attackWithAgressiveMonsters(); controllers.effectController.updateSplatters(world.model.currentMap); + controllers.mapController.handleMapEvents(world.model.currentMap, world.model.player.position, MapObject.MapObjectEvaluationType.continuously); gameRoundListeners.onNewTick(); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MapController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MapController.java index 48b121864..9c99bd067 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MapController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MapController.java @@ -29,7 +29,31 @@ public final class MapController { this.world = world; } - public void handleMapEvent(MapObject o, Coord position) { + public void handleMapEventsAfterMovement(PredefinedMap currentMap, Coord newPosition, Coord lastPosition) { + // We don't allow event objects to overlap, so there can only be one object returned here. + MapObject mapObject = currentMap.getEventObjectAt(newPosition); + if (mapObject == null) return; + + switch (mapObject.evaluateWhen) { + case afterEveryRound: + return; + case whenEntering: + // Do not trigger event if the player already was on the same MapObject before. + if (mapObject.position.contains(lastPosition)) return; + break; + } + handleMapEvent(mapObject, newPosition); + } + + public void handleMapEvents(PredefinedMap currentMap, Coord position, MapObject.MapObjectEvaluationType evaluationType) { + MapObject mapObject = currentMap.getEventObjectAt(position); + if (mapObject == null) return; + if (mapObject.evaluateWhen != evaluationType) return; + handleMapEvent(mapObject, position); + } + + private void handleMapEvent(MapObject o, Coord position) { + if (!shouldHandleMapEvent(o)) return; switch (o.type) { case sign: if (o.id == null || o.id.length() <= 0) return; @@ -46,11 +70,22 @@ public final class MapController { break; case script: runScriptArea(o); + break; } } + private boolean shouldHandleMapEvent(MapObject mapObject) { + if (world.model.uiSelections.isInCombat) { + // Only "script" events may run while in combat. + if (mapObject.type != MapObject.MapObjectType.script) return false; + } + return true; + } + private void runScriptArea(MapObject o) { - mapScriptExecutor.proceedToPhrase(controllers.getResources(), o.id, true, true); + Resources res = controllers.getResources(); + mapScriptExecutor.proceedToPhrase(res, o.id, true, true); + controllers.mapController.applyCurrentMapReplacements(res, true); } private void steppedOnRestArea(MapObject area) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java index 2c3b4a8bc..c8946ed77 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java @@ -121,7 +121,7 @@ public final class MovementController implements TimedMessageTask.Callback { return; } - moveToNextIfPossible(true); + moveToNextIfPossible(); } private boolean findWalkablePosition(int dx, int dy) { @@ -207,7 +207,7 @@ public final class MovementController implements TimedMessageTask.Callback { else return -v; } - public void moveToNextIfPossible(boolean handleEvents) { + public void moveToNextIfPossible() { final Player player = world.model.player; final PredefinedMap currentMap = world.model.currentMap; final Coord newPosition = player.nextPosition; @@ -225,14 +225,9 @@ public final class MovementController implements TimedMessageTask.Callback { controllers.combatController.setCombatSelection(null, null); playerMovementListeners.onPlayerMoved(newPosition, player.lastPosition); - if (handleEvents) { - MapObject o = currentMap.getEventObjectAt(newPosition); - if (o != null) { - if (!o.position.contains(player.lastPosition)) { // Do not trigger event if the player already was on the same MapObject before. - controllers.mapController.handleMapEvent(o, newPosition); - } - } + controllers.mapController.handleMapEventsAfterMovement(currentMap, newPosition, player.lastPosition); + if (!world.model.uiSelections.isInCombat) { Loot loot = currentMap.getBagAt(newPosition); if (loot != null) controllers.itemController.playerSteppedOnLootBag(loot); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapObject.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapObject.java index 6bfde347e..e3c71a5c5 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapObject.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapObject.java @@ -17,7 +17,7 @@ public final class MapObject { public static enum MapObjectEvaluationType { whenEntering ,onEveryStep - ,afterEveryTurn + ,afterEveryRound ,continuously } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapTranslator.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapTranslator.java index e390f7577..7cbfce35a 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapTranslator.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapTranslator.java @@ -147,8 +147,8 @@ public final class TMXMapTranslator { evaluateWhen = MapObject.MapObjectEvaluationType.whenEntering; } else if (p.value.equalsIgnoreCase("step")) { evaluateWhen = MapObject.MapObjectEvaluationType.onEveryStep; - } else if (p.value.equalsIgnoreCase("turn")) { - evaluateWhen = MapObject.MapObjectEvaluationType.afterEveryTurn; + } else if (p.value.equalsIgnoreCase("round")) { + evaluateWhen = MapObject.MapObjectEvaluationType.afterEveryRound; } else if (p.value.equalsIgnoreCase("always")) { evaluateWhen = MapObject.MapObjectEvaluationType.continuously; } else if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) {