From e3ea3342c5bd4fc803f93f7d631787b28398f910 Mon Sep 17 00:00:00 2001 From: Oskar Wiksten Date: Sat, 12 Jan 2013 20:02:38 +0100 Subject: [PATCH] Work in progress on moving UI dependencies into being pubsub instead of direct calls from model->ui. --- .../AndorsTrail/AndorsTrailApplication.java | 16 +- .../src/com/gpl/rpg/AndorsTrail/Dialogs.java | 118 +++++---- .../com/gpl/rpg/AndorsTrail/Savegames.java | 13 +- .../com/gpl/rpg/AndorsTrail/WorldSetup.java | 13 +- .../AndorsTrail/activity/AboutActivity.java | 2 +- .../activity/ActorConditionInfoActivity.java | 2 +- .../activity/BulkSelectionInterface.java | 4 +- .../activity/ConversationActivity.java | 7 +- .../AndorsTrail/activity/DebugInterface.java | 12 +- .../activity/DisplayWorldMapActivity.java | 4 +- .../activity/HeroinfoActivity.java | 4 +- .../activity/HeroinfoActivity_Inventory.java | 4 +- .../activity/HeroinfoActivity_Quests.java | 12 +- .../activity/HeroinfoActivity_Skills.java | 7 +- .../activity/HeroinfoActivity_Stats.java | 8 +- .../activity/ItemInfoActivity.java | 4 +- .../AndorsTrail/activity/LevelUpActivity.java | 54 +---- .../activity/LoadSaveActivity.java | 6 +- .../AndorsTrail/activity/LoadingActivity.java | 4 +- .../AndorsTrail/activity/MainActivity.java | 225 ++++++++++++++--- .../activity/MonsterEncounterActivity.java | 2 +- .../activity/MonsterInfoActivity.java | 6 +- .../AndorsTrail/activity/ShopActivity.java | 4 +- .../activity/SkillInfoActivity.java | 4 +- .../activity/StartScreenActivity.java | 17 +- .../rpg/AndorsTrail/context/ViewContext.java | 48 ++-- .../controller/ActorStatsController.java | 226 ++++++++++++----- .../controller/CombatController.java | 228 ++++++++---------- .../AndorsTrail/controller/Controller.java | 83 +++---- .../controller/ConversationController.java | 17 +- .../controller/GameRoundController.java | 35 ++- .../controller/InputController.java | 21 +- .../controller/ItemController.java | 131 +++++----- .../controller/MonsterMovementController.java | 55 +++-- .../controller/MonsterSpawningController.java | 80 ++++++ .../controller/MovementController.java | 63 +++-- .../controller/SkillController.java | 33 ++- .../controller/VisualEffectController.java | 43 ++-- .../listeners/CombatActionListener.java | 15 ++ .../listeners/CombatActionListeners.java | 80 ++++++ .../listeners/CombatSelectionListener.java | 10 + .../listeners/CombatSelectionListeners.java | 35 +++ .../listeners/CombatTurnListener.java | 10 + .../listeners/CombatTurnListeners.java | 43 ++++ .../controller/listeners/LootBagListener.java | 8 + .../listeners/LootBagListeners.java | 25 ++ .../listeners/MonsterMovementListener.java | 9 + .../listeners/MonsterMovementListeners.java | 26 ++ .../listeners/MonsterSpawnListener.java | 13 + .../listeners/MonsterSpawnListeners.java | 54 +++++ .../listeners/PlayerMovementListener.java | 9 + .../listeners/PlayerMovementListeners.java | 26 ++ .../listeners/PlayerStatsListener.java | 7 + .../listeners/PlayerStatsListeners.java | 16 ++ .../listeners/QuickSlotListener.java | 6 + .../listeners/QuickSlotListeners.java | 24 ++ .../listeners/VisualEffectFrameListener.java | 8 + .../listeners/VisualEffectFrameListeners.java | 25 ++ .../listeners/WorldEventListener.java | 19 ++ .../listeners/WorldEventListeners.java | 108 +++++++++ .../rpg/AndorsTrail/model/ModelContainer.java | 5 +- .../rpg/AndorsTrail/model/actor/Actor.java | 15 +- .../rpg/AndorsTrail/model/actor/Monster.java | 4 +- .../rpg/AndorsTrail/model/actor/Player.java | 22 +- .../gpl/rpg/AndorsTrail/model/item/Loot.java | 11 + .../model/listeners/ActorStatsListener.java | 10 + .../model/listeners/ActorStatsListeners.java | 43 ++++ .../model/listeners/ListOfListeners.java | 10 + .../AndorsTrail/model/map/MapCollection.java | 5 +- .../model/map/MonsterSpawnArea.java | 10 +- .../AndorsTrail/model/map/PredefinedMap.java | 69 +----- .../LegacySavegameFormatReaderForPlayer.java | 14 +- .../com/gpl/rpg/AndorsTrail/util/Range.java | 8 +- .../AndorsTrail/view/ActorConditionList.java | 2 +- .../gpl/rpg/AndorsTrail/view/CombatView.java | 114 +++++++-- .../DisplayActiveActorConditionIcons.java | 25 +- .../gpl/rpg/AndorsTrail/view/MainView.java | 154 ++++++++++-- .../rpg/AndorsTrail/view/QuickitemView.java | 24 +- .../gpl/rpg/AndorsTrail/view/RangeBar.java | 9 +- .../gpl/rpg/AndorsTrail/view/StatusView.java | 51 +++- .../gpl/rpg/AndorsTrail/view/ToolboxView.java | 4 +- .../rpg/AndorsTrail/view/VirtualDpadView.java | 4 +- 82 files changed, 1989 insertions(+), 815 deletions(-) create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MonsterSpawningController.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListener.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListeners.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatSelectionListener.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatSelectionListeners.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatTurnListener.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatTurnListeners.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/LootBagListener.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/LootBagListeners.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterMovementListener.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterMovementListeners.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterSpawnListener.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterSpawnListeners.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerMovementListener.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerMovementListeners.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerStatsListener.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerStatsListeners.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/QuickSlotListener.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/QuickSlotListeners.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/VisualEffectFrameListener.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/VisualEffectFrameListeners.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/WorldEventListener.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/WorldEventListeners.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorStatsListener.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorStatsListeners.java diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java index 3229c6271..5b7415d9a 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java @@ -1,7 +1,5 @@ package com.gpl.rpg.AndorsTrail; -import java.lang.ref.WeakReference; - import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; @@ -23,10 +21,14 @@ public final class AndorsTrailApplication extends Application { public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? 999 : 34; public static final String CURRENT_VERSION_DISPLAY = "0.7.0dev"; - public final WorldContext world = new WorldContext(); - public final WorldSetup setup = new WorldSetup(world, this); - public WeakReference currentView; - public final AndorsTrailPreferences preferences = new AndorsTrailPreferences(); + private final AndorsTrailPreferences preferences = new AndorsTrailPreferences(); + private final WorldContext world = new WorldContext(); + private final ViewContext view = new ViewContext(this, world); + private final WorldSetup setup = new WorldSetup(world, view, this); + public WorldContext getWorld() { return world; } + public WorldSetup getWorldSetup() { return setup; } + public AndorsTrailPreferences getPreferences() { return preferences; } + public ViewContext getViewContext() { return view; } public static AndorsTrailApplication getApplicationFromActivity(Activity activity) { return ((AndorsTrailApplication) activity.getApplication()); @@ -40,7 +42,7 @@ public final class AndorsTrailApplication extends Application { public boolean isInitialized() { return world.model != null; } - public static void setWindowParameters(Activity activity, final AndorsTrailPreferences preferences) { + public void setWindowParameters(Activity activity) { activity.requestWindowFeature(Window.FEATURE_NO_TITLE); if (preferences.fullscreen) { activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/Dialogs.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/Dialogs.java index 37347f081..9434a50d6 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/Dialogs.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/Dialogs.java @@ -1,7 +1,6 @@ package com.gpl.rpg.AndorsTrail; import java.util.Arrays; -import java.util.HashSet; import android.app.Activity; import android.app.AlertDialog; @@ -39,8 +38,6 @@ import com.gpl.rpg.AndorsTrail.activity.SkillInfoActivity; import com.gpl.rpg.AndorsTrail.activity.StartScreenActivity; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.controller.Controller; -import com.gpl.rpg.AndorsTrail.controller.ItemController; import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionType; import com.gpl.rpg.AndorsTrail.model.actor.Monster; import com.gpl.rpg.AndorsTrail.model.item.ItemType; @@ -112,84 +109,81 @@ public final class Dialogs { currentActivity.startActivityForResult(intent, MainActivity.INTENTREQUEST_MONSTERENCOUNTER); } - public static void showMonsterInfo(final Activity currentActivity, final Monster monster) { - Intent intent = new Intent(currentActivity, MonsterInfoActivity.class); + public static void showMonsterInfo(final Context context, final Monster monster) { + Intent intent = new Intent(context, MonsterInfoActivity.class); intent.setData(Uri.parse("content://com.gpl.rpg.AndorsTrail/monsterinfo")); addMonsterIdentifiers(intent, monster); - currentActivity.startActivity(intent); + context.startActivity(intent); } - public static void showMonsterLoot(final MainActivity mainActivity, final ViewContext context, final HashSet lootBags, int totalExpThisFight) { - // The real object of lootBags will get clear():ed by the caller after we have reached this function. - // Therefore, we make a shallow copy of it to remember the Loot objects that should be modified. - HashSet copy = new HashSet(lootBags); - - String msg = mainActivity.getString(R.string.dialog_monsterloot_message); - showLoot(mainActivity, context, copy, totalExpThisFight, R.string.dialog_monsterloot_title, msg, false); - } - - public static void showGroundLoot(final MainActivity mainActivity, final ViewContext context, final Loot loot) { + public static String getGroundLootMessage(final Context ctx, final Loot loot) { String msg = ""; - if (!loot.items.isEmpty()) msg = mainActivity.getString(R.string.dialog_groundloot_message); - showLoot(mainActivity, context, Arrays.asList(loot), 0, R.string.dialog_groundloot_title, msg, !loot.isVisible); - } - - private static void showLoot(final MainActivity mainActivity, final ViewContext context, final Iterable lootBags, final int exp, final int title, String msg, boolean isContainer) { - //if (ItemController.updateLootVisibility(context, lootBags)) return; + if (!loot.items.isEmpty()) msg = ctx.getString(R.string.dialog_groundloot_message); - final Loot combinedLoot = new Loot(); - for (Loot l : lootBags) { - combinedLoot.add(l); + if (loot.gold > 0) { + msg += ctx.getString(R.string.dialog_loot_foundgold, loot.gold); } + msg += getLootMessage(ctx, loot); + return msg; + } + public static String getMonsterLootMessage(final Context ctx, final Loot combinedLoot, final int exp) { + String msg = ctx.getString(R.string.dialog_monsterloot_message); if (exp > 0) { - msg += mainActivity.getString(R.string.dialog_monsterloot_gainedexp, exp); + msg += ctx.getString(R.string.dialog_monsterloot_gainedexp, exp); } - if (combinedLoot.gold > 0) { - msg += mainActivity.getString(R.string.dialog_loot_foundgold, combinedLoot.gold); + msg += getLootMessage(ctx, combinedLoot); + return msg; + } + private static String getLootMessage(final Context ctx, final Loot loot) { + String msg = ""; + if (loot.gold > 0) { + msg += ctx.getString(R.string.dialog_loot_foundgold, loot.gold); } - - if (!isContainer) { - if (context.preferences.displayLoot != AndorsTrailPreferences.DISPLAYLOOT_DIALOG) { - if (context.preferences.displayLoot == AndorsTrailPreferences.DISPLAYLOOT_TOAST) { - int numItems = combinedLoot.items.countItems(); - if (numItems == 1) { - msg += mainActivity.getString(R.string.dialog_loot_pickedupitem); - } else if (numItems > 1){ - msg += mainActivity.getString(R.string.dialog_loot_pickedupitems, numItems); - } - mainActivity.showToast(msg, Toast.LENGTH_LONG); - } - ItemController.pickupAll(lootBags, context.model); - ItemController.updateLootVisibility(context, lootBags); - context.gameRoundController.resume(); - return; - } + int numItems = loot.items.countItems(); + if (numItems == 1) { + msg += ctx.getString(R.string.dialog_loot_pickedupitem); + } else if (numItems > 1){ + msg += ctx.getString(R.string.dialog_loot_pickedupitems, numItems); } - + return msg; + } + + public static void showMonsterLoot(final MainActivity mainActivity, final ViewContext view, final WorldContext world, final Iterable lootBags, final Loot combinedLoot, final String msg) { + showLoot(mainActivity, view, world, combinedLoot, lootBags, R.string.dialog_monsterloot_title, msg); + } + + public static void showGroundLoot(final MainActivity mainActivity, final ViewContext view, final WorldContext world, final Loot loot, final String msg) { + showLoot(mainActivity, view, world, loot, Arrays.asList(loot), R.string.dialog_monsterloot_title, msg); + } + + private static void showLoot(final MainActivity mainActivity, final ViewContext view, final WorldContext world, final Loot combinedLoot, final Iterable lootBags, final int title, final String msg) { final ListView itemList = new ListView(mainActivity); itemList.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, ListView.LayoutParams.WRAP_CONTENT)); itemList.setPadding(20, 0, 20, 20); itemList.setOnItemClickListener(new OnItemClickListener() { @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { + public void onItemClick(AdapterView parent, View v, int position, long id) { final String itemTypeID = ((ItemContainerAdapter) parent.getAdapter()).getItem(position).itemType.id; - combinedLoot.items.removeItem(itemTypeID); for (Loot l : lootBags) { - if (l.items.removeItem(itemTypeID)) break; + if (l.items.removeItem(itemTypeID)) { + view.itemController.removeLootBagIfEmpty(l); + break; + } } - ItemType type = context.itemTypes.getItemType(itemTypeID); - context.model.player.inventory.addItem(type); + combinedLoot.items.removeItem(itemTypeID); + ItemType type = world.itemTypes.getItemType(itemTypeID); + world.model.player.inventory.addItem(type); ((ItemContainerAdapter) itemList.getAdapter()).notifyDataSetChanged(); } }); - itemList.setAdapter(new ItemContainerAdapter(mainActivity, context.tileManager, combinedLoot.items, context.model.player)); + itemList.setAdapter(new ItemContainerAdapter(mainActivity, world.tileManager, combinedLoot.items, world.model.player)); AlertDialog.Builder db = new AlertDialog.Builder(mainActivity) .setTitle(title) .setMessage(msg) - .setIcon(new BitmapDrawable(context.tileManager.preloadedTiles.getBitmap(TileManager.iconID_groundbag))) + .setIcon(new BitmapDrawable(world.tileManager.preloadedTiles.getBitmap(TileManager.iconID_groundbag))) .setNegativeButton(R.string.dialog_close, null) .setView(itemList); @@ -197,17 +191,17 @@ public final class Dialogs { db.setPositiveButton(R.string.dialog_loot_pickall, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - ItemController.pickupAll(lootBags, context.model); + view.itemController.pickupAll(lootBags); } }); } final Dialog d = db.create(); - showDialogAndPause(d, context, new OnDismissListener() { + showDialogAndPause(d, view, new OnDismissListener() { @Override public void onDismiss(DialogInterface arg0) { - ItemController.updateLootVisibility(context, lootBags); + view.itemController.removeLootBagIfEmpty(lootBags); } }); } @@ -228,18 +222,14 @@ public final class Dialogs { currentActivity.startActivityForResult(intent, MainActivity.INTENTREQUEST_LEVELUP); } - public static void showRest(final Activity currentActivity, final ViewContext viewContext, final MapObject area) { - if (!viewContext.preferences.confirmRest) { - Controller.ui_playerRested(currentActivity, viewContext, area); - return; - } + public static void showConfirmRest(final Activity currentActivity, final ViewContext viewContext, final MapObject area) { Dialog d = new AlertDialog.Builder(currentActivity) .setTitle(R.string.dialog_rest_title) .setMessage(R.string.dialog_rest_confirm_message) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - Controller.ui_playerRested(currentActivity, viewContext, area); + viewContext.controller.rest(area); } }) .setNegativeButton(android.R.string.no, null) @@ -270,8 +260,8 @@ public final class Dialogs { currentActivity.startActivityForResult(intent, MainActivity.INTENTREQUEST_PREFERENCES); } - public static void showSave(final MainActivity mainActivity, final ViewContext viewContext) { - if (viewContext.model.uiSelections.isInCombat) { + public static void showSave(final MainActivity mainActivity, final ViewContext viewContext, final WorldContext world) { + if (world.model.uiSelections.isInCombat) { mainActivity.showToast(mainActivity.getResources().getString(R.string.menu_save_saving_not_allowed_in_combat), Toast.LENGTH_SHORT); return; } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/Savegames.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/Savegames.java index 6e6ccd1a6..1395ba0e1 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/Savegames.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/Savegames.java @@ -21,8 +21,8 @@ import java.util.regex.Pattern; import android.content.Context; import android.os.Environment; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.controller.ActorStatsController; import com.gpl.rpg.AndorsTrail.controller.Constants; import com.gpl.rpg.AndorsTrail.controller.Controller; import com.gpl.rpg.AndorsTrail.controller.MovementController; @@ -117,17 +117,18 @@ public final class Savegames { final FileHeader header = new FileHeader(src); if (header.fileversion > AndorsTrailApplication.CURRENT_VERSION) return LOAD_RESULT_FUTURE_VERSION; - world.maps.readFromParcel(src, world, header.fileversion); - world.model = new ModelContainer(src, world, header.fileversion); + ViewContext view = new ViewContext(null, world); + world.maps.readFromParcel(src, world, view, header.fileversion); + world.model = new ModelContainer(src, world, view, header.fileversion); src.close(); - onWorldLoaded(world); + onWorldLoaded(world, view); return LOAD_RESULT_SUCCESS; } - private static void onWorldLoaded(WorldContext world) { - ActorStatsController.recalculatePlayerStats(world.model.player); + private static void onWorldLoaded(WorldContext world, ViewContext view) { + view.actorStatsController.recalculatePlayerStats(world.model.player); Controller.resetMapsNotRecentlyVisited(world); MovementController.moveBlockedActors(world); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/WorldSetup.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/WorldSetup.java index bbb813768..5d53da0a2 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/WorldSetup.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/WorldSetup.java @@ -6,8 +6,8 @@ import android.content.Context; import android.content.res.Resources; import android.os.AsyncTask; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.controller.Controller; import com.gpl.rpg.AndorsTrail.controller.MovementController; import com.gpl.rpg.AndorsTrail.model.ModelContainer; import com.gpl.rpg.AndorsTrail.resource.ResourceLoader; @@ -15,6 +15,7 @@ import com.gpl.rpg.AndorsTrail.resource.ResourceLoader; public final class WorldSetup { private final WorldContext world; + private final ViewContext view; private final WeakReference androidContext; private boolean isResourcesInitialized = false; private boolean isInitializingResources = false; @@ -28,8 +29,9 @@ public final class WorldSetup { public String newHeroName; private int loadResult; - public WorldSetup(WorldContext world, Context androidContext) { + public WorldSetup(WorldContext world, ViewContext view, Context androidContext) { this.world = world; + this.view = view; this.androidContext = new WeakReference(androidContext); } @@ -145,11 +147,12 @@ public final class WorldSetup { } private void createNewWorld() { - Context ctx = androidContext.get(); world.model = new ModelContainer(); world.model.player.initializeNewPlayer(world.itemTypes, world.dropLists, newHeroName); - MovementController.respawnPlayer(ctx.getResources(), world); - Controller.playerRested(world, null); + + view.actorStatsController.recalculatePlayerStats(world.model.player); + view.movementController.respawnPlayer(); + view.controller.lotsOfTimePassed(); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/AboutActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/AboutActivity.java index 1f1a13ed3..67ec852cc 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/AboutActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/AboutActivity.java @@ -23,7 +23,7 @@ public final class AboutActivity extends Activity implements ImageGetter { super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); - AndorsTrailApplication.setWindowParameters(this, app.preferences); + app.setWindowParameters(this); setContentView(R.layout.about); final Resources res = getResources(); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ActorConditionInfoActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ActorConditionInfoActivity.java index f47dfe860..66f980bb9 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ActorConditionInfoActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ActorConditionInfoActivity.java @@ -25,7 +25,7 @@ public class ActorConditionInfoActivity extends Activity { AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } requestWindowFeature(Window.FEATURE_NO_TITLE); - final WorldContext world = app.world; + final WorldContext world = app.getWorld(); String conditionTypeID = getIntent().getData().getLastPathSegment().toString(); ActorConditionType conditionType = world.actorConditionsTypes.getActorConditionType(conditionTypeID); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java index b155d5df7..aa2abd652 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java @@ -73,8 +73,8 @@ public class BulkSelectionInterface extends Activity implements TextWatcher { super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; - AndorsTrailApplication.setWindowParameters(this, app.preferences); + this.world = app.getWorld(); + app.setWindowParameters(this); final Resources res = getResources(); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java index 2ae2d172a..2521bd34a 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java @@ -31,6 +31,7 @@ import android.widget.TextView.BufferType; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.Dialogs; import com.gpl.rpg.AndorsTrail.R; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.ConversationController; import com.gpl.rpg.AndorsTrail.conversation.ConversationCollection; @@ -49,6 +50,7 @@ public final class ConversationActivity extends Activity implements OnKeyListene private static final int NPCConversationColor = Color.argb(255, 0xbb, 0xbb, 0x22); private WorldContext world; + private ViewContext view; private Player player; private String phraseID; private Phrase phrase; @@ -71,7 +73,8 @@ public final class ConversationActivity extends Activity implements OnKeyListene super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; + this.world = app.getWorld(); + this.view = app.getViewContext(); this.player = world.model.player; requestWindowFeature(Window.FEATURE_NO_TITLE); @@ -239,7 +242,7 @@ public final class ConversationActivity extends Activity implements OnKeyListene Loot loot = null; if (applyPhraseRewards) { - loot = ConversationController.applyPhraseRewards(player, phrase, world); + loot = view.conversationController.applyPhraseRewards(player, phrase); } if (phrase.message == null) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java index d3e5c845e..c214105d9 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java @@ -20,11 +20,11 @@ public final class DebugInterface { private final Resources res; private final WorldContext world; - public DebugInterface(ViewContext viewContext) { - this.viewContext = viewContext; - this.mainActivity = viewContext.mainActivity; - this.world = viewContext; + public DebugInterface(ViewContext view, WorldContext world, MainActivity mainActivity) { + this.viewContext = view; + this.world = world; this.res = mainActivity.getResources(); + this.mainActivity = mainActivity; } public void addDebugButtons() { @@ -37,7 +37,6 @@ public final class DebugInterface { world.model.player.damagePotential.set(99, 99); world.model.player.attackChance = 200; world.model.player.attackCost = 1; - mainActivity.updateStatus(); mainActivity.showToast("DEBUG: damagePotential=99, chance=200%, cost=1", Toast.LENGTH_SHORT); } }) @@ -129,9 +128,8 @@ public final class DebugInterface { public void onClick(View arg0) { world.model.player.baseTraits.maxHP = 200; world.model.player.health.max = world.model.player.baseTraits.maxHP; - world.model.player.setMaxHP(); + viewContext.actorStatsController.setActorMaxHealth(world.model.player); world.model.player.conditions.clear(); - mainActivity.updateStatus(); mainActivity.showToast("DEBUG: hp set to max", Toast.LENGTH_SHORT); } }) diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java index cfe9efae5..b68e47bd6 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java @@ -31,9 +31,9 @@ public class DisplayWorldMapActivity extends Activity { AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; + this.world = app.getWorld(); - AndorsTrailApplication.setWindowParameters(this, app.preferences); + app.setWindowParameters(this); setContentView(R.layout.displayworldmap); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity.java index 78ff6e2a6..1fe951994 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity.java @@ -20,9 +20,9 @@ public final class HeroinfoActivity extends ActivityGroup { super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; + this.world = app.getWorld(); - AndorsTrailApplication.setWindowParameters(this, app.preferences); + app.setWindowParameters(this); setContentView(R.layout.heroinfo); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Inventory.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Inventory.java index 8c6db50d0..70de94ef5 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Inventory.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Inventory.java @@ -53,8 +53,8 @@ public final class HeroinfoActivity_Inventory extends Activity { super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; - this.view = app.currentView.get(); + this.world = app.getWorld(); + this.view = app.getViewContext(); this.player = world.model.player; setContentView(R.layout.heroinfo_inventory); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Quests.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Quests.java index 3349027ab..9e990767c 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Quests.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Quests.java @@ -17,6 +17,7 @@ import android.widget.AdapterView.OnItemSelectedListener; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.R; +import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.model.quest.Quest; import com.gpl.rpg.AndorsTrail.model.quest.QuestCollection; @@ -39,9 +40,10 @@ public final class HeroinfoActivity_Quests extends Activity { final AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - AndorsTrailApplication.setWindowParameters(this, app.preferences); - this.questCollection = app.world.quests; - this.player = app.world.model.player; + app.setWindowParameters(this); + final WorldContext world = app.getWorld(); + this.questCollection = world.quests; + this.player = world.model.player; setContentView(R.layout.questlog); @@ -52,14 +54,14 @@ public final class HeroinfoActivity_Quests extends Activity { questlog_includecompleted.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView arg0, View arg1, int arg2, long arg3) { - app.world.model.uiSelections.selectedQuestFilter = questlog_includecompleted.getSelectedItemPosition(); + world.model.uiSelections.selectedQuestFilter = questlog_includecompleted.getSelectedItemPosition(); reloadQuests(); } @Override public void onNothingSelected(AdapterView arg0) {} }); - questlog_includecompleted.setSelection(app.world.model.uiSelections.selectedQuestFilter); + questlog_includecompleted.setSelection(world.model.uiSelections.selectedQuestFilter); ExpandableListView questlog_contents = (ExpandableListView) findViewById(R.id.questlog_contents); questlog_contents_adapter = new SimpleExpandableListAdapter( diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Skills.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Skills.java index d9df87740..251156d92 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Skills.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Skills.java @@ -3,6 +3,7 @@ package com.gpl.rpg.AndorsTrail.activity; import com.gpl.rpg.AndorsTrail.Dialogs; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.R; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.SkillController; import com.gpl.rpg.AndorsTrail.model.actor.Player; @@ -19,6 +20,7 @@ import android.widget.AdapterView.OnItemClickListener; public final class HeroinfoActivity_Skills extends Activity { private WorldContext world; + private ViewContext view; private Player player; @@ -29,7 +31,8 @@ public final class HeroinfoActivity_Skills extends Activity { super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; + this.world = app.getWorld(); + this.view = app.getViewContext(); this.player = world.model.player; setContentView(R.layout.heroinfo_skill_list); @@ -59,7 +62,7 @@ public final class HeroinfoActivity_Skills extends Activity { if (resultCode != RESULT_OK) break; int skillID = data.getExtras().getInt("skillID"); - SkillController.levelUpSkillManually(player, world.skills.getSkill(skillID)); + view.skillController.levelUpSkillManually(player, skillID); break; } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Stats.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Stats.java index befcb3b0d..7537ef98c 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Stats.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Stats.java @@ -50,7 +50,7 @@ public final class HeroinfoActivity_Stats extends Activity { super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; + this.world = app.getWorld(); this.player = world.model.player; setContentView(R.layout.heroinfo_stats); @@ -114,15 +114,15 @@ public final class HeroinfoActivity_Stats extends Activity { private void updateTraits() { heroinfo_level.setText(Integer.toString(player.getLevel())); heroinfo_totalexperience.setText(Integer.toString(player.getTotalExperience())); - heroinfo_ap.setText(player.ap.toString()); + heroinfo_ap.setText(player.getMaxAP() + "/" + player.getCurrentAP()); heroinfo_reequip_cost.setText(Integer.toString(player.getReequipCost())); heroinfo_useitem_cost.setText(Integer.toString(player.getUseItemCost())); basetraitsinfo_max_hp.setText(Integer.toString(player.baseTraits.maxHP)); basetraitsinfo_max_ap.setText(Integer.toString(player.baseTraits.maxAP)); heroinfo_base_reequip_cost.setText(Integer.toString(player.baseTraits.reequipCost)); heroinfo_base_useitem_cost.setText(Integer.toString(player.baseTraits.useItemCost)); - rangebar_hp.update(player.health); - rangebar_exp.update(player.levelExperience); + rangebar_hp.update(player.getMaxHP(), player.getCurrentHP()); + rangebar_exp.update(player.getMaxLevelExperience(), player.getCurrentLevelExperience()); TraitsInfoView.update(heroinfo_container, player); TraitsInfoView.updateTraitsTable( diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java index bd0d4d90e..bfb4274b1 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java @@ -33,9 +33,9 @@ public final class ItemInfoActivity extends Activity { super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; + this.world = app.getWorld(); - AndorsTrailApplication.setWindowParameters(this, app.preferences); + app.setWindowParameters(this); final Intent intent = getIntent(); Bundle params = intent.getExtras(); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java index 973bdbc28..b70bbf608 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java @@ -11,26 +11,27 @@ import android.widget.TextView; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.R; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.ActorStatsController; import com.gpl.rpg.AndorsTrail.controller.Constants; -import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection; import com.gpl.rpg.AndorsTrail.model.actor.Player; public final class LevelUpActivity extends Activity { private WorldContext world; + private ViewContext view; private Player player; private TextView levelup_description; private TextView levelup_title; private View levelup_adds_new_skillpoint; - /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; + this.world = app.getWorld(); + this.view = app.getViewContext(); this.player = world.model.player; requestWindowFeature(Window.FEATURE_NO_TITLE); @@ -47,7 +48,7 @@ public final class LevelUpActivity extends Activity { b.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { - levelup(SELECT_HEALTH); + levelup(ActorStatsController.LEVELUP_HEALTH); } }); b.setText(getString(R.string.levelup_add_health, Constants.LEVELUP_EFFECT_HEALTH)); @@ -56,7 +57,7 @@ public final class LevelUpActivity extends Activity { b.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { - levelup(SELECT_ATK_CH); + levelup(ActorStatsController.LEVELUP_ATTACK_CHANCE); } }); b.setText(getString(R.string.levelup_add_attackchance, Constants.LEVELUP_EFFECT_ATK_CH)); @@ -65,7 +66,7 @@ public final class LevelUpActivity extends Activity { b.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { - levelup(SELECT_ATK_DMG); + levelup(ActorStatsController.LEVELUP_ATTACK_DAMAGE); } }); b.setText(getString(R.string.levelup_add_attackdamage, Constants.LEVELUP_EFFECT_ATK_DMG)); @@ -74,7 +75,7 @@ public final class LevelUpActivity extends Activity { b.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { - levelup(SELECT_DEF_CH); + levelup(ActorStatsController.LEVELUP_BLOCK_CHANCE); } }); b.setText(getString(R.string.levelup_add_blockchance, Constants.LEVELUP_EFFECT_DEF_CH)); @@ -99,45 +100,10 @@ public final class LevelUpActivity extends Activity { } } - private static final int SELECT_HEALTH = 0; - private static final int SELECT_ATK_CH = 1; - private static final int SELECT_ATK_DMG = 2; - private static final int SELECT_DEF_CH = 3; - public void levelup(int selectionID) { if (LevelUpActivity.this.isFinishing()) return; - addLevelupEffect(player, selectionID); - LevelUpActivity.this.finish(); - } - - public static void addLevelupEffect(Player player, int selectionID) { - int hpIncrease = 0; - switch (selectionID) { - case SELECT_HEALTH: - hpIncrease = Constants.LEVELUP_EFFECT_HEALTH; - break; - case SELECT_ATK_CH: - player.baseTraits.attackChance += Constants.LEVELUP_EFFECT_ATK_CH; - break; - case SELECT_ATK_DMG: - player.baseTraits.damagePotential.max += Constants.LEVELUP_EFFECT_ATK_DMG; - player.baseTraits.damagePotential.current += Constants.LEVELUP_EFFECT_ATK_DMG; - break; - case SELECT_DEF_CH: - player.baseTraits.blockChance += Constants.LEVELUP_EFFECT_DEF_CH; - break; - } - if (player.nextLevelAddsNewSkillpoint()) { - player.availableSkillIncreases++; - } - player.level++; - - hpIncrease += player.getSkillLevel(SkillCollection.SKILL_FORTITUDE) * SkillCollection.PER_SKILLPOINT_INCREASE_FORTITUDE_HEALTH; - player.health.max += hpIncrease; - player.baseTraits.maxHP += hpIncrease; - player.health.current += hpIncrease; - - ActorStatsController.recalculatePlayerStats(player); + view.actorStatsController.addLevelupEffect(player, selectionID); + finish(); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java index 563df2ee0..17ed2b69c 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java @@ -34,9 +34,9 @@ public final class LoadSaveActivity extends Activity implements OnClickListener super.onCreate(savedInstanceState); final AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); - AndorsTrailApplication.setWindowParameters(this, app.preferences); - this.model = app.world.model; - this.preferences = app.preferences; + app.setWindowParameters(this); + this.model = app.getWorld().model; + this.preferences = app.getPreferences(); String loadsave = getIntent().getData().getLastPathSegment().toString(); isLoading = (loadsave.equalsIgnoreCase("load")); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LoadingActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LoadingActivity.java index abd411f5e..9b95f88b1 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LoadingActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LoadingActivity.java @@ -27,8 +27,8 @@ public final class LoadingActivity extends Activity implements OnResourcesLoaded public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); - AndorsTrailApplication.setWindowParameters(this, app.preferences); - this.setup = app.setup; + app.setWindowParameters(this); + this.setup = app.getWorldSetup(); } @Override diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java index 44491a7e8..215475a8a 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java @@ -11,9 +11,17 @@ import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.CombatController; import com.gpl.rpg.AndorsTrail.controller.MovementController; +import com.gpl.rpg.AndorsTrail.controller.listeners.CombatActionListener; +import com.gpl.rpg.AndorsTrail.controller.listeners.CombatTurnListener; +import com.gpl.rpg.AndorsTrail.controller.listeners.PlayerMovementListener; +import com.gpl.rpg.AndorsTrail.controller.listeners.WorldEventListener; +import com.gpl.rpg.AndorsTrail.model.AttackResult; import com.gpl.rpg.AndorsTrail.model.actor.Monster; import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.model.item.ItemContainer.ItemEntry; +import com.gpl.rpg.AndorsTrail.model.item.Loot; +import com.gpl.rpg.AndorsTrail.model.map.MapObject; +import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap; import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.view.CombatView; import com.gpl.rpg.AndorsTrail.view.DisplayActiveActorConditionIcons; @@ -39,7 +47,7 @@ import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; -public final class MainActivity extends Activity { +public final class MainActivity extends Activity implements PlayerMovementListener, CombatActionListener, CombatTurnListener, WorldEventListener { public static final int INTENTREQUEST_MONSTERENCOUNTER = 2; public static final int INTENTREQUEST_ITEMINFO = 3; @@ -76,17 +84,17 @@ public final class MainActivity extends Activity { AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; - this.view = new ViewContext(app, this); - app.currentView = new WeakReference(this.view); - AndorsTrailApplication.setWindowParameters(this, app.preferences); + AndorsTrailPreferences preferences = app.getPreferences(); + this.world = app.getWorld(); + this.view = app.getViewContext(); + app.setWindowParameters(this); setContentView(R.layout.main); mainview = (MainView) findViewById(R.id.main_mainview); statusview = (StatusView) findViewById(R.id.main_statusview); combatview = (CombatView) findViewById(R.id.main_combatview); quickitemview = (QuickitemView) findViewById(R.id.main_quickitemview); - activeConditions = new DisplayActiveActorConditionIcons(app.preferences, world.tileManager, this, (RelativeLayout) findViewById(R.id.statusview_activeconditions)); + activeConditions = new DisplayActiveActorConditionIcons(view, world, this, (RelativeLayout) findViewById(R.id.statusview_activeconditions)); dpad = (VirtualDpadView) findViewById(R.id.main_virtual_dpad); toolboxview = (ToolboxView) findViewById(R.id.main_toolboxview); statusview.registerToolboxViews(toolboxview, quickitemview); @@ -100,12 +108,13 @@ public final class MainActivity extends Activity { }); clearMessages(); - if (AndorsTrailApplication.DEVELOPMENT_DEBUGBUTTONS) new DebugInterface(view).addDebugButtons(); + if (AndorsTrailApplication.DEVELOPMENT_DEBUGBUTTONS) + new DebugInterface(view, world, this).addDebugButtons(); quickitemview.setVisibility(View.GONE); quickitemview.registerForContextMenu(this); - dpad.updateVisibility(app.preferences); + dpad.updateVisibility(preferences); // Define which views are in front of each other. dpad.bringToFront(); @@ -139,15 +148,15 @@ public final class MainActivity extends Activity { final Coord p = world.model.player.nextPosition; Monster m = world.model.currentMap.getMonsterAt(p); if (m == null) return; - world.model.currentMap.remove(m); - redrawAll(MainView.REDRAW_ALL_MONSTER_KILLED); + view.monsterSpawnController.remove(world.model.currentMap, m); } break; case INTENTREQUEST_PREFERENCES: AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); - AndorsTrailPreferences.read(this, app.preferences); - world.tileManager.updatePreferences(app.preferences); - dpad.updateVisibility(app.preferences); + AndorsTrailPreferences preferences = app.getPreferences(); + AndorsTrailPreferences.read(this, preferences); + world.tileManager.updatePreferences(preferences); + dpad.updateVisibility(preferences); break; case INTENTREQUEST_SAVEGAME: if (resultCode != Activity.RESULT_OK) break; @@ -172,17 +181,17 @@ public final class MainActivity extends Activity { view.gameRoundController.pause(); view.movementController.stopMovement(); - activeConditions.unsubscribe(world); + unsubscribeFromModel(); save(Savegames.SLOT_QUICKSAVE); } - @Override + @Override protected void onResume() { super.onResume(); - if (!AndorsTrailApplication.getApplicationFromActivity(this).setup.isSceneReady) return; + if (!AndorsTrailApplication.getApplicationFromActivity(this).getWorldSetup().isSceneReady) return; - activeConditions.subscribe(world); + subscribeToModelChanges(); view.gameRoundController.resume(); @@ -190,8 +199,33 @@ public final class MainActivity extends Activity { view.combatController.setCombatSelection(world.model.uiSelections.selectedMonster, world.model.uiSelections.selectedPosition); view.combatController.enterCombat(CombatController.BEGIN_TURN_CONTINUE); } + updateStatus(); } + private void unsubscribeFromModel() { + activeConditions.unsubscribe(); + combatview.unsubscribe(); + mainview.unsubscribe(); + quickitemview.unsubscribe(); + statusview.unsubscribe(); + view.movementController.playerMovementListeners.remove(this); + view.combatController.combatActionListeners.remove(this); + view.combatController.combatTurnListeners.remove(this); + view.controller.worldEventListeners.remove(this); + } + + private void subscribeToModelChanges() { + view.controller.worldEventListeners.add(this); + view.combatController.combatTurnListeners.add(this); + view.combatController.combatActionListeners.add(this); + view.movementController.playerMovementListeners.add(this); + statusview.subscribe(); + quickitemview.subscribe(); + mainview.subscribe(); + combatview.subscribe(); + activeConditions.subscribe(); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { menu.add(R.string.exit_to_menu) @@ -208,7 +242,7 @@ public final class MainActivity extends Activity { .setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem arg0) { - Dialogs.showSave(MainActivity.this, view); + Dialogs.showSave(MainActivity.this, view, world); return true; } }); @@ -266,20 +300,14 @@ public final class MainActivity extends Activity { return true; } - public void updateStatus() { + private void updateStatus() { statusview.updateStatus(); quickitemview.refreshQuickitems(); combatview.updateStatus(); toolboxview.updateIcons(); } - public void redrawAll(int why) { - this.mainview.redrawAll(why); - } - public void redrawTile(final Coord pos, int why) { - this.mainview.redrawTile(pos, why); - } - public void message(String msg) { + private void message(String msg) { StringBuilder sb = new StringBuilder(); for(int i = 0; i < NUM_MESSAGES-1; ++i) { messages[i] = messages[i + 1]; @@ -294,7 +322,7 @@ public final class MainActivity extends Activity { statusText.setVisibility(View.VISIBLE); } - public void clearMessages() { + private void clearMessages() { for(int i = 0; i < NUM_MESSAGES; ++i) { messages[i] = ""; } @@ -313,4 +341,147 @@ public final class MainActivity extends Activity { } t.show(); } + + + @Override + public void onPlayerMoved(Coord newPosition, Coord previousPosition) { } + + @Override + public void onPlayerEnteredNewMap(PredefinedMap map, Coord p) { + clearMessages(); + } + + @Override + public void onCombatStarted() { + clearMessages(); + } + + @Override + public void onCombatEnded() { + clearMessages(); + } + + @Override + public void onPlayerAttackMissed(Monster target, AttackResult attackResult) { + message(getString(R.string.combat_result_heromiss)); + } + + @Override + public void onPlayerAttackSuccess(Monster target, AttackResult attackResult) { + String msg; + final String monsterName = target.getName(); + if (attackResult.isCriticalHit) { + msg = getString(R.string.combat_result_herohitcritical, monsterName, attackResult.damage); + } else { + msg = getString(R.string.combat_result_herohit, monsterName, attackResult.damage); + } + if (attackResult.targetDied) { + msg += " " + getString(R.string.combat_result_herokillsmonster, monsterName, attackResult.damage); + } + message(msg); + } + + @Override + public void onMonsterAttackMissed(Monster attacker, AttackResult attackResult) { + message(getString(R.string.combat_result_monstermiss, attacker.getName())); + } + + @Override + public void onMonsterAttackSuccess(Monster attacker, AttackResult attackResult) { + final String monsterName = attacker.getName(); + if (attackResult.isCriticalHit) { + message(getString(R.string.combat_result_monsterhitcritical, monsterName, attackResult.damage)); + } else { + message(getString(R.string.combat_result_monsterhit, monsterName, attackResult.damage)); + } + } + + @Override + public void onPlayerKilledMonster(Monster target) { } + + @Override + public void onNewPlayerTurn() { } + + @Override + public void onMonsterIsAttacking(Monster m) { } + + @Override + public void onPlayerStartedConversation(Monster m, String phraseID) { + Dialogs.showConversation(this, view, phraseID, m); + } + + @Override + public void onPlayerSteppedOnMonster(Monster m) { + Dialogs.showMonsterEncounter(this, view, m); + } + + @Override + public void onPlayerSteppedOnMapSignArea(MapObject area) { + Dialogs.showMapSign(this, view, area.id); + } + + @Override + public void onPlayerSteppedOnKeyArea(MapObject area) { + Dialogs.showKeyArea(this, view, area.id); + } + + @Override + public void onPlayerSteppedOnRestArea(MapObject area) { + Dialogs.showConfirmRest(this, view, area); + } + + @Override + public void onPlayerSteppedOnGroundLoot(Loot loot) { + final String msg = Dialogs.getGroundLootMessage(this, loot); + Dialogs.showGroundLoot(this, view, world, loot, msg); + } + + @Override + public void onPlayerPickedUpGroundLoot(Loot loot) { + if (view.preferences.displayLoot == AndorsTrailPreferences.DISPLAYLOOT_NONE) return; + + final String msg = Dialogs.getGroundLootMessage(this, loot); + showToast(msg, Toast.LENGTH_LONG); + } + + @Override + public void onPlayerFoundMonsterLoot(Iterable loot, int exp) { + final Loot combinedLoot = Loot.combine(loot); + final String msg = Dialogs.getMonsterLootMessage(this, combinedLoot, exp); + Dialogs.showMonsterLoot(this, view, world, loot, combinedLoot, msg); + } + + @Override + public void onPlayerPickedUpMonsterLoot(Iterable loot, int exp) { + if (view.preferences.displayLoot == AndorsTrailPreferences.DISPLAYLOOT_NONE) return; + + final Loot combinedLoot = Loot.combine(loot); + final String msg = Dialogs.getMonsterLootMessage(this, combinedLoot, exp); + showToast(msg, Toast.LENGTH_LONG); + } + + @Override + public void onPlayerRested() { + Dialogs.showRested(this, view); + } + + @Override + public void onPlayerDied(int lostExp) { + message(getString(R.string.combat_hero_dies, lostExp)); + } + + @Override + public void onPlayerStartedFleeing() { + message(getString(R.string.combat_begin_flee)); + } + + @Override + public void onPlayerFailedFleeing() { + message(getString(R.string.combat_flee_failed)); + } + + @Override + public void onPlayerDoesNotHaveEnoughAP() { + message(getString(R.string.combat_not_enough_ap)); + } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterEncounterActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterEncounterActivity.java index dd8412d9b..9767b3032 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterEncounterActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterEncounterActivity.java @@ -22,7 +22,7 @@ public final class MonsterEncounterActivity extends Activity { super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; + this.world = app.getWorld(); requestWindowFeature(Window.FEATURE_NO_TITLE); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java index 21069760b..48222841e 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java @@ -36,7 +36,7 @@ public final class MonsterInfoActivity extends Activity { super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; + this.world = app.getWorld(); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.monsterinfo); @@ -87,8 +87,8 @@ public final class MonsterInfoActivity extends Activity { monster.getOnHitEffectsAsList(), null, false); - hp.update(monster.health); - monsterinfo_max_ap.setText(Integer.toString(monster.ap.max)); + hp.update(monster.getMaxHP(), monster.getCurrentHP()); + monsterinfo_max_ap.setText(Integer.toString(monster.getMaxAP())); } public static int getMonsterDifficultyResource(WorldContext world, Monster monster) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java index 033dca1a8..cc98a163c 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java @@ -43,10 +43,10 @@ public final class ShopActivity extends TabActivity implements OnContainerItemCl AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; + this.world = app.getWorld(); this.player = world.model.player; - AndorsTrailApplication.setWindowParameters(this, app.preferences); + app.setWindowParameters(this); final Monster npc = Dialogs.getMonsterFromIntent(getIntent(), world); final Player player = world.model.player; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/SkillInfoActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/SkillInfoActivity.java index a4861bbb1..a4af43fc7 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/SkillInfoActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/SkillInfoActivity.java @@ -29,10 +29,10 @@ public final class SkillInfoActivity extends Activity { super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - this.world = app.world; + this.world = app.getWorld(); this.player = world.model.player; - AndorsTrailApplication.setWindowParameters(this, app.preferences); + app.setWindowParameters(this); setContentView(R.layout.skill_info_view); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java index be52021ad..f09ddfc39 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java @@ -8,6 +8,7 @@ import com.gpl.rpg.AndorsTrail.Savegames; import com.gpl.rpg.AndorsTrail.WorldSetup; import com.gpl.rpg.AndorsTrail.Savegames.FileHeader; import com.gpl.rpg.AndorsTrail.controller.Constants; +import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager; import android.app.Activity; import android.app.AlertDialog; @@ -39,9 +40,10 @@ public final class StartScreenActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); - AndorsTrailPreferences.read(this, app.preferences); - AndorsTrailApplication.setWindowParameters(this, app.preferences); + final AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); + final AndorsTrailPreferences preferences = app.getPreferences(); + AndorsTrailPreferences.read(this, preferences); + app.setWindowParameters(this); setContentView(R.layout.startscreen); @@ -103,9 +105,10 @@ public final class StartScreenActivity extends Activity { } final Resources res = getResources(); - app.world.tileManager.setDensity(res); - app.world.tileManager.updatePreferences(app.preferences); - app.setup.startResourceLoader(res, app.preferences); + TileManager tileManager = app.getWorld().tileManager; + tileManager.setDensity(res); + tileManager.updatePreferences(preferences); + app.getWorldSetup().startResourceLoader(res, preferences); if (AndorsTrailApplication.DEVELOPMENT_FORCE_STARTNEWGAME) { if (AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES) { @@ -187,7 +190,7 @@ public final class StartScreenActivity extends Activity { } private void continueGame(boolean createNewCharacter, int loadFromSlot, String name) { - final WorldSetup setup = AndorsTrailApplication.getApplicationFromActivity(this).setup; + final WorldSetup setup = AndorsTrailApplication.getApplicationFromActivity(this).getWorldSetup(); setup.createNewCharacter = createNewCharacter; setup.loadFromSlot = loadFromSlot; setup.newHeroName = name; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/context/ViewContext.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/context/ViewContext.java index 7e1759b0a..42e5fa078 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/context/ViewContext.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/context/ViewContext.java @@ -1,49 +1,59 @@ package com.gpl.rpg.AndorsTrail.context; +import android.content.res.Resources; + import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences; -import com.gpl.rpg.AndorsTrail.activity.MainActivity; import com.gpl.rpg.AndorsTrail.controller.ActorStatsController; import com.gpl.rpg.AndorsTrail.controller.CombatController; import com.gpl.rpg.AndorsTrail.controller.Controller; +import com.gpl.rpg.AndorsTrail.controller.ConversationController; import com.gpl.rpg.AndorsTrail.controller.GameRoundController; +import com.gpl.rpg.AndorsTrail.controller.MonsterSpawningController; +import com.gpl.rpg.AndorsTrail.controller.SkillController; import com.gpl.rpg.AndorsTrail.controller.VisualEffectController; import com.gpl.rpg.AndorsTrail.controller.ItemController; import com.gpl.rpg.AndorsTrail.controller.MonsterMovementController; import com.gpl.rpg.AndorsTrail.controller.MovementController; import com.gpl.rpg.AndorsTrail.controller.InputController; -public class ViewContext extends WorldContext { - //Views - public final MainActivity mainActivity; - +public class ViewContext { //Controllers public final Controller controller; public final GameRoundController gameRoundController; public final CombatController combatController; + public final ConversationController conversationController; public final VisualEffectController effectController; public final ItemController itemController; public final MonsterMovementController monsterMovementController; + public final MonsterSpawningController monsterSpawnController; public final MovementController movementController; public final ActorStatsController actorStatsController; public final InputController inputController; + public final SkillController skillController; public final AndorsTrailPreferences preferences; - + public final AndorsTrailApplication app; - public ViewContext(AndorsTrailApplication application, MainActivity mainActivity) { - super(application.world); - this.mainActivity = mainActivity; - this.preferences = application.preferences; + public ViewContext(AndorsTrailApplication app, WorldContext world) { + this.app = app; + this.preferences = app.getPreferences(); - this.controller = new Controller(this); - this.gameRoundController = new GameRoundController(this); - this.combatController = new CombatController(this); - this.effectController = new VisualEffectController(this); - this.itemController = new ItemController(this); - this.monsterMovementController = new MonsterMovementController(this); - this.movementController = new MovementController(this); - this.actorStatsController = new ActorStatsController(this); - this.inputController = new InputController(this); + this.controller = new Controller(this, world); + this.gameRoundController = new GameRoundController(this, world); + this.combatController = new CombatController(this, world); + this.conversationController = new ConversationController(this, world); + this.effectController = new VisualEffectController(this, world); + this.itemController = new ItemController(this, world); + this.monsterMovementController = new MonsterMovementController(this, world); + this.monsterSpawnController = new MonsterSpawningController(this, world); + this.movementController = new MovementController(this, world); + this.actorStatsController = new ActorStatsController(this, world); + this.inputController = new InputController(this, world); + this.skillController = new SkillController(this, world); + } + + public Resources getResources() { + return app.getResources(); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java index 007b5c5b3..2fdc4dc40 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java @@ -4,6 +4,8 @@ import java.util.ArrayList; import com.gpl.rpg.AndorsTrail.VisualEffectCollection; import com.gpl.rpg.AndorsTrail.context.ViewContext; +import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.controller.listeners.PlayerStatsListeners; import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionType; @@ -17,19 +19,24 @@ import com.gpl.rpg.AndorsTrail.model.item.Inventory; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnEquip; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; import com.gpl.rpg.AndorsTrail.model.item.ItemType; +import com.gpl.rpg.AndorsTrail.model.listeners.ActorConditionListeners; +import com.gpl.rpg.AndorsTrail.model.listeners.ActorStatsListeners; import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap; import com.gpl.rpg.AndorsTrail.model.map.MonsterSpawnArea; public class ActorStatsController { private final ViewContext view; - //private final WorldContext world; + private final WorldContext world; + public final ActorConditionListeners actorConditionListeners = new ActorConditionListeners(); + public final ActorStatsListeners actorStatsListeners = new ActorStatsListeners(); + public final PlayerStatsListeners playerStatsListeners = new PlayerStatsListeners(); - public ActorStatsController(ViewContext context) { + public ActorStatsController(ViewContext context, WorldContext world) { this.view = context; - //this.world = context; + this.world = world; } - public static void addConditionsFromEquippedItem(Player player, ItemType itemType) { + public void addConditionsFromEquippedItem(Player player, ItemType itemType) { ItemTraits_OnEquip equipEffects = itemType.effects_equip; if (equipEffects == null) return; if (equipEffects.addedConditions == null) return; @@ -37,7 +44,7 @@ public class ActorStatsController { applyActorCondition(player, e, ActorCondition.DURATION_FOREVER); } } - public static void removeConditionsFromUnequippedItem(Player player, ItemType itemType) { + public void removeConditionsFromUnequippedItem(Player player, ItemType itemType) { ItemTraits_OnEquip equipEffects = itemType.effects_equip; if (equipEffects == null) return; if (equipEffects.addedConditions == null) return; @@ -52,7 +59,7 @@ public class ActorStatsController { } } - private static void removeStackableActorCondition(Actor actor, ActorConditionType type, int magnitude, int duration) { + private void removeStackableActorCondition(Actor actor, ActorConditionType type, int magnitude, int duration) { for(int i = actor.conditions.size() - 1; i >= 0; --i) { ActorCondition c = actor.conditions.get(i); if (!type.conditionTypeID.equals(c.conditionType.conditionTypeID)) continue; @@ -60,16 +67,16 @@ public class ActorStatsController { if (c.magnitude > magnitude) { c.magnitude -= magnitude; - actor.conditionListener.onActorConditionMagnitudeChanged(actor, c); + actorConditionListeners.onActorConditionMagnitudeChanged(actor, c); } else { actor.conditions.remove(i); - actor.conditionListener.onActorConditionRemoved(actor, c); + actorConditionListeners.onActorConditionRemoved(actor, c); } break; } } - private static void removeNonStackableActorCondition(Player player, ActorConditionType type, int magnitude, int duration) { + private void removeNonStackableActorCondition(Player player, ActorConditionType type, int magnitude, int duration) { for (int i = 0; i < Inventory.NUM_WORN_SLOTS; ++i) { ItemType t = player.inventory.wear[i]; if (t == null) continue; @@ -87,8 +94,8 @@ public class ActorStatsController { removeStackableActorCondition(player, type, magnitude, duration); } - public static void applyActorCondition(Actor actor, ActorConditionEffect e) { applyActorCondition(actor, e, e.duration); } - private static void applyActorCondition(Actor actor, ActorConditionEffect e, int duration) { + public void applyActorCondition(Actor actor, ActorConditionEffect e) { applyActorCondition(actor, e, e.duration); } + private void applyActorCondition(Actor actor, ActorConditionEffect e, int duration) { if (e.isRemovalEffect()) { removeAllConditionsOfType(actor, e.conditionType.conditionTypeID); } else if (e.magnitude > 0) { @@ -101,7 +108,7 @@ public class ActorStatsController { recalculateActorCombatTraits(actor); } - private static void addStackableActorCondition(Actor actor, ActorConditionEffect e, int duration) { + private void addStackableActorCondition(Actor actor, ActorConditionEffect e, int duration) { final ActorConditionType type = e.conditionType; int magnitude = e.magnitude; @@ -111,15 +118,15 @@ public class ActorStatsController { if (c.duration == duration) { // If the actor already has a condition of this type and the same duration, just increase the magnitude instead. c.magnitude += magnitude; - actor.conditionListener.onActorConditionMagnitudeChanged(actor, c); + actorConditionListeners.onActorConditionMagnitudeChanged(actor, c); return; } } ActorCondition c = new ActorCondition(type, magnitude, duration); actor.conditions.add(c); - actor.conditionListener.onActorConditionAdded(actor, c); + actorConditionListeners.onActorConditionAdded(actor, c); } - private static void addNonStackableActorCondition(Actor actor, ActorConditionEffect e, int duration) { + private void addNonStackableActorCondition(Actor actor, ActorConditionEffect e, int duration) { final ActorConditionType type = e.conditionType; for(int i = actor.conditions.size() - 1; i >= 0; --i) { @@ -131,46 +138,46 @@ public class ActorStatsController { } // If the actor already has this condition, but of a lower magnitude, we remove the old one and add this higher magnitude. actor.conditions.remove(i); - actor.conditionListener.onActorConditionRemoved(actor, c); + actorConditionListeners.onActorConditionRemoved(actor, c); } ActorCondition c = e.createCondition(duration); actor.conditions.add(c); - actor.conditionListener.onActorConditionAdded(actor, c); + actorConditionListeners.onActorConditionAdded(actor, c); } - public static void removeAllTemporaryConditions(final Actor actor) { + public void removeAllTemporaryConditions(final Actor actor) { for(int i = actor.conditions.size() - 1; i >= 0; --i) { ActorCondition c = actor.conditions.get(i); if (!c.isTemporaryEffect()) continue; actor.conditions.remove(i); - actor.conditionListener.onActorConditionRemoved(actor, c); + actorConditionListeners.onActorConditionRemoved(actor, c); } } - private static void removeAllConditionsOfType(final Actor actor, final String conditionTypeID) { + private void removeAllConditionsOfType(final Actor actor, final String conditionTypeID) { for(int i = actor.conditions.size() - 1; i >= 0; --i) { ActorCondition c = actor.conditions.get(i); if (!c.conditionType.conditionTypeID.equals(conditionTypeID)) continue; actor.conditions.remove(i); - actor.conditionListener.onActorConditionRemoved(actor, c); + actorConditionListeners.onActorConditionRemoved(actor, c); } } - private static void applyEffectsFromCurrentConditions(Actor actor) { + private void applyEffectsFromCurrentConditions(Actor actor) { for (ActorCondition c : actor.conditions) { applyAbilityEffects(actor, c.conditionType.abilityEffect, c.magnitude); } } - public static void applyAbilityEffects(Actor actor, AbilityModifierTraits effects, int multiplier) { + public void applyAbilityEffects(Actor actor, AbilityModifierTraits effects, int multiplier) { if (effects == null) return; - actor.health.addToMax(effects.increaseMaxHP * multiplier); - actor.ap.addToMax(effects.increaseMaxAP * multiplier); - actor.moveCost += effects.increaseMoveCost * multiplier; + addActorMaxHealth(actor, effects.increaseMaxHP * multiplier, false); + addActorMaxAP(actor, effects.increaseMaxAP * multiplier, false); - actor.attackCost += effects.increaseAttackCost * multiplier; + addActorMoveCost(actor, effects.increaseMoveCost * multiplier); + addActorAttackCost(actor, effects.increaseAttackCost * multiplier); //criticalMultiplier should not be increased. It is always defined by the weapon in use. actor.attackChance += effects.increaseAttackChance * multiplier; actor.criticalSkill += effects.increaseCriticalSkill * multiplier; @@ -179,29 +186,27 @@ public class ActorStatsController { actor.blockChance += effects.increaseBlockChance * multiplier; actor.damageResistance += effects.increaseDamageResistance * multiplier; - if (actor.attackCost <= 0) actor.attackCost = 1; if (actor.attackChance < 0) actor.attackChance = 0; - if (actor.moveCost <= 0) actor.moveCost = 1; if (actor.damagePotential.max < 0) actor.damagePotential.set(0, 0); } - public static void recalculatePlayerStats(Player player) { + public void recalculatePlayerStats(Player player) { player.resetStatsToBaseTraits(); player.recalculateLevelExperience(); - ItemController.applyInventoryEffects(player); - SkillController.applySkillEffects(player); + view.itemController.applyInventoryEffects(player); + view.skillController.applySkillEffects(player); applyEffectsFromCurrentConditions(player); ItemController.recalculateHitEffectsFromWornItems(player); - player.health.capAtMax(); - player.ap.capAtMax(); + capActorHealthAtMax(player); + capActorAPAtMax(player); } - public static void recalculateMonsterCombatTraits(Monster monster) { + public void recalculateMonsterCombatTraits(Monster monster) { monster.resetStatsToBaseTraits(); applyEffectsFromCurrentConditions(monster); - monster.health.capAtMax(); - monster.ap.capAtMax(); + capActorHealthAtMax(monster); + capActorAPAtMax(monster); } - private static void recalculateActorCombatTraits(Actor actor) { + private void recalculateActorCombatTraits(Actor actor) { if (actor.isPlayer) recalculatePlayerStats((Player) actor); else recalculateMonsterCombatTraits((Monster) actor); } @@ -217,21 +222,19 @@ public class ActorStatsController { } if (!isFullRound) decreaseDurationAndRemoveConditions(player); - - view.mainActivity.updateStatus(); } - private static void removeConditionsFromSkillEffects(Player player) { + private void removeConditionsFromSkillEffects(Player player) { if (SkillController.rollForSkillChance(player, SkillCollection.SKILL_REJUVENATION, SkillCollection.PER_SKILLPOINT_INCREASE_REJUVENATION_CHANCE)) { int i = getRandomConditionForRejuvenate(player); if (i >= 0) { ActorCondition c = player.conditions.get(i); if (c.magnitude > 1) { c.magnitude -= 1; - player.conditionListener.onActorConditionMagnitudeChanged(player, c); + actorConditionListeners.onActorConditionMagnitudeChanged(player, c); } else { player.conditions.remove(i); - player.conditionListener.onActorConditionRemoved(player, c); + actorConditionListeners.onActorConditionRemoved(player, c); } recalculatePlayerStats(player); } @@ -278,23 +281,23 @@ public class ActorStatsController { for (ActorCondition c : actor.conditions) { StatsModifierTraits effect = isFullRound ? c.conditionType.statsEffect_everyFullRound : c.conditionType.statsEffect_everyRound; effectToStart = applyStatsModifierEffect(actor, effect, c.magnitude, effectToStart); - if (effect != null) actor.conditionListener.onActorConditionRoundEffectApplied(actor, c); + if (effect != null) actorConditionListeners.onActorConditionRoundEffectApplied(actor, c); } startVisualEffect(actor, effectToStart); } - private static void decreaseDurationAndRemoveConditions(Actor actor) { + private void decreaseDurationAndRemoveConditions(Actor actor) { boolean removedAnyConditions = false; for(int i = actor.conditions.size() - 1; i >= 0; --i) { ActorCondition c = actor.conditions.get(i); if (!c.isTemporaryEffect()) continue; if (c.duration <= 1) { actor.conditions.remove(i); - actor.conditionListener.onActorConditionRemoved(actor, c); + actorConditionListeners.onActorConditionRemoved(actor, c); removedAnyConditions = true; } else { c.duration -= 1; - actor.conditionListener.onActorConditionDurationChanged(actor, c); + actorConditionListeners.onActorConditionDurationChanged(actor, c); } } if (removedAnyConditions) { @@ -323,7 +326,7 @@ public class ActorStatsController { } } - private static void rollForConditionEffect(Actor actor, ActorConditionEffect conditionEffect) { + private void rollForConditionEffect(Actor actor, ActorConditionEffect conditionEffect) { int chanceRollBias = 0; if (actor.isPlayer) chanceRollBias = SkillController.getActorConditionEffectChanceRollBias(conditionEffect, (Player) actor); @@ -342,15 +345,14 @@ public class ActorStatsController { private void startVisualEffect(Actor actor, VisualEffect effectToStart) { if (effectToStart == null) return; view.effectController.startEffect( - view.mainActivity.mainview - , actor.position + actor.position , effectToStart.visualEffectID , effectToStart.effectValue , null , 0); } - private static VisualEffect applyStatsModifierEffect(Actor actor, StatsModifierTraits effect, int magnitude, VisualEffect existingVisualEffect) { + private VisualEffect applyStatsModifierEffect(Actor actor, StatsModifierTraits effect, int magnitude, VisualEffect existingVisualEffect) { if (effect == null) return existingVisualEffect; int effectValue = 0; @@ -358,7 +360,7 @@ public class ActorStatsController { if (effect.currentAPBoost != null) { effectValue = Constants.rollValue(effect.currentAPBoost); effectValue *= magnitude; - boolean changed = actor.ap.change(effectValue, false, false); + boolean changed = changeActorAP(actor, effectValue, false, false); if (!changed) effectValue = 0; // So that the visualeffect doesn't start. if (effectValue != 0) { if (!effect.hasVisualEffect()) { @@ -369,7 +371,7 @@ public class ActorStatsController { if (effect.currentHPBoost != null) { effectValue = Constants.rollValue(effect.currentHPBoost); effectValue *= magnitude; - boolean changed = actor.health.change(effectValue, false, false); + boolean changed = changeActorHealth(actor, effectValue, false, false); if (!changed) effectValue = 0; // So that the visualeffect doesn't start. if (effectValue != 0) { if (!effect.hasVisualEffect()) { @@ -406,9 +408,123 @@ public class ActorStatsController { if (level > 0) { boolean hasAdjacentMonster = MovementController.hasAdjacentAggressiveMonster(currentMap, player); if (!hasAdjacentMonster) { - boolean changed = player.health.add(level * SkillCollection.PER_SKILLPOINT_INCREASE_REGENERATION, false); - if (changed) view.mainActivity.updateStatus(); + addActorHealth(player, level * SkillCollection.PER_SKILLPOINT_INCREASE_REGENERATION); } } } + + public static final int LEVELUP_HEALTH = 0; + public static final int LEVELUP_ATTACK_CHANCE = 1; + public static final int LEVELUP_ATTACK_DAMAGE = 2; + public static final int LEVELUP_BLOCK_CHANCE = 3; + + public void addLevelupEffect(Player player, int selectionID) { + int hpIncrease = 0; + switch (selectionID) { + case LEVELUP_HEALTH: + hpIncrease = Constants.LEVELUP_EFFECT_HEALTH; + break; + case LEVELUP_ATTACK_CHANCE: + player.baseTraits.attackChance += Constants.LEVELUP_EFFECT_ATK_CH; + break; + case LEVELUP_ATTACK_DAMAGE: + player.baseTraits.damagePotential.max += Constants.LEVELUP_EFFECT_ATK_DMG; + player.baseTraits.damagePotential.current += Constants.LEVELUP_EFFECT_ATK_DMG; + break; + case LEVELUP_BLOCK_CHANCE: + player.baseTraits.blockChance += Constants.LEVELUP_EFFECT_DEF_CH; + break; + } + if (player.nextLevelAddsNewSkillpoint()) { + player.availableSkillIncreases++; + } + player.level++; + + hpIncrease += player.getSkillLevel(SkillCollection.SKILL_FORTITUDE) * SkillCollection.PER_SKILLPOINT_INCREASE_FORTITUDE_HEALTH; + addActorMaxHealth(player, hpIncrease, true); + player.baseTraits.maxHP += hpIncrease; + + recalculatePlayerStats(player); + } + + public void healAllMonsters(MonsterSpawnArea area) { + for (Monster m : area.monsters) { + removeAllTemporaryConditions(m); + setActorMaxHealth(m); + } + } + + public void addExperience(int exp) { + if (exp == 0) return; + Player p = world.model.player; + p.totalExperience += exp; + p.levelExperience.add(exp, true); + playerStatsListeners.onPlayerExperienceChanged(p); + } + public void addActorMoveCost(Actor actor, int amount) { + if (amount == 0) return; + actor.moveCost += amount; + if (actor.moveCost <= 0) actor.moveCost = 1; + actorStatsListeners.onActorMoveCostChanged(actor, actor.moveCost); + } + public void addActorAttackCost(Actor actor, int amount) { + if (amount == 0) return; + actor.attackCost += amount; + if (actor.attackCost <= 0) actor.attackCost = 1; + actorStatsListeners.onActorAttackCostChanged(actor, actor.attackCost); + } + + public void setActorMaxHealth(Actor actor) { + if (actor.health.isMax()) return; + actor.health.setMax(); + actorStatsListeners.onActorHealthChanged(actor); + } + public void capActorHealthAtMax(Actor actor) { + if (actor.health.capAtMax()) actorStatsListeners.onActorHealthChanged(actor); + } + public boolean addActorHealth(Actor actor, int amount) { return changeActorHealth(actor, amount, false, false); } + public boolean removeActorHealth(Actor actor, int amount) { return changeActorHealth(actor, -amount, false, false); } + public boolean changeActorHealth(Actor actor, int deltaAmount, boolean mayUnderflow, boolean mayOverflow) { + final boolean changed = actor.health.change(deltaAmount, mayUnderflow, mayOverflow); + if(changed) actorStatsListeners.onActorHealthChanged(actor); + return changed; + } + public void addActorMaxHealth(Actor actor, int amount, boolean affectCurrentHealth) { + if (amount == 0) return; + actor.health.addToMax(amount); + if (affectCurrentHealth) actor.health.add(amount, false); + actorStatsListeners.onActorHealthChanged(actor); + } + + public void setActorMaxAP(Actor actor) { + if (actor.ap.isMax()) return; + actor.ap.setMax(); + actorStatsListeners.onActorAPChanged(actor); + } + public void capActorAPAtMax(Actor actor) { + if (actor.ap.capAtMax()) actorStatsListeners.onActorAPChanged(actor); + } + public boolean addActorAP(Actor actor, int amount) { return changeActorAP(actor, amount, false, false); } + public boolean changeActorAP(Actor actor, int deltaAmount, boolean mayUnderflow, boolean mayOverflow) { + final boolean changed = actor.ap.change(deltaAmount, mayUnderflow, mayOverflow); + if(changed) actorStatsListeners.onActorAPChanged(actor); + return changed; + } + public boolean useAPs(Actor actor, int cost) { + if (actor.ap.current < cost) return false; + actor.ap.subtract(cost, false); + actorStatsListeners.onActorAPChanged(actor); + return true; + } + public void addActorMaxAP(Actor actor, int amount, boolean affectCurrentAP) { + if (amount == 0) return; + actor.ap.addToMax(amount); + if (affectCurrentAP) actor.ap.add(amount, false); + actorStatsListeners.onActorAPChanged(actor); + } + public void setActorMinAP(Actor actor) { + if (actor.ap.current == 0) return; + actor.ap.current = 0; + actorStatsListeners.onActorAPChanged(actor); + } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java index 163b3ae60..826732890 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java @@ -2,18 +2,18 @@ package com.gpl.rpg.AndorsTrail.controller; import java.util.HashSet; -import android.content.res.Resources; import android.os.Handler; import android.os.Message; import android.util.FloatMath; import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences; -import com.gpl.rpg.AndorsTrail.Dialogs; import com.gpl.rpg.AndorsTrail.VisualEffectCollection; -import com.gpl.rpg.AndorsTrail.R; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectCompletedCallback; +import com.gpl.rpg.AndorsTrail.controller.listeners.CombatActionListeners; +import com.gpl.rpg.AndorsTrail.controller.listeners.CombatSelectionListeners; +import com.gpl.rpg.AndorsTrail.controller.listeners.CombatTurnListeners; import com.gpl.rpg.AndorsTrail.model.AttackResult; import com.gpl.rpg.AndorsTrail.model.ModelContainer; import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection; @@ -25,21 +25,21 @@ import com.gpl.rpg.AndorsTrail.model.item.Loot; import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap; import com.gpl.rpg.AndorsTrail.model.map.MonsterSpawnArea; import com.gpl.rpg.AndorsTrail.util.Coord; -import com.gpl.rpg.AndorsTrail.view.MainView; public final class CombatController implements VisualEffectCompletedCallback { - private final ViewContext context; + private final ViewContext view; private final WorldContext world; - private final ModelContainer model; + public final CombatSelectionListeners combatSelectionListeners = new CombatSelectionListeners(); + public final CombatActionListeners combatActionListeners = new CombatActionListeners(); + public final CombatTurnListeners combatTurnListeners = new CombatTurnListeners(); private Monster currentActiveMonster = null; private final HashSet killedMonsterBags = new HashSet(); private int totalExpThisFight = 0; - public CombatController(ViewContext context) { - this.context = context; - this.world = context; - this.model = world.model; + public CombatController(ViewContext view, WorldContext world) { + this.view = view; + this.world = world; } public static final int BEGIN_TURN_PLAYER = 0; @@ -47,70 +47,66 @@ public final class CombatController implements VisualEffectCompletedCallback { public static final int BEGIN_TURN_CONTINUE = 2; public void enterCombat(int beginTurnAs) { - context.mainActivity.combatview.show(); - model.uiSelections.isInCombat = true; + world.model.uiSelections.isInCombat = true; killedMonsterBags.clear(); - context.mainActivity.clearMessages(); + combatTurnListeners.onCombatStarted(); if (beginTurnAs == BEGIN_TURN_PLAYER) newPlayerTurn(true); else if (beginTurnAs == BEGIN_TURN_MONSTERS) beginMonsterTurn(true); else continueTurn(); - updateTurnInfo(); } public void exitCombat(boolean pickupLootBags) { setCombatSelection(null, null); - context.mainActivity.combatview.hide(); - model.uiSelections.isInCombat = false; - context.mainActivity.clearMessages(); + world.model.uiSelections.isInCombat = false; + combatTurnListeners.onCombatEnded(); currentActiveMonster = null; - model.uiSelections.selectedPosition = null; - model.uiSelections.selectedMonster = null; + world.model.uiSelections.selectedPosition = null; + world.model.uiSelections.selectedMonster = null; if (!killedMonsterBags.isEmpty()) { if (pickupLootBags) { - lootCurrentMonsterBags(); + view.itemController.lootMonsterBags(killedMonsterBags, totalExpThisFight); } killedMonsterBags.clear(); } else { - context.gameRoundController.resume(); + view.gameRoundController.resume(); } totalExpThisFight = 0; } - private void lootCurrentMonsterBags() { - Dialogs.showMonsterLoot(context.mainActivity, context, killedMonsterBags, totalExpThisFight); - ItemController.consumeNonItemLoot(killedMonsterBags, model); - } - public boolean isMonsterTurn() { return currentActiveMonster != null; } public void setCombatSelection(Monster selectedMonster) { - Coord p = selectedMonster.rectPosition.findPositionAdjacentTo(model.player.position); + Coord p = selectedMonster.rectPosition.findPositionAdjacentTo(world.model.player.position); setCombatSelection(selectedMonster, p); } public void setCombatSelection(Monster selectedMonster, Coord selectedPosition) { if (selectedMonster != null) { if (!selectedMonster.isAgressive()) return; } - Coord previousSelection = model.uiSelections.selectedPosition; - if (model.uiSelections.selectedPosition != null) { - model.uiSelections.selectedPosition = null; + Coord previousSelection = world.model.uiSelections.selectedPosition; + if (previousSelection != null) { + world.model.uiSelections.selectedPosition = null; if (selectedPosition == null || !selectedPosition.equals(previousSelection)) { - context.mainActivity.redrawTile(previousSelection, MainView.REDRAW_TILE_SELECTION_REMOVED); + } else { + previousSelection = null; } } - context.mainActivity.combatview.updateCombatSelection(selectedMonster, selectedPosition); - model.uiSelections.selectedMonster = selectedMonster; + world.model.uiSelections.selectedMonster = selectedMonster; if (selectedPosition != null) { - model.uiSelections.selectedPosition = new Coord(selectedPosition); - model.uiSelections.isInCombat = true; - context.mainActivity.redrawTile(selectedPosition, MainView.REDRAW_TILE_SELECTION_ADDED); + world.model.uiSelections.selectedPosition = new Coord(selectedPosition); + world.model.uiSelections.isInCombat = true; } else { - model.uiSelections.selectedPosition = null; + world.model.uiSelections.selectedPosition = null; } + + if (selectedMonster != null) combatSelectionListeners.onMonsterSelected(selectedMonster, selectedPosition, previousSelection); + else if (selectedPosition != null) combatSelectionListeners.onMovementDestinationSelected(selectedPosition, previousSelection); + else if (previousSelection != null) combatSelectionListeners.onCombatSelectionCleared(previousSelection); } + public void setCombatSelection(Coord p) { - PredefinedMap map = model.currentMap; + PredefinedMap map = world.model.currentMap; Monster m = map.getMonsterAt(p); if (m != null) { setCombatSelection(m, p); @@ -119,21 +115,18 @@ public final class CombatController implements VisualEffectCompletedCallback { } } - private void message(String s) { - context.mainActivity.message(s); - } private boolean useAPs(int cost) { - if (model.player.useAPs(cost)) { + if (view.actorStatsController.useAPs(world.model.player, cost)) { return true; } else { - message(context.mainActivity.getResources().getString(R.string.combat_not_enough_ap)); + combatActionListeners.onPlayerDoesNotHaveEnoughAP(); return false; } } public boolean canExitCombat() { return getAdjacentMonster() == null; } private Monster getAdjacentMonster() { - return MovementController.getAdjacentAggressiveMonster(model.currentMap, model.player); + return MovementController.getAdjacentAggressiveMonster(world.model.currentMap, world.model.player); } public void executeMoveAttack(int dx, int dy) { @@ -157,8 +150,8 @@ public final class CombatController implements VisualEffectCompletedCallback { private void executeFlee(int dx, int dy) { // avoid monster fields when fleeing - if (!context.movementController.findWalkablePosition(dx, dy, AndorsTrailPreferences.MOVEMENTAGGRESSIVENESS_DEFENSIVE)) return; - Monster m = model.currentMap.getMonsterAt(model.player.nextPosition); + if (!view.movementController.findWalkablePosition(dx, dy, AndorsTrailPreferences.MOVEMENTAGGRESSIVENESS_DEFENSIVE)) return; + Monster m = world.model.currentMap.getMonsterAt(world.model.player.nextPosition); if (m != null) return; executeCombatMove(world.model.player.nextPosition); } @@ -166,37 +159,24 @@ public final class CombatController implements VisualEffectCompletedCallback { private Monster currentlyAttackedMonster; private AttackResult lastAttackResult; private void executePlayerAttack() { - if (context.effectController.isRunningVisualEffect()) return; - if (!useAPs(model.player.getAttackCost())) return; - final Monster target = model.uiSelections.selectedMonster; + if (view.effectController.isRunningVisualEffect()) return; + if (!useAPs(world.model.player.getAttackCost())) return; + final Monster target = world.model.uiSelections.selectedMonster; this.currentlyAttackedMonster = target; final AttackResult attack = playerAttacks(world, target); this.lastAttackResult = attack; - Resources r = context.mainActivity.getResources(); if (attack.isHit) { - String msg; + combatActionListeners.onPlayerAttackSuccess(target, attack); - final String monsterName = target.getName(); - if (attack.isCriticalHit) { - msg = r.getString(R.string.combat_result_herohitcritical, monsterName, attack.damage); - } else { - msg = r.getString(R.string.combat_result_herohit, monsterName, attack.damage); - } - if (attack.targetDied) { - msg += " " + r.getString(R.string.combat_result_herokillsmonster, monsterName, attack.damage); - } - message(msg); - - context.mainActivity.updateStatus(); if (lastAttackResult.targetDied) { playerKilledMonster(currentlyAttackedMonster); } - startAttackEffect(attack, model.uiSelections.selectedPosition, this, CALLBACK_PLAYERATTACK); + startAttackEffect(attack, world.model.uiSelections.selectedPosition, this, CALLBACK_PLAYERATTACK); } else { - message(r.getString(R.string.combat_result_heromiss)); + combatActionListeners.onPlayerAttackMissed(target, attack); playerAttackCompleted(); } } @@ -216,65 +196,62 @@ public final class CombatController implements VisualEffectCompletedCallback { } public void playerKilledMonster(Monster killedMonster) { - final Player player = model.player; + final Player player = world.model.player; - Loot loot = model.currentMap.getBagOrCreateAt(killedMonster.position); + Loot loot = world.model.currentMap.getBagOrCreateAt(killedMonster.position); killedMonster.createLoot(loot, player); - model.currentMap.remove(killedMonster); - VisualEffectController.addSplatter(model.currentMap, killedMonster); + view.monsterSpawnController.remove(world.model.currentMap, killedMonster); + view.effectController.addSplatter(world.model.currentMap, killedMonster); - player.ap.add(player.getSkillLevel(SkillCollection.SKILL_CLEAVE) * SkillCollection.PER_SKILLPOINT_INCREASE_CLEAVE_AP, false); - player.health.add(player.getSkillLevel(SkillCollection.SKILL_EATER) * SkillCollection.PER_SKILLPOINT_INCREASE_EATER_HEALTH, false); + view.actorStatsController.addActorAP(player, player.getSkillLevel(SkillCollection.SKILL_CLEAVE) * SkillCollection.PER_SKILLPOINT_INCREASE_CLEAVE_AP); + view.actorStatsController.addActorHealth(player, player.getSkillLevel(SkillCollection.SKILL_EATER) * SkillCollection.PER_SKILLPOINT_INCREASE_EATER_HEALTH); + + world.model.statistics.addMonsterKill(killedMonster.getMonsterTypeID()); + view.actorStatsController.addExperience(loot.exp); - model.statistics.addMonsterKill(killedMonster.getMonsterTypeID()); - model.player.addExperience(loot.exp); totalExpThisFight += loot.exp; loot.exp = 0; - context.actorStatsController.applyKillEffectsToPlayer(player); + view.actorStatsController.applyKillEffectsToPlayer(player); - context.mainActivity.updateStatus(); - if (!loot.hasItems()) { - model.currentMap.removeGroundLoot(loot); - } else { - ItemController.updateLootVisibility(context, loot); - if (model.uiSelections.isInCombat) killedMonsterBags.add(loot); + world.model.currentMap.removeGroundLoot(loot); + } else if (world.model.uiSelections.isInCombat) { + killedMonsterBags.add(loot); } - context.mainActivity.redrawAll(MainView.REDRAW_ALL_MONSTER_KILLED); + combatActionListeners.onPlayerKilledMonster(killedMonster); } private boolean playerHasApLeft() { - final Player player = model.player; + final Player player = world.model.player; if (player.hasAPs(player.getUseItemCost())) return true; if (player.hasAPs(player.getAttackCost())) return true; if (player.hasAPs(player.getMoveCost())) return true; return false; } private void playerActionCompleted() { - context.mainActivity.updateStatus(); if (!playerHasApLeft()) beginMonsterTurn(false); } private void continueTurn() { - if (model.uiSelections.isPlayersCombatTurn) return; + if (world.model.uiSelections.isPlayersCombatTurn) return; if (playerHasApLeft()) return; handleNextMonsterAction(); } private void executeCombatMove(final Coord dest) { - if (model.uiSelections.selectedMonster != null) return; + if (world.model.uiSelections.selectedMonster != null) return; if (dest == null) return; - if (!useAPs(model.player.getMoveCost())) return; + if (!useAPs(world.model.player.getMoveCost())) return; - int fleeChanceBias = model.player.getSkillLevel(SkillCollection.SKILL_EVASION) * SkillCollection.PER_SKILLPOINT_INCREASE_EVASION_FLEE_CHANCE_PERCENTAGE; + int fleeChanceBias = world.model.player.getSkillLevel(SkillCollection.SKILL_EVASION) * SkillCollection.PER_SKILLPOINT_INCREASE_EVASION_FLEE_CHANCE_PERCENTAGE; if (Constants.roll100(Constants.FLEE_FAIL_CHANCE_PERCENT - fleeChanceBias)) { fleeingFailed(); return; } - model.player.nextPosition.set(dest); - context.movementController.moveToNextIfPossible(false); + world.model.player.nextPosition.set(dest); + view.movementController.moveToNextIfPossible(false); if (canExitCombat()) exitCombat(true); @@ -282,8 +259,7 @@ public final class CombatController implements VisualEffectCompletedCallback { } private void fleeingFailed() { - Resources r = context.mainActivity.getResources(); - message(r.getString(R.string.combat_flee_failed)); + combatActionListeners.onPlayerFailedFleeing(); beginMonsterTurn(false); } @@ -295,14 +271,14 @@ public final class CombatController implements VisualEffectCompletedCallback { }; public void beginMonsterTurn(boolean isFirstRound) { - model.player.ap.current = 0; - model.uiSelections.isPlayersCombatTurn = false; - for (MonsterSpawnArea a : model.currentMap.spawnAreas) { + view.actorStatsController.setActorMinAP(world.model.player); + world.model.uiSelections.isPlayersCombatTurn = false; + for (MonsterSpawnArea a : world.model.currentMap.spawnAreas) { for (Monster m : a.monsters) { - m.setMaxAP(); + view.actorStatsController.setActorMaxAP(m); } } - if (!isFirstRound) context.gameRoundController.onNewMonsterRound(); + if (!isFirstRound) view.gameRoundController.onNewMonsterRound(); handleNextMonsterAction(); } @@ -311,11 +287,11 @@ public final class CombatController implements VisualEffectCompletedCallback { if (previousMonster.hasAPs(previousMonster.getAttackCost())) return previousMonster; } - for (MonsterSpawnArea a : model.currentMap.spawnAreas) { + for (MonsterSpawnArea a : world.model.currentMap.spawnAreas) { for (Monster m : a.monsters) { if (!m.isAgressive()) continue; - if (m.isAdjacentTo(model.player)) { + if (m.isAdjacentTo(world.model.player)) { if (m.hasAPs(m.getAttackCost())) return m; } } @@ -324,35 +300,27 @@ public final class CombatController implements VisualEffectCompletedCallback { } private void handleNextMonsterAction() { - if (!context.model.uiSelections.isMainActivityVisible) return; + if (!world.model.uiSelections.isMainActivityVisible) return; currentActiveMonster = determineNextMonster(currentActiveMonster); if (currentActiveMonster == null) { endMonsterTurn(); return; } - currentActiveMonster.useAPs(currentActiveMonster.getAttackCost()); + view.actorStatsController.useAPs(currentActiveMonster, currentActiveMonster.getAttackCost()); - context.mainActivity.combatview.updateTurnInfo(currentActiveMonster); - Resources r = context.mainActivity.getResources(); - AttackResult attack = monsterAttacks(model, currentActiveMonster); + combatTurnListeners.onMonsterIsAttacking(currentActiveMonster); + AttackResult attack = monsterAttacks(world.model, currentActiveMonster); this.lastAttackResult = attack; - String monsterName = currentActiveMonster.getName(); if (attack.isHit) { - if (attack.isCriticalHit) { - message(r.getString(R.string.combat_result_monsterhitcritical, monsterName, attack.damage)); - } else { - message(r.getString(R.string.combat_result_monsterhit, monsterName, attack.damage)); - } - context.mainActivity.updateStatus(); + combatActionListeners.onMonsterAttackSuccess(currentActiveMonster, attack); - startAttackEffect(attack, model.player.position, this, CALLBACK_MONSTERATTACK); + startAttackEffect(attack, world.model.player.position, this, CALLBACK_MONSTERATTACK); } else { - message(r.getString(R.string.combat_result_monstermiss, monsterName)); - context.mainActivity.updateStatus(); + combatActionListeners.onMonsterAttackMissed(currentActiveMonster, attack); - monsterTurnHandler.sendEmptyMessageDelayed(0, context.preferences.attackspeed_milliseconds); + monsterTurnHandler.sendEmptyMessageDelayed(0, view.preferences.attackspeed_milliseconds); } } @@ -370,20 +338,19 @@ public final class CombatController implements VisualEffectCompletedCallback { private void monsterAttackCompleted() { if (lastAttackResult.targetDied) { - context.controller.handlePlayerDeath(); + view.controller.handlePlayerDeath(); return; } handleNextMonsterAction(); } private void startAttackEffect(AttackResult attack, final Coord position, VisualEffectCompletedCallback callback, int callbackValue) { - if (context.preferences.attackspeed_milliseconds <= 0) { + if (view.preferences.attackspeed_milliseconds <= 0) { callback.onVisualEffectCompleted(callbackValue); return; } - context.effectController.startEffect( - context.mainActivity.mainview - , position + view.effectController.startEffect( + position , VisualEffectCollection.EFFECT_BLOOD , attack.damage , callback @@ -395,14 +362,10 @@ public final class CombatController implements VisualEffectCompletedCallback { } private void newPlayerTurn(boolean isFirstRound) { - model.player.setMaxAP(); - if (!isFirstRound) context.gameRoundController.onNewPlayerRound(); - model.uiSelections.isPlayersCombatTurn = true; - updateTurnInfo(); - } - private void updateTurnInfo() { - context.mainActivity.combatview.updateTurnInfo(currentActiveMonster); - context.mainActivity.updateStatus(); + view.actorStatsController.setActorMaxAP(world.model.player); + if (!isFirstRound) view.gameRoundController.onNewPlayerRound(); + world.model.uiSelections.isPlayersCombatTurn = true; + combatTurnListeners.onNewPlayerTurn(); } private static boolean hasCriticalAttack(Actor attacker, Actor target) { @@ -445,13 +408,13 @@ public final class CombatController implements VisualEffectCompletedCallback { private AttackResult playerAttacks(WorldContext world, Monster currentMonster) { AttackResult result = attack(world.model.player, currentMonster); - SkillController.applySkillEffectsFromPlayerAttack(result, world, currentMonster); + view.skillController.applySkillEffectsFromPlayerAttack(result, world, currentMonster); return result; } private AttackResult monsterAttacks(ModelContainer model, Monster currentMonster) { AttackResult result = attack(currentMonster, model.player); - SkillController.applySkillEffectsFromMonsterAttack(result, world, currentMonster); + view.skillController.applySkillEffectsFromMonsterAttack(result, world, currentMonster); return result; } @@ -479,7 +442,7 @@ public final class CombatController implements VisualEffectCompletedCallback { } damage -= target.getDamageResistance(); if (damage < 0) damage = 0; - target.health.subtract(damage, false); + view.actorStatsController.removeActorHealth(world.model.player, damage); applyAttackHitStatusEffects(attacker, target); @@ -491,7 +454,7 @@ public final class CombatController implements VisualEffectCompletedCallback { if (onHitEffects == null) return; for (ItemTraits_OnUse e : onHitEffects) { - context.actorStatsController.applyUseEffect(attacker, target, e); + view.actorStatsController.applyUseEffect(attacker, target, e); } } @@ -502,7 +465,6 @@ public final class CombatController implements VisualEffectCompletedCallback { public void startFlee() { setCombatSelection(null, null); - Resources r = context.mainActivity.getResources(); - message(r.getString(R.string.combat_begin_flee)); + combatActionListeners.onPlayerStartedFleeing(); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/Controller.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/Controller.java index 4672b3f75..65affb138 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/Controller.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/Controller.java @@ -1,13 +1,8 @@ package com.gpl.rpg.AndorsTrail.controller; -import android.app.Activity; - -import com.gpl.rpg.AndorsTrail.Dialogs; -import com.gpl.rpg.AndorsTrail.R; -import com.gpl.rpg.AndorsTrail.activity.MainActivity; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.model.ModelContainer; +import com.gpl.rpg.AndorsTrail.controller.listeners.WorldEventListeners; import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection; import com.gpl.rpg.AndorsTrail.model.actor.Monster; import com.gpl.rpg.AndorsTrail.model.actor.Player; @@ -19,19 +14,18 @@ public final class Controller { private final ViewContext view; private final WorldContext world; - private final ModelContainer model; + public final WorldEventListeners worldEventListeners = new WorldEventListeners(); - public Controller(ViewContext context) { + public Controller(ViewContext context, WorldContext world) { this.view = context; - this.world = context; - this.model = world.model; + this.world = world; } public void handleMapEvent(MapObject o, Coord position) { switch (o.type) { case MapObject.MAPEVENT_SIGN: if (o.id == null || o.id.length() <= 0) return; - Dialogs.showMapSign(view.mainActivity, view, o.id); + worldEventListeners.onPlayerSteppedOnMapSignArea(o); break; case MapObject.MAPEVENT_NEWMAP: if (o.map == null || o.place == null) return; @@ -40,10 +34,18 @@ public final class Controller { view.movementController.placePlayerAt(MapObject.MAPEVENT_NEWMAP, o.map, o.place, offset_x, offset_y); break; case MapObject.MAPEVENT_REST: - Dialogs.showRest(view.mainActivity, view, o); + steppedOnRestArea(o); break; } } + + private void steppedOnRestArea(MapObject area) { + if (!view.preferences.confirmRest) { + rest(area); + } else { + worldEventListeners.onPlayerSteppedOnRestArea(area); + } + } public void steppedOnMonster(Monster m, Coord p) { if (m.isAgressive()) { @@ -51,54 +53,48 @@ public final class Controller { if (!view.preferences.confirmAttack) { view.combatController.enterCombat(CombatController.BEGIN_TURN_PLAYER); } else { - Dialogs.showMonsterEncounter(view.mainActivity, view, m); + worldEventListeners.onPlayerSteppedOnMonster(m); } } else { - Dialogs.showConversation(view.mainActivity, view, m.getPhraseID(), m); + worldEventListeners.onPlayerStartedConversation(m, m.getPhraseID()); } } public void handlePlayerDeath() { view.combatController.exitCombat(false); - final Player player = model.player; - int lostExp = player.levelExperience.current * Constants.PERCENT_EXP_LOST_WHEN_DIED / 100; + final Player player = world.model.player; + int lostExp = player.getCurrentLevelExperience() * Constants.PERCENT_EXP_LOST_WHEN_DIED / 100; lostExp -= lostExp * player.getSkillLevel(SkillCollection.SKILL_LOWER_EXPLOSS) * SkillCollection.PER_SKILLPOINT_INCREASE_EXPLOSS_PERCENT / 100; if (lostExp < 0) lostExp = 0; - player.addExperience(-lostExp); - model.statistics.addPlayerDeath(lostExp); - final MainActivity act = view.mainActivity; - MovementController.respawnPlayer(act.getResources(), world); - playerRested(world, null); - act.updateStatus(); - act.mainview.notifyMapChanged(world.model); - act.message(act.getResources().getString(R.string.combat_hero_dies, lostExp)); + view.actorStatsController.addExperience(-lostExp); + world.model.statistics.addPlayerDeath(lostExp); + view.movementController.respawnPlayer(); + lotsOfTimePassed(); + worldEventListeners.onPlayerDied(lostExp); } - public static void playerRested(final WorldContext world, MapObject area) { + public void lotsOfTimePassed() { final Player player = world.model.player; - ActorStatsController.removeAllTemporaryConditions(player); - ActorStatsController.recalculatePlayerStats(player); - player.setMaxAP(); - player.setMaxHP(); - if (area != null) { - player.setSpawnPlace(world.model.currentMap.name, area.id); - } + view.actorStatsController.removeAllTemporaryConditions(player); + view.actorStatsController.recalculatePlayerStats(player); + view.actorStatsController.setActorMaxAP(player); + view.actorStatsController.setActorMaxHealth(player); for (PredefinedMap m : world.maps.predefinedMaps) { m.resetTemporaryData(); } - world.model.currentMap.spawnAll(world); + view.monsterSpawnController.spawnAll(world.model.currentMap); } - public static void ui_playerRested(final Activity currentActivity, final ViewContext viewContext, MapObject area) { - playerRested(viewContext, area); - viewContext.mainActivity.updateStatus(); - Dialogs.showRested(currentActivity, viewContext); + public void rest(MapObject area) { + lotsOfTimePassed(); + world.model.player.setSpawnPlace(world.model.currentMap.name, area.id); + worldEventListeners.onPlayerRested(); } - public boolean handleKeyArea(MapObject area) { - if (view.model.player.hasExactQuestProgress(area.requireQuestProgress)) return true; - Dialogs.showKeyArea(view.mainActivity, view, area.id); + public boolean canEnterKeyArea(MapObject area) { + if (world.model.player.hasExactQuestProgress(area.requireQuestProgress)) return true; + worldEventListeners.onPlayerSteppedOnKeyArea(area); return false; } @@ -110,11 +106,4 @@ public final class Controller { m.resetTemporaryData(); } } - - public boolean moveAndSpawnMonsters() { - boolean hasChanged = false; - if (view.monsterMovementController.moveMonsters()) hasChanged = true; - if (model.currentMap.maybeSpawn(world)) hasChanged = true; - return hasChanged; - } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ConversationController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ConversationController.java index ca0375f7e..91939655a 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ConversationController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ConversationController.java @@ -1,5 +1,6 @@ package com.gpl.rpg.AndorsTrail.controller; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.conversation.Phrase; import com.gpl.rpg.AndorsTrail.conversation.Phrase.Reply; @@ -16,9 +17,17 @@ import com.gpl.rpg.AndorsTrail.util.ConstRange; public final class ConversationController { + private final ViewContext view; + private final WorldContext world; + + public ConversationController(ViewContext view, WorldContext world) { + this.view = view; + this.world = world; + } + private static final ConstRange always = new ConstRange(1, 1); - public static Loot applyPhraseRewards(final Player player, final Phrase phrase, final WorldContext world) { + public Loot applyPhraseRewards(final Player player, final Phrase phrase) { if (phrase.rewards == null || phrase.rewards.length == 0) return null; final Loot loot = new Loot(); @@ -32,11 +41,11 @@ public final class ConversationController { ActorConditionType conditionType = world.actorConditionsTypes.getActorConditionType(reward.rewardID); ActorConditionEffect e = new ActorConditionEffect(conditionType, magnitude, duration, always); - ActorStatsController.applyActorCondition(player, e); + view.actorStatsController.applyActorCondition(player, e); break; case Reward.REWARD_TYPE_SKILL_INCREASE: int skillID = Integer.parseInt(reward.rewardID); - SkillController.levelUpSkillByQuest(player, world.skills.getSkill(skillID)); + view.skillController.levelUpSkillByQuest(player, world.skills.getSkill(skillID)); break; case Reward.REWARD_TYPE_DROPLIST: world.dropLists.getDropList(reward.rewardID).createRandomLoot(loot, player); @@ -58,7 +67,7 @@ public final class ConversationController { } player.inventory.add(loot); - player.addExperience(loot.exp); + view.actorStatsController.addExperience(loot.exp); return loot; } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/GameRoundController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/GameRoundController.java index 930434df2..0c5e7c8aa 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/GameRoundController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/GameRoundController.java @@ -2,29 +2,25 @@ package com.gpl.rpg.AndorsTrail.controller; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.model.ModelContainer; import com.gpl.rpg.AndorsTrail.util.TimedMessageTask; -import com.gpl.rpg.AndorsTrail.view.MainView; public final class GameRoundController implements TimedMessageTask.Callback { private final ViewContext view; private final WorldContext world; - private final ModelContainer model; private final TimedMessageTask roundTimer; - public GameRoundController(ViewContext context) { + public GameRoundController(ViewContext context, WorldContext world) { this.view = context; - this.world = context; - this.model = world.model; + this.world = world; this.roundTimer = new TimedMessageTask(this, Constants.TICK_DELAY, true); } private int ticksUntilNextRound = Constants.TICKS_PER_ROUND; private int ticksUntilNextFullRound = Constants.TICKS_PER_FULLROUND; public boolean onTick(TimedMessageTask task) { - if (!model.uiSelections.isMainActivityVisible) return false; - if (model.uiSelections.isInCombat) return false; + if (!world.model.uiSelections.isMainActivityVisible) return false; + if (world.model.uiSelections.isInCombat) return false; onNewTick(); @@ -44,8 +40,7 @@ public final class GameRoundController implements TimedMessageTask.Callback { } public void resume() { - view.mainActivity.updateStatus(); - model.uiSelections.isMainActivityVisible = true; + world.model.uiSelections.isMainActivityVisible = true; restartWaitForNextRound(); restartWaitForNextFullRound(); roundTimer.start(); @@ -61,13 +56,13 @@ public final class GameRoundController implements TimedMessageTask.Callback { public void pause() { roundTimer.stop(); - model.uiSelections.isMainActivityVisible = false; + world.model.uiSelections.isMainActivityVisible = false; } public void onNewFullRound() { Controller.resetMapsNotRecentlyVisited(world); - view.actorStatsController.applyConditionsToMonsters(model.currentMap, true); - view.actorStatsController.applyConditionsToPlayer(model.player, true); + view.actorStatsController.applyConditionsToMonsters(world.model.currentMap, true); + view.actorStatsController.applyConditionsToPlayer(world.model.player, true); } public void onNewRound() { @@ -75,19 +70,17 @@ public final class GameRoundController implements TimedMessageTask.Callback { onNewPlayerRound(); } public void onNewPlayerRound() { - view.actorStatsController.applyConditionsToPlayer(model.player, false); - view.actorStatsController.applySkillEffectsForNewRound(model.player, model.currentMap); + view.actorStatsController.applyConditionsToPlayer(world.model.player, false); + view.actorStatsController.applySkillEffectsForNewRound(world.model.player, world.model.currentMap); } public void onNewMonsterRound() { - view.actorStatsController.applyConditionsToMonsters(model.currentMap, false); + view.actorStatsController.applyConditionsToMonsters(world.model.currentMap, false); } private void onNewTick() { - boolean hasChanged = false; - if (view.controller.moveAndSpawnMonsters()) hasChanged = true; + view.monsterMovementController.moveMonsters(); + view.monsterSpawnController.maybeSpawn(world.model.currentMap); view.monsterMovementController.attackWithAgressiveMonsters(); - if (VisualEffectController.updateSplatters(model.currentMap)) hasChanged = true; - - if (hasChanged) view.mainActivity.redrawAll(MainView.REDRAW_ALL_MONSTER_MOVED); //TODO: should only redraw spawned tiles + view.effectController.updateSplatters(world.model.currentMap); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/InputController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/InputController.java index b128fd963..a20432739 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/InputController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/InputController.java @@ -7,23 +7,20 @@ import android.view.View.OnLongClickListener; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.model.ModelContainer; import com.gpl.rpg.AndorsTrail.util.Coord; public final class InputController implements OnClickListener, OnLongClickListener{ private final ViewContext view; private final WorldContext world; - private final ModelContainer model; private final Coord lastTouchPosition_tileCoords = new Coord(); private int lastTouchPosition_dx = 0; private int lastTouchPosition_dy = 0; private long lastTouchEventTime = 0; - public InputController(ViewContext context) { - this.view = context; - this.world = context; - this.model = world.model; + public InputController(ViewContext view, WorldContext world) { + this.view = view; + this.world = world; } public boolean onKeyboardAction(int keyCode) { @@ -54,7 +51,7 @@ public final class InputController implements OnClickListener, OnLongClickListen } public void onRelativeMovement(int dx, int dy) { if (!allowInputInterval()) return; - if (model.uiSelections.isInCombat) { + if (world.model.uiSelections.isInCombat) { view.combatController.executeMoveAttack(dx, dy); } else { view.movementController.startMovement(dx, dy, null); @@ -67,13 +64,13 @@ public final class InputController implements OnClickListener, OnLongClickListen @Override public void onClick(View arg0) { - if (!model.uiSelections.isInCombat) return; + if (!world.model.uiSelections.isInCombat) return; onRelativeMovement(lastTouchPosition_dx, lastTouchPosition_dy); } @Override public boolean onLongClick(View arg0) { - if (model.uiSelections.isInCombat) { + if (world.model.uiSelections.isInCombat) { //TODO: Should be able to mark positions far away (mapwalk / ranged combat) if (lastTouchPosition_dx == 0 && lastTouchPosition_dy == 0) return false; if (Math.abs(lastTouchPosition_dx) > 1) return false; @@ -98,10 +95,10 @@ public final class InputController implements OnClickListener, OnLongClickListen public boolean onTouchedTile(int tile_x, int tile_y) { lastTouchPosition_tileCoords.set(tile_x, tile_y); - lastTouchPosition_dx = tile_x - model.player.position.x; - lastTouchPosition_dy = tile_y - model.player.position.y; + lastTouchPosition_dx = tile_x - world.model.player.position.x; + lastTouchPosition_dy = tile_y - world.model.player.position.y; - if (model.uiSelections.isInCombat) return false; + if (world.model.uiSelections.isInCombat) return false; view.movementController.startMovement(lastTouchPosition_dx, lastTouchPosition_dy, lastTouchPosition_tileCoords); return true; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java index 7ad6e2636..adbd4f423 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java @@ -2,9 +2,11 @@ package com.gpl.rpg.AndorsTrail.controller; import java.util.ArrayList; -import com.gpl.rpg.AndorsTrail.Dialogs; +import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.controller.listeners.LootBagListeners; +import com.gpl.rpg.AndorsTrail.controller.listeners.QuickSlotListeners; import com.gpl.rpg.AndorsTrail.model.ModelContainer; import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection; import com.gpl.rpg.AndorsTrail.model.ability.traits.AbilityModifierTraits; @@ -15,31 +17,31 @@ import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; import com.gpl.rpg.AndorsTrail.model.item.ItemType; import com.gpl.rpg.AndorsTrail.model.item.Loot; import com.gpl.rpg.AndorsTrail.model.item.ItemContainer.ItemEntry; -import com.gpl.rpg.AndorsTrail.view.MainView; public final class ItemController { private final ViewContext view; private final WorldContext world; - private final ModelContainer model; + public final QuickSlotListeners quickSlotListeners = new QuickSlotListeners(); + public final LootBagListeners lootBagListeners = new LootBagListeners(); - public ItemController(ViewContext context) { + public ItemController(ViewContext context, WorldContext world) { this.view = context; - this.world = context; - this.model = world.model; + this.world = world; } public void dropItem(ItemType type, int quantity) { - if (model.player.inventory.getItemQuantity(type.id) < quantity) return; - model.player.inventory.removeItem(type.id, quantity); - model.currentMap.itemDropped(type, quantity, model.player.position); + if (world.model.player.inventory.getItemQuantity(type.id) < quantity) return; + world.model.player.inventory.removeItem(type.id, quantity); + world.model.currentMap.itemDropped(type, quantity, world.model.player.position); } public void equipItem(ItemType type, int slot) { if (!type.isEquippable()) return; - final Player player = model.player; - if (model.uiSelections.isInCombat) { - if (!player.useAPs(player.getReequipCost())) return; + final Player player = world.model.player; + if (world.model.uiSelections.isInCombat) { + boolean changed = view.actorStatsController.useAPs(player, player.getReequipCost()); + if (!changed) return; } if (!player.inventory.removeItem(type.id, 1)) return; @@ -52,53 +54,79 @@ public final class ItemController { } player.inventory.wear[slot] = type; - ActorStatsController.addConditionsFromEquippedItem(player, type); - ActorStatsController.recalculatePlayerStats(player); + view.actorStatsController.addConditionsFromEquippedItem(player, type); + view.actorStatsController.recalculatePlayerStats(player); } public void unequipSlot(ItemType type, int slot) { if (!type.isEquippable()) return; - final Player player = model.player; + final Player player = world.model.player; if (player.inventory.isEmptySlot(slot)) return; - if (model.uiSelections.isInCombat) { - if (!player.useAPs(player.getReequipCost())) return; + if (world.model.uiSelections.isInCombat) { + boolean changed = view.actorStatsController.useAPs(player, player.getReequipCost()); + if (!changed) return; } unequipSlot(player, slot); - ActorStatsController.recalculatePlayerStats(player); + view.actorStatsController.recalculatePlayerStats(player); } - private static void unequipSlot(Player player, int slot) { + private void unequipSlot(Player player, int slot) { ItemType removedItemType = player.inventory.wear[slot]; if (removedItemType == null) return; player.inventory.addItem(removedItemType); player.inventory.wear[slot] = null; - ActorStatsController.removeConditionsFromUnequippedItem(player, removedItemType); + view.actorStatsController.removeConditionsFromUnequippedItem(player, removedItemType); } public void useItem(ItemType type) { if (!type.isUsable()) return; - final Player player = model.player; - if (model.uiSelections.isInCombat) { - if (!player.useAPs(player.getUseItemCost())) return; + final Player player = world.model.player; + if (world.model.uiSelections.isInCombat) { + boolean changed = view.actorStatsController.useAPs(player, player.getUseItemCost()); + if (!changed) return; } if (!player.inventory.removeItem(type.id, 1)) return; view.actorStatsController.applyUseEffect(player, null, type.effects_use); - model.statistics.addItemUsage(type); + world.model.statistics.addItemUsage(type); //TODO: provide feedback that the item has been used. //context.mainActivity.message(androidContext.getResources().getString(R.string.inventory_item_used, type.name)); } - public void handleLootBag(Loot loot) { - Dialogs.showGroundLoot(view.mainActivity, view, loot); - consumeNonItemLoot(loot, model); + public void playerSteppedOnLootBag(Loot loot) { + if (pickupLootBagWithoutConfirmation(loot.isContainer())) { + view.controller.worldEventListeners.onPlayerPickedUpGroundLoot(loot); + pickupAll(loot); + removeLootBagIfEmpty(loot); + } else { + view.controller.worldEventListeners.onPlayerSteppedOnGroundLoot(loot); + consumeNonItemLoot(loot); + } } - public static void applyInventoryEffects(Player player) { + public void lootMonsterBags(Iterable killedMonsterBags, int totalExpThisFight) { + if (pickupLootBagWithoutConfirmation(false)) { + view.controller.worldEventListeners.onPlayerPickedUpMonsterLoot(killedMonsterBags, totalExpThisFight); + pickupAll(killedMonsterBags); + removeLootBagIfEmpty(killedMonsterBags); + view.gameRoundController.resume(); + } else { + view.controller.worldEventListeners.onPlayerFoundMonsterLoot(killedMonsterBags, totalExpThisFight); + consumeNonItemLoot(killedMonsterBags); + } + } + + private boolean pickupLootBagWithoutConfirmation(boolean isContainer) { + if (isContainer) return false; + if (view.preferences.displayLoot == AndorsTrailPreferences.DISPLAYLOOT_DIALOG) return false; + return true; + } + + public void applyInventoryEffects(Player player) { ItemType weapon = getMainWeapon(player); if (weapon != null) { player.attackCost = 0; @@ -126,7 +154,7 @@ public final class ItemController { return null; } - private static void applyInventoryEffects(Player player, int slot) { + private void applyInventoryEffects(Player player, int slot) { ItemType type = player.inventory.wear[slot]; if (type == null) return; if (slot == Inventory.WEARSLOT_SHIELD) { @@ -135,7 +163,7 @@ public final class ItemController { if (SkillController.isDualWielding(mainHandItem, type)) return; } if (type.effects_equip != null && type.effects_equip.stats != null) - ActorStatsController.applyAbilityEffects(player, type.effects_equip.stats, 1); + view.actorStatsController.applyAbilityEffects(player, type.effects_equip.stats, 1); } public static void recalculateHitEffectsFromWornItems(Player player) { @@ -159,51 +187,46 @@ public final class ItemController { } } - public static void consumeNonItemLoot(Loot loot, ModelContainer model) { + public void consumeNonItemLoot(Loot loot) { // Experience will be given as soon as the monster is killed. - model.player.inventory.gold += loot.gold; + world.model.player.inventory.gold += loot.gold; loot.gold = 0; - removeEmptyLoot(loot, model); + removeLootBagIfEmpty(loot); } - public static void consumeNonItemLoot(Iterable lootBags, ModelContainer model) { + public void consumeNonItemLoot(Iterable lootBags) { for(Loot l : lootBags) { - consumeNonItemLoot(l, model); + consumeNonItemLoot(l); } } - public static void pickupAll(Loot loot, ModelContainer model) { - model.player.inventory.add(loot.items); - consumeNonItemLoot(loot, model); + public void pickupAll(Loot loot) { + world.model.player.inventory.add(loot.items); + consumeNonItemLoot(loot); loot.clear(); } - public static void pickupAll(Iterable lootBags, ModelContainer model) { + public void pickupAll(Iterable lootBags) { for(Loot l : lootBags) { - pickupAll(l, model); + pickupAll(l); } } - public static boolean removeEmptyLoot(Loot loot, ModelContainer model) { + public boolean removeLootBagIfEmpty(final Loot loot) { if (!loot.hasItems()) { - model.currentMap.removeGroundLoot(loot); + world.model.currentMap.removeGroundLoot(loot); + lootBagListeners.onLootBagRemoved(loot.position); return true; // The bag was removed. } else { return false; } } - public static boolean updateLootVisibility(final ViewContext context, final Iterable lootBags) { + public boolean removeLootBagIfEmpty(final Iterable lootBags) { boolean isEmpty = true; for (Loot l : lootBags) { - if (!updateLootVisibility(context, l)) isEmpty = false; + if (!removeLootBagIfEmpty(l)) isEmpty = false; } return isEmpty; } - public static boolean updateLootVisibility(final ViewContext context, final Loot loot) { - final boolean isBagRemoved = removeEmptyLoot(loot, context.model); - context.mainActivity.redrawTile(loot.position, MainView.REDRAW_TILE_BAG); - return isBagRemoved; - } - private static int getMarketPriceFactor(Player player) { return Constants.MARKET_PRICEFACTOR_PERCENT - player.getSkillLevel(SkillCollection.SKILL_BARTER) * SkillCollection.PER_SKILLPOINT_INCREASE_BARTER_PRICEFACTOR_PERCENTAGE; @@ -316,12 +339,12 @@ public final class ItemController { } public void quickitemUse(int quickSlotId) { - useItem(model.player.inventory.quickitem[quickSlotId]); - view.mainActivity.updateStatus(); + useItem(world.model.player.inventory.quickitem[quickSlotId]); + quickSlotListeners.onQuickSlotUsed(quickSlotId); } public void setQuickItem(ItemType itemType, int quickSlotId) { - model.player.inventory.quickitem[quickSlotId] = itemType; - view.mainActivity.updateStatus(); + world.model.player.inventory.quickitem[quickSlotId] = itemType; + quickSlotListeners.onQuickSlotChanged(quickSlotId); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MonsterMovementController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MonsterMovementController.java index c9b7aed5c..3c0dcaef8 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MonsterMovementController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MonsterMovementController.java @@ -2,54 +2,64 @@ package com.gpl.rpg.AndorsTrail.controller; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.model.ModelContainer; +import com.gpl.rpg.AndorsTrail.controller.listeners.MonsterMovementListeners; import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection; import com.gpl.rpg.AndorsTrail.model.actor.Monster; +import com.gpl.rpg.AndorsTrail.model.map.MapObject; import com.gpl.rpg.AndorsTrail.model.map.MonsterSpawnArea; +import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap; import com.gpl.rpg.AndorsTrail.util.Coord; +import com.gpl.rpg.AndorsTrail.util.CoordRect; public final class MonsterMovementController { private final ViewContext view; private final WorldContext world; - private final ModelContainer model; + public final MonsterMovementListeners monsterMovementListeners = new MonsterMovementListeners(); - public MonsterMovementController(ViewContext context) { - this.view = context; - this.world = context; - this.model = world.model; + public MonsterMovementController(ViewContext context, WorldContext world) { + this.view = context; + this.world = world; } - public boolean moveMonsters() { - boolean atLeastOneMonsterMoved = false; + public void moveMonsters() { long currentTime = System.currentTimeMillis(); - for (MonsterSpawnArea a : model.currentMap.spawnAreas) { + for (MonsterSpawnArea a : world.model.currentMap.spawnAreas) { for (Monster m : a.monsters) { if (m.nextActionTime <= currentTime) { - if (moveMonster(m, a, currentTime)) atLeastOneMonsterMoved = true; + moveMonster(m, a, currentTime); } } } - - return atLeastOneMonsterMoved; } public void attackWithAgressiveMonsters() { - for (MonsterSpawnArea a : model.currentMap.spawnAreas) { + for (MonsterSpawnArea a : world.model.currentMap.spawnAreas) { for (Monster m : a.monsters) { if (!m.isAgressive()) continue; - if (!m.isAdjacentTo(model.player)) continue; + if (!m.isAdjacentTo(world.model.player)) continue; - int aggressionChanceBias = model.player.getSkillLevel(SkillCollection.SKILL_EVASION) * SkillCollection.PER_SKILLPOINT_INCREASE_EVASION_MONSTER_ATTACK_CHANCE_PERCENTAGE; + int aggressionChanceBias = world.model.player.getSkillLevel(SkillCollection.SKILL_EVASION) * SkillCollection.PER_SKILLPOINT_INCREASE_EVASION_MONSTER_ATTACK_CHANCE_PERCENTAGE; if (Constants.roll100(Constants.MONSTER_AGGRESSION_CHANCE_PERCENT - aggressionChanceBias)) { + monsterMovementListeners.onMonsterSteppedOnPlayer(m); view.combatController.monsterSteppedOnPlayer(m); return; } } } } + + public static boolean monsterCanMoveTo(final PredefinedMap map, final CoordRect p) { + if (!map.isWalkable(p)) return false; + if (map.getMonsterAt(p) != null) return false; + MapObject m = map.getEventObjectAt(p.topLeft); + if (m != null) { + if (m.type == MapObject.MAPEVENT_NEWMAP) return false; + } + return true; + } - private boolean moveMonster(final Monster m, final MonsterSpawnArea area, long currentTime) { + private void moveMonster(final Monster m, final MonsterSpawnArea area, long currentTime) { m.nextActionTime += getMillisecondsPerMove(m); if (m.movementDestination == null) { // Monster has waited and should start to move again. @@ -69,22 +79,23 @@ public final class MonsterMovementController { ,m.position.y + sgn(m.movementDestination.y - m.position.y) ); - if (!model.currentMap.monsterCanMoveTo(m.nextPosition)) { + if (!monsterCanMoveTo(world.model.currentMap, m.nextPosition)) { cancelCurrentMonsterMovement(m); - return false; + return; } - if (m.nextPosition.contains(model.player.position)) { + if (m.nextPosition.contains(world.model.player.position)) { if (!m.isAgressive()) { cancelCurrentMonsterMovement(m); - return false; + return; } + monsterMovementListeners.onMonsterSteppedOnPlayer(m); view.combatController.monsterSteppedOnPlayer(m); } else { + CoordRect previousPosition = new CoordRect(m.position, m.rectPosition.size); m.position.set(m.nextPosition.topLeft); + monsterMovementListeners.onMonsterMoved(m, previousPosition); } - return true; } - return false; } private void cancelCurrentMonsterMovement(final Monster m) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MonsterSpawningController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MonsterSpawningController.java new file mode 100644 index 000000000..e6b0c7890 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MonsterSpawningController.java @@ -0,0 +1,80 @@ +package com.gpl.rpg.AndorsTrail.controller; + +import com.gpl.rpg.AndorsTrail.context.ViewContext; +import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.controller.listeners.MonsterSpawnListeners; +import com.gpl.rpg.AndorsTrail.model.actor.Monster; +import com.gpl.rpg.AndorsTrail.model.actor.MonsterType; +import com.gpl.rpg.AndorsTrail.model.map.MonsterSpawnArea; +import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap; +import com.gpl.rpg.AndorsTrail.util.Coord; +import com.gpl.rpg.AndorsTrail.util.CoordRect; +import com.gpl.rpg.AndorsTrail.util.Size; + +public final class MonsterSpawningController { + private final ViewContext view; + private final WorldContext world; + public final MonsterSpawnListeners monsterSpawnListeners = new MonsterSpawnListeners(); + + public MonsterSpawningController(ViewContext view, WorldContext world) { + this.view = view; + this.world = world; + } + + public void spawnAllInArea(PredefinedMap map, MonsterSpawnArea area, boolean respawnUniqueMonsters) { + while (area.isSpawnable(respawnUniqueMonsters)) { + final boolean wasAbleToSpawn = spawnInArea(map, area, null); + if (!wasAbleToSpawn) break; + } + view.actorStatsController.healAllMonsters(area); + } + + public void maybeSpawn(PredefinedMap map) { + for (MonsterSpawnArea a : map.spawnAreas) { + if (!a.isSpawnable(false)) continue; + if (!a.rollShouldSpawn()) continue; + spawnInArea(map, a, world.model.player.position); + } + } + + public void spawnAll(PredefinedMap map) { + boolean respawnUniqueMonsters = false; + if (!map.visited) respawnUniqueMonsters = true; + for (MonsterSpawnArea a : map.spawnAreas) { + spawnAllInArea(map, a, respawnUniqueMonsters); + } + } + + private boolean spawnInArea(PredefinedMap map, MonsterSpawnArea a, Coord playerPosition) { + return spawnInArea(map, a, a.getRandomMonsterType(world), playerPosition); + } + public boolean TEST_spawnInArea(PredefinedMap map, MonsterSpawnArea a, MonsterType type) { return spawnInArea(map, a, type, null); } + private boolean spawnInArea(PredefinedMap map, MonsterSpawnArea a, MonsterType type, Coord playerPosition) { + Coord p = getRandomFreePosition(map, a.area, type.tileSize, playerPosition); + if (p == null) return false; + Monster m = a.spawn(p, type); + monsterSpawnListeners.onMonsterSpawned(m); + return true; + } + + public static Coord getRandomFreePosition(PredefinedMap map, CoordRect area, Size requiredSize, Coord playerPosition) { + CoordRect p = new CoordRect(requiredSize); + for(int i = 0; i < 100; ++i) { + p.topLeft.set( + area.topLeft.x + Constants.rnd.nextInt(area.size.width) + ,area.topLeft.y + Constants.rnd.nextInt(area.size.height)); + if (!MonsterMovementController.monsterCanMoveTo(map, p)) continue; + if (playerPosition != null && p.contains(playerPosition)) continue; + return p.topLeft; + } + return null; // Couldn't find a free spot. + } + + public void remove(PredefinedMap map, Monster m) { + for (MonsterSpawnArea a : map.spawnAreas) { + a.remove(m); + } + monsterSpawnListeners.onMonsterRemoved(m, m.rectPosition); + } + +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java index 74d4dab55..199e60aea 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java @@ -6,6 +6,7 @@ import android.os.AsyncTask; import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.controller.listeners.PlayerMovementListeners; import com.gpl.rpg.AndorsTrail.model.ModelContainer; import com.gpl.rpg.AndorsTrail.model.actor.Monster; import com.gpl.rpg.AndorsTrail.model.actor.Player; @@ -23,13 +24,12 @@ import com.gpl.rpg.AndorsTrail.util.TimedMessageTask; public final class MovementController implements TimedMessageTask.Callback { private final ViewContext view; private final WorldContext world; - private final ModelContainer model; private final TimedMessageTask movementHandler; + public final PlayerMovementListeners playerMovementListeners = new PlayerMovementListeners(); - public MovementController(ViewContext context) { + public MovementController(ViewContext context, WorldContext world) { this.view = context; - this.world = context; - this.model = world.model; + this.world = world; this.movementHandler = new TimedMessageTask(this, Constants.MINIMUM_INPUT_INTERVAL, false); } @@ -40,7 +40,7 @@ public final class MovementController implements TimedMessageTask.Callback { protected Void doInBackground(Void... arg0) { stopMovement(); - placePlayerAt(view.mainActivity.getResources(), world, objectType, mapName, placeName, offset_x, offset_y); + placePlayerAt(view.getResources(), objectType, mapName, placeName, offset_x, offset_y); return null; } @@ -48,8 +48,7 @@ public final class MovementController implements TimedMessageTask.Callback { @Override protected void onPostExecute(Void result) { super.onPostExecute(result); - view.mainActivity.clearMessages(); - view.mainActivity.mainview.notifyMapChanged(model); + playerMovementListeners.onPlayerEnteredNewMap(world.model.currentMap, world.model.player.position); stopMovement(); view.gameRoundController.resume(); } @@ -59,7 +58,7 @@ public final class MovementController implements TimedMessageTask.Callback { task.execute(); } - public static void placePlayerAt(final Resources res, final WorldContext world, int objectType, String mapName, String placeName, int offset_x, int offset_y) { + public void placePlayerAt(final Resources res, int objectType, String mapName, String placeName, int offset_x, int offset_y) { if (mapName == null || placeName == null) return; PredefinedMap newMap = world.maps.findPredefinedMap(mapName); if (newMap == null) { @@ -81,26 +80,26 @@ public final class MovementController implements TimedMessageTask.Callback { model.player.position.y += Math.min(offset_y, place.position.size.height-1); model.player.lastPosition.set(model.player.position); - if (!newMap.visited) playerVisitsMapFirstTime(world, newMap); - else playerVisitsMap(world, newMap); + if (!newMap.visited) playerVisitsMapFirstTime(newMap); + else playerVisitsMap(newMap); refreshMonsterAggressiveness(newMap, model.player); - VisualEffectController.updateSplatters(newMap); + view.effectController.updateSplatters(newMap); } - private static void playerVisitsMapFirstTime(final WorldContext world, PredefinedMap m) { + private void playerVisitsMapFirstTime(PredefinedMap m) { m.reset(); - m.spawnAll(world); + view.monsterSpawnController.spawnAll(m); m.createAllContainerLoot(); m.visited = true; } - private static void playerVisitsMap(final WorldContext world, PredefinedMap m) { + private void playerVisitsMap(PredefinedMap m) { // Respawn everything if a certain time has elapsed. - if (!m.isRecentlyVisited()) m.spawnAll(world); + if (!m.isRecentlyVisited()) view.monsterSpawnController.spawnAll(m); } public boolean mayMovePlayer() { - return !model.uiSelections.isInCombat; + return !world.model.uiSelections.isInCombat; } private void movePlayer(int dx, int dy) { @@ -109,9 +108,9 @@ public final class MovementController implements TimedMessageTask.Callback { if (!findWalkablePosition(dx, dy)) return; - Monster m = model.currentMap.getMonsterAt(model.player.nextPosition); + Monster m = world.model.currentMap.getMonsterAt(world.model.player.nextPosition); if (m != null) { - view.controller.steppedOnMonster(m, model.player.nextPosition); + view.controller.steppedOnMonster(m, world.model.player.nextPosition); return; } @@ -168,20 +167,20 @@ public final class MovementController implements TimedMessageTask.Callback { } private boolean tryWalkablePosition(int dx, int dy, int aggressiveness) { - final Player player = model.player; + final Player player = world.model.player; player.nextPosition.set( player.position.x + dx ,player.position.y + dy ); - if (!model.currentMap.isWalkable(player.nextPosition)) return false; + if (!world.model.currentMap.isWalkable(player.nextPosition)) return false; // allow player to enter every field when he is NORMAL // prevent player from entering "non-monster-fields" when he is AGGRESSIVE // prevent player from entering "monster-fields" when he is DEFENSIVE if (aggressiveness == AndorsTrailPreferences.MOVEMENTAGGRESSIVENESS_NORMAL) return true; - Monster m = model.currentMap.getMonsterAt(player.nextPosition); + Monster m = world.model.currentMap.getMonsterAt(player.nextPosition); if (m != null && !m.isAgressive()) return true; // avoid MOVEMENTAGGRESSIVENESS settings for NPCs if (aggressiveness == AndorsTrailPreferences.MOVEMENTAGGRESSIVENESS_AGGRESSIVE && m == null) return false; @@ -202,14 +201,14 @@ public final class MovementController implements TimedMessageTask.Callback { } public void moveToNextIfPossible(boolean handleEvents) { - final Player player = model.player; - final PredefinedMap currentMap = model.currentMap; + final Player player = world.model.player; + final PredefinedMap currentMap = world.model.currentMap; final Coord newPosition = player.nextPosition; for (MapObject o : currentMap.eventObjects) { if (o.type == MapObject.MAPEVENT_KEYAREA) { if (o.position.contains(newPosition)) { - if (!view.controller.handleKeyArea(o)) return; + if (!view.controller.canEnterKeyArea(o)) return; } } } @@ -217,7 +216,7 @@ public final class MovementController implements TimedMessageTask.Callback { player.lastPosition.set(player.position); player.position.set(newPosition); view.combatController.setCombatSelection(null, null); - view.mainActivity.mainview.notifyPlayerMoved(newPosition); + playerMovementListeners.onPlayerMoved(newPosition, player.lastPosition); if (handleEvents) { MapObject o = currentMap.getEventObjectAt(newPosition); @@ -228,12 +227,12 @@ public final class MovementController implements TimedMessageTask.Callback { } Loot loot = currentMap.getBagAt(newPosition); - if (loot != null) view.itemController.handleLootBag(loot); + if (loot != null) view.itemController.playerSteppedOnLootBag(loot); } } - public static void respawnPlayer(final Resources res, final WorldContext world) { - placePlayerAt(res, world, MapObject.MAPEVENT_REST, world.model.player.getSpawnMap(), world.model.player.getSpawnPlace(), 0, 0); + public void respawnPlayer() { + placePlayerAt(MapObject.MAPEVENT_REST, world.model.player.getSpawnMap(), world.model.player.getSpawnPlace(), 0, 0); } public static void moveBlockedActors(final WorldContext world) { @@ -257,7 +256,7 @@ public final class MovementController implements TimedMessageTask.Callback { for (MonsterSpawnArea a : map.spawnAreas) { for (Monster m : a.monsters) { if (!map.isWalkable(m.rectPosition)) { - Coord p = map.getRandomFreePosition(a.area, m.tileSize, playerPosition); + Coord p = MonsterSpawningController.getRandomFreePosition(map, a.area, m.tileSize, playerPosition); if (p == null) continue; m.position.set(p); } @@ -280,7 +279,7 @@ public final class MovementController implements TimedMessageTask.Callback { private int movementDx; private int movementDy; public void startMovement(int dx, int dy, Coord destination) { - if (model.uiSelections.isInCombat) return; + if (world.model.uiSelections.isInCombat) return; if (dx == 0 && dy == 0) return; movementDx = dx; @@ -293,8 +292,8 @@ public final class MovementController implements TimedMessageTask.Callback { } public boolean onTick(TimedMessageTask task) { - if (!model.uiSelections.isMainActivityVisible) return false; - if (model.uiSelections.isInCombat) return false; + if (!world.model.uiSelections.isMainActivityVisible) return false; + if (world.model.uiSelections.isInCombat) return false; movePlayer(movementDx, movementDy); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java index b2d938aef..54c26cdc0 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java @@ -1,5 +1,6 @@ package com.gpl.rpg.AndorsTrail.controller; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.AttackResult; import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; @@ -15,7 +16,25 @@ import com.gpl.rpg.AndorsTrail.model.item.DropList.DropItem; import com.gpl.rpg.AndorsTrail.util.ConstRange; public final class SkillController { - public static void applySkillEffects(Player player) { + private final ViewContext view; + private final WorldContext world; + + public SkillController(ViewContext view, WorldContext world) { + this.view = view; + this.world = world; + } + + public void addSkillLevel(int skillID, boolean requireAvailableSkillpoint) { + Player player = world.model.player; + if (requireAvailableSkillpoint) { + if (!player.hasAvailableSkillpoints()) return; + --player.availableSkillIncreases; + } + player.skillLevels.put(skillID, player.skillLevels.get(skillID) + 1); + view.actorStatsController.recalculatePlayerStats(player); + } + + public void applySkillEffects(Player player) { player.attackChance += SkillCollection.PER_SKILLPOINT_INCREASE_WEAPON_CHANCE * player.getSkillLevel(SkillCollection.SKILL_WEAPON_CHANCE); player.damagePotential.addToMax(SkillCollection.PER_SKILLPOINT_INCREASE_WEAPON_DAMAGE_MAX * player.getSkillLevel(SkillCollection.SKILL_WEAPON_DMG)); player.damagePotential.add(SkillCollection.PER_SKILLPOINT_INCREASE_WEAPON_DAMAGE_MIN * player.getSkillLevel(SkillCollection.SKILL_WEAPON_DMG), false); @@ -27,7 +46,7 @@ public final class SkillController { if (player.hasCriticalMultiplierEffect()) { player.criticalMultiplier += player.criticalMultiplier * SkillCollection.PER_SKILLPOINT_INCREASE_BETTER_CRITICALS_PERCENT * player.getSkillLevel(SkillCollection.SKILL_BETTER_CRITICALS) / 100; } - player.ap.addToMax(SkillCollection.PER_SKILLPOINT_INCREASE_SPEED * player.getSkillLevel(SkillCollection.SKILL_SPEED)); + view.actorStatsController.addActorMaxAP(player, SkillCollection.PER_SKILLPOINT_INCREASE_SPEED * player.getSkillLevel(SkillCollection.SKILL_SPEED), false); /*final int berserkLevel = player.getSkillLevel(Skills.SKILL_BERSERKER); if (berserkLevel > 0) { final int berserkHealth = player.health.max * Skills.BERSERKER_STARTS_AT_HEALTH_PERCENT / 100; @@ -132,13 +151,13 @@ public final class SkillController { if (skillLevel <= 0) return false; return Constants.roll100(chancePerSkillLevel * skillLevel); } - private static void addConditionToActor(Actor target, WorldContext world, String conditionName, int magnitude, int duration) { + private void addConditionToActor(Actor target, WorldContext world, String conditionName, int magnitude, int duration) { ActorConditionType conditionType = world.actorConditionsTypes.getActorConditionType(conditionName); ActorConditionEffect effect = new ActorConditionEffect(conditionType, magnitude, duration, null); - ActorStatsController.applyActorCondition(target, effect); + view.actorStatsController.applyActorCondition(target, effect); } - public static void applySkillEffectsFromPlayerAttack(AttackResult result, WorldContext world, Monster monster) { + public void applySkillEffectsFromPlayerAttack(AttackResult result, WorldContext world, Monster monster) { if (!result.isHit) return; Player player = world.model.player; @@ -160,10 +179,10 @@ public final class SkillController { } } - public static void applySkillEffectsFromMonsterAttack(AttackResult result, WorldContext world, Monster monster) { + public void applySkillEffectsFromMonsterAttack(AttackResult result, WorldContext world, Monster monster) { if (!result.isHit) { if (rollForSkillChance(world.model.player, SkillCollection.SKILL_TAUNT, SkillCollection.PER_SKILLPOINT_INCREASE_TAUNT_CHANCE)) { - monster.ap.subtract(SkillCollection.TAUNT_AP_LOSS, false); + view.actorStatsController.changeActorAP(monster, -SkillCollection.TAUNT_AP_LOSS, false, false); } } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/VisualEffectController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/VisualEffectController.java index 692768fa0..1b6213ac2 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/VisualEffectController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/VisualEffectController.java @@ -7,7 +7,9 @@ import android.os.Handler; import com.gpl.rpg.AndorsTrail.VisualEffectCollection; import com.gpl.rpg.AndorsTrail.VisualEffectCollection.VisualEffect; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.controller.listeners.VisualEffectFrameListeners; import com.gpl.rpg.AndorsTrail.model.actor.Monster; import com.gpl.rpg.AndorsTrail.model.actor.MonsterType; import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap; @@ -15,19 +17,25 @@ import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager; import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.util.CoordRect; import com.gpl.rpg.AndorsTrail.util.Size; -import com.gpl.rpg.AndorsTrail.view.MainView; public final class VisualEffectController { private int effectCount = 0; + private final ViewContext view; + private final WorldContext world; private final VisualEffectCollection effectTypes; - public VisualEffectController(WorldContext world) { + + public final VisualEffectFrameListeners visualEffectFrameListeners = new VisualEffectFrameListeners(); + + public VisualEffectController(ViewContext view, WorldContext world) { + this.view = view; + this.world = world; this.effectTypes = world.visualEffectTypes; } - public void startEffect(MainView mainview, Coord position, int effectID, int displayValue, VisualEffectCompletedCallback callback, int callbackValue) { + public void startEffect(Coord position, int effectID, int displayValue, VisualEffectCompletedCallback callback, int callbackValue) { ++effectCount; - (new VisualEffectAnimation(effectTypes.effects[effectID], position, mainview, displayValue, callback, callbackValue)) + (new VisualEffectAnimation(effectTypes.effects[effectID], position, displayValue, callback, callbackValue)) .start(); } @@ -53,12 +61,12 @@ public final class VisualEffectController { this.textPaint.setAlpha(255 * (effect.lastFrame - frame) / (effect.lastFrame - beginFadeAtFrame)); } area.topLeft.y = position.y - 1; - view.redrawAreaWithEffect(this, tileID, textYOffset, this.textPaint); + visualEffectFrameListeners.onNewAnimationFrame(this, tileID, textYOffset); } protected void onCompleted() { --effectCount; - view.redrawArea(area, MainView.REDRAW_AREA_EFFECT_COMPLETED); + visualEffectFrameListeners.onAnimationCompleted(this); if (callback != null) callback.onVisualEffectCompleted(callbackValue); } @@ -69,17 +77,16 @@ public final class VisualEffectController { private int currentFrame = 0; private final VisualEffect effect; - private final MainView view; public final Coord position; public final String displayText; public final CoordRect area; - private final Paint textPaint = new Paint(); + public final Paint textPaint = new Paint(); private final int beginFadeAtFrame; private final VisualEffectCompletedCallback callback; private final int callbackValue; - public VisualEffectAnimation(VisualEffect effect, Coord position, MainView view, int displayValue, VisualEffectCompletedCallback callback, int callbackValue) { + public VisualEffectAnimation(VisualEffect effect, Coord position, int displayValue, VisualEffectCompletedCallback callback, int callbackValue) { this.position = position; this.callback = callback; this.callbackValue = callbackValue; @@ -88,10 +95,9 @@ public final class VisualEffectController { this.displayText = (displayValue == 0) ? null : String.valueOf(displayValue); this.textPaint.setColor(effect.textColor); this.textPaint.setShadowLayer(2, 1, 1, Color.DKGRAY); - this.textPaint.setTextSize(view.scaledTileSize * 0.5f); // 32dp. + this.textPaint.setTextSize(world.tileManager.viewTileSize * 0.5f); // 32dp. this.textPaint.setAlpha(255); this.textPaint.setTextAlign(Align.CENTER); - this.view = view; this.beginFadeAtFrame = effect.lastFrame / 2; } } @@ -123,26 +129,27 @@ public final class VisualEffectController { } } - public static boolean updateSplatters(PredefinedMap map) { + public void updateSplatters(PredefinedMap map) { long now = System.currentTimeMillis(); - boolean hasChanges = false; for (int i = map.splatters.size() - 1; i >= 0; --i) { BloodSplatter b = map.splatters.get(i); if (b.removeAfter <= now) { map.splatters.remove(i); - hasChanges = true; + view.monsterSpawnController.monsterSpawnListeners.onSplatterRemoved(b.position); } else if (!b.reducedIcon && b.reduceIconAfter <= now) { b.reducedIcon = true; b.iconID++; - hasChanges = true; + view.monsterSpawnController.monsterSpawnListeners.onSplatterChanged(b.position); } } - return hasChanges; } - public static void addSplatter(PredefinedMap map, Monster m) { + public void addSplatter(PredefinedMap map, Monster m) { int iconID = getSplatterIconFromMonsterClass(m.getMonsterClass()); - if (iconID > 0) map.splatters.add(new BloodSplatter(iconID, m.position)); + if (iconID > 0) { + map.splatters.add(new BloodSplatter(iconID, m.position)); + view.monsterSpawnController.monsterSpawnListeners.onSplatterAdded(m.position); + } } private static int getSplatterIconFromMonsterClass(int monsterClass) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListener.java new file mode 100644 index 000000000..dadc26ef2 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListener.java @@ -0,0 +1,15 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.AttackResult; +import com.gpl.rpg.AndorsTrail.model.actor.Monster; + +public interface CombatActionListener { + void onPlayerAttackMissed(Monster target, AttackResult attackResult); + void onPlayerAttackSuccess(Monster target, AttackResult attackResult); + void onMonsterAttackMissed(Monster attacker, AttackResult attackResult); + void onMonsterAttackSuccess(Monster attacker, AttackResult attackResult); + void onPlayerKilledMonster(Monster target); + void onPlayerStartedFleeing(); + void onPlayerFailedFleeing(); + void onPlayerDoesNotHaveEnoughAP(); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListeners.java new file mode 100644 index 000000000..c178b70e0 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListeners.java @@ -0,0 +1,80 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.AttackResult; +import com.gpl.rpg.AndorsTrail.model.actor.Monster; +import com.gpl.rpg.AndorsTrail.model.listeners.ListOfListeners; + +public class CombatActionListeners extends ListOfListeners implements CombatActionListener { + + private final Function2 onPlayerAttackMissed = new Function2() { + @Override public void call(CombatActionListener listener, Monster target, AttackResult attackResult) { listener.onPlayerAttackMissed(target, attackResult); } + }; + + private final Function2 onPlayerAttackSuccess = new Function2() { + @Override public void call(CombatActionListener listener, Monster target, AttackResult attackResult) { listener.onPlayerAttackSuccess(target, attackResult); } + }; + + private final Function2 onMonsterAttackMissed = new Function2() { + @Override public void call(CombatActionListener listener, Monster attacker, AttackResult attackResult) { listener.onMonsterAttackMissed(attacker, attackResult); } + }; + + private final Function2 onMonsterAttackSuccess = new Function2() { + @Override public void call(CombatActionListener listener, Monster attacker, AttackResult attackResult) { listener.onMonsterAttackSuccess(attacker, attackResult); } + }; + + private final Function1 onPlayerKilledMonster = new Function1() { + @Override public void call(CombatActionListener listener, Monster target) { listener.onPlayerKilledMonster(target); } + }; + + private final Function onPlayerStartedFleeing = new Function() { + @Override public void call(CombatActionListener listener) { listener.onPlayerStartedFleeing(); } + }; + + private final Function onPlayerFailedFleeing = new Function() { + @Override public void call(CombatActionListener listener) { listener.onPlayerFailedFleeing(); } + }; + + private final Function onPlayerDoesNotHaveEnoughAP = new Function() { + @Override public void call(CombatActionListener listener) { listener.onPlayerDoesNotHaveEnoughAP(); } + }; + + @Override + public void onPlayerAttackMissed(Monster target, AttackResult attackResult) { + callAllListeners(this.onPlayerAttackMissed, target, attackResult); + } + + @Override + public void onPlayerAttackSuccess(Monster target, AttackResult attackResult) { + callAllListeners(this.onPlayerAttackSuccess, target, attackResult); + } + + @Override + public void onMonsterAttackMissed(Monster attacker, AttackResult attackResult) { + callAllListeners(this.onMonsterAttackMissed, attacker, attackResult); + } + + @Override + public void onMonsterAttackSuccess(Monster attacker, AttackResult attackResult) { + callAllListeners(this.onMonsterAttackSuccess, attacker, attackResult); + } + + @Override + public void onPlayerKilledMonster(Monster target) { + callAllListeners(this.onPlayerKilledMonster, target); + } + + @Override + public void onPlayerStartedFleeing() { + callAllListeners(this.onPlayerStartedFleeing); + } + + @Override + public void onPlayerFailedFleeing() { + callAllListeners(this.onPlayerFailedFleeing); + } + + @Override + public void onPlayerDoesNotHaveEnoughAP() { + callAllListeners(this.onPlayerDoesNotHaveEnoughAP); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatSelectionListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatSelectionListener.java new file mode 100644 index 000000000..740ce25af --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatSelectionListener.java @@ -0,0 +1,10 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Monster; +import com.gpl.rpg.AndorsTrail.util.Coord; + +public interface CombatSelectionListener { + void onMonsterSelected(Monster m, Coord selectedPosition, Coord previousSelection); + void onMovementDestinationSelected(Coord selectedPosition, Coord previousSelection); + void onCombatSelectionCleared(Coord previousSelection); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatSelectionListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatSelectionListeners.java new file mode 100644 index 000000000..d2121bbe8 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatSelectionListeners.java @@ -0,0 +1,35 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Monster; +import com.gpl.rpg.AndorsTrail.model.listeners.ListOfListeners; +import com.gpl.rpg.AndorsTrail.util.Coord; + +public class CombatSelectionListeners extends ListOfListeners implements CombatSelectionListener { + + private final Function3 onMonsterSelected = new Function3() { + @Override public void call(CombatSelectionListener listener, Monster monster, Coord selectedPosition, Coord previousSelection) { listener.onMonsterSelected(monster, selectedPosition, previousSelection); } + }; + + private final Function2 onMovementDestinationSelected = new Function2() { + @Override public void call(CombatSelectionListener listener, Coord selectedPosition, Coord previousSelection) { listener.onMovementDestinationSelected(selectedPosition, previousSelection); } + }; + + private final Function1 onCombatSelectionCleared = new Function1() { + @Override public void call(CombatSelectionListener listener, Coord previousSelection) { listener.onCombatSelectionCleared(previousSelection); } + }; + + @Override + public void onMonsterSelected(Monster m, Coord selectedPosition, Coord previousSelection) { + callAllListeners(this.onMonsterSelected, m, selectedPosition, previousSelection); + } + + @Override + public void onMovementDestinationSelected(Coord selectedPosition, Coord previousSelection) { + callAllListeners(this.onMovementDestinationSelected, selectedPosition, previousSelection); + } + + @Override + public void onCombatSelectionCleared(Coord previousSelection) { + callAllListeners(this.onCombatSelectionCleared, previousSelection); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatTurnListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatTurnListener.java new file mode 100644 index 000000000..a24964184 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatTurnListener.java @@ -0,0 +1,10 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Monster; + +public interface CombatTurnListener { + void onCombatStarted(); + void onCombatEnded(); + void onNewPlayerTurn(); + void onMonsterIsAttacking(Monster m); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatTurnListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatTurnListeners.java new file mode 100644 index 000000000..a6e7af4b2 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatTurnListeners.java @@ -0,0 +1,43 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Monster; +import com.gpl.rpg.AndorsTrail.model.listeners.ListOfListeners; + +public class CombatTurnListeners extends ListOfListeners implements CombatTurnListener { + + private final Function onCombatStarted = new Function() { + @Override public void call(CombatTurnListener listener) { listener.onCombatStarted(); } + }; + + private final Function onCombatEnded = new Function() { + @Override public void call(CombatTurnListener listener) { listener.onCombatEnded(); } + }; + + private final Function onNewPlayerTurn = new Function() { + @Override public void call(CombatTurnListener listener) { listener.onNewPlayerTurn(); } + }; + + private final Function1 onMonsterIsAttacking = new Function1() { + @Override public void call(CombatTurnListener listener, Monster m) { listener.onMonsterIsAttacking(m); } + }; + + @Override + public void onCombatStarted() { + callAllListeners(this.onCombatStarted); + } + + @Override + public void onCombatEnded() { + callAllListeners(this.onCombatEnded); + } + + @Override + public void onNewPlayerTurn() { + callAllListeners(this.onNewPlayerTurn); + } + + @Override + public void onMonsterIsAttacking(Monster m) { + callAllListeners(this.onMonsterIsAttacking, m); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/LootBagListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/LootBagListener.java new file mode 100644 index 000000000..d142258c3 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/LootBagListener.java @@ -0,0 +1,8 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.util.Coord; + +public interface LootBagListener { + void onLootBagCreated(Coord p); + void onLootBagRemoved(Coord p); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/LootBagListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/LootBagListeners.java new file mode 100644 index 000000000..e67d8e5d6 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/LootBagListeners.java @@ -0,0 +1,25 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.listeners.ListOfListeners; +import com.gpl.rpg.AndorsTrail.util.Coord; + +public class LootBagListeners extends ListOfListeners implements LootBagListener { + + private final Function1 onLootBagCreated = new Function1() { + @Override public void call(LootBagListener listener, Coord p) { listener.onLootBagCreated(p); } + }; + + private final Function1 onLootBagRemoved = new Function1() { + @Override public void call(LootBagListener listener, Coord p) { listener.onLootBagRemoved(p); } + }; + + @Override + public void onLootBagCreated(Coord p) { + callAllListeners(this.onLootBagCreated, p); + } + + @Override + public void onLootBagRemoved(Coord p) { + callAllListeners(this.onLootBagRemoved, p); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterMovementListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterMovementListener.java new file mode 100644 index 000000000..82f0189db --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterMovementListener.java @@ -0,0 +1,9 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Monster; +import com.gpl.rpg.AndorsTrail.util.CoordRect; + +public interface MonsterMovementListener { + void onMonsterSteppedOnPlayer(Monster m); + void onMonsterMoved(Monster m, CoordRect previousPosition); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterMovementListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterMovementListeners.java new file mode 100644 index 000000000..7f26bd32f --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterMovementListeners.java @@ -0,0 +1,26 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Monster; +import com.gpl.rpg.AndorsTrail.model.listeners.ListOfListeners; +import com.gpl.rpg.AndorsTrail.util.CoordRect; + +public class MonsterMovementListeners extends ListOfListeners implements MonsterMovementListener { + + private final Function1 onMonsterSteppedOnPlayer = new Function1() { + @Override public void call(MonsterMovementListener listener, Monster monster) { listener.onMonsterSteppedOnPlayer(monster); } + }; + + private final Function2 onMonsterMoved = new Function2() { + @Override public void call(MonsterMovementListener listener, Monster monster, CoordRect previousPosition) { listener.onMonsterMoved(monster, previousPosition); } + }; + + @Override + public void onMonsterSteppedOnPlayer(Monster m) { + callAllListeners(this.onMonsterSteppedOnPlayer, m); + } + + @Override + public void onMonsterMoved(Monster m, CoordRect previousPosition) { + callAllListeners(this.onMonsterMoved, m, previousPosition); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterSpawnListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterSpawnListener.java new file mode 100644 index 000000000..dff18a8f4 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterSpawnListener.java @@ -0,0 +1,13 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Monster; +import com.gpl.rpg.AndorsTrail.util.Coord; +import com.gpl.rpg.AndorsTrail.util.CoordRect; + +public interface MonsterSpawnListener { + void onMonsterSpawned(Monster m); + void onMonsterRemoved(Monster m, CoordRect previousPosition); + void onSplatterAdded(Coord p); + void onSplatterChanged(Coord p); + void onSplatterRemoved(Coord p); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterSpawnListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterSpawnListeners.java new file mode 100644 index 000000000..9277402d4 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/MonsterSpawnListeners.java @@ -0,0 +1,54 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Monster; +import com.gpl.rpg.AndorsTrail.model.listeners.ListOfListeners; +import com.gpl.rpg.AndorsTrail.util.Coord; +import com.gpl.rpg.AndorsTrail.util.CoordRect; + +public class MonsterSpawnListeners extends ListOfListeners implements MonsterSpawnListener { + + private final Function1 onMonsterSpawned = new Function1() { + @Override public void call(MonsterSpawnListener listener, Monster monster) { listener.onMonsterSpawned(monster); } + }; + + private final Function2 onMonsterRemoved = new Function2() { + @Override public void call(MonsterSpawnListener listener, Monster monster, CoordRect previousPosition) { listener.onMonsterRemoved(monster, previousPosition); } + }; + + private final Function1 onSplatterAdded = new Function1() { + @Override public void call(MonsterSpawnListener listener, Coord p) { listener.onSplatterAdded(p); } + }; + + private final Function1 onSplatterChanged = new Function1() { + @Override public void call(MonsterSpawnListener listener, Coord p) { listener.onSplatterChanged(p); } + }; + + private final Function1 onSplatterRemoved = new Function1() { + @Override public void call(MonsterSpawnListener listener, Coord p) { listener.onSplatterRemoved(p); } + }; + + @Override + public void onMonsterSpawned(Monster m) { + callAllListeners(this.onMonsterSpawned, m); + } + + @Override + public void onMonsterRemoved(Monster m, CoordRect previousPosition) { + callAllListeners(this.onMonsterRemoved, m, previousPosition); + } + + @Override + public void onSplatterAdded(Coord p) { + callAllListeners(this.onSplatterAdded, p); + } + + @Override + public void onSplatterChanged(Coord p) { + callAllListeners(this.onSplatterChanged, p); + } + + @Override + public void onSplatterRemoved(Coord p) { + callAllListeners(this.onSplatterRemoved, p); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerMovementListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerMovementListener.java new file mode 100644 index 000000000..ffa475d5d --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerMovementListener.java @@ -0,0 +1,9 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap; +import com.gpl.rpg.AndorsTrail.util.Coord; + +public interface PlayerMovementListener { + void onPlayerMoved(Coord newPosition, Coord previousPosition); + void onPlayerEnteredNewMap(PredefinedMap map, Coord p); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerMovementListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerMovementListeners.java new file mode 100644 index 000000000..a8c09fe49 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerMovementListeners.java @@ -0,0 +1,26 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.listeners.ListOfListeners; +import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap; +import com.gpl.rpg.AndorsTrail.util.Coord; + +public class PlayerMovementListeners extends ListOfListeners implements PlayerMovementListener { + + private final Function2 onPlayerMoved = new Function2() { + @Override public void call(PlayerMovementListener listener, Coord newPosition, Coord previousPosition) { listener.onPlayerMoved(newPosition, previousPosition); } + }; + + private final Function2 onPlayerEnteredNewMap = new Function2() { + @Override public void call(PlayerMovementListener listener, PredefinedMap map, Coord p) { listener.onPlayerEnteredNewMap(map, p); } + }; + + @Override + public void onPlayerMoved(Coord newPosition, Coord previousPosition) { + callAllListeners(this.onPlayerMoved, newPosition, previousPosition); + } + + @Override + public void onPlayerEnteredNewMap(PredefinedMap map, Coord p) { + callAllListeners(this.onPlayerEnteredNewMap, map, p); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerStatsListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerStatsListener.java new file mode 100644 index 000000000..7f8942ceb --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerStatsListener.java @@ -0,0 +1,7 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Player; + +public interface PlayerStatsListener { + void onPlayerExperienceChanged(Player p); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerStatsListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerStatsListeners.java new file mode 100644 index 000000000..ebb474b63 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/PlayerStatsListeners.java @@ -0,0 +1,16 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Player; +import com.gpl.rpg.AndorsTrail.model.listeners.ListOfListeners; + +public class PlayerStatsListeners extends ListOfListeners implements PlayerStatsListener { + + private final Function1 onPlayerExperienceChanged = new Function1() { + @Override public void call(PlayerStatsListener listener, Player p) { listener.onPlayerExperienceChanged(p); } + }; + + @Override + public void onPlayerExperienceChanged(Player p) { + callAllListeners(this.onPlayerExperienceChanged, p); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/QuickSlotListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/QuickSlotListener.java new file mode 100644 index 000000000..0ce5b14e4 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/QuickSlotListener.java @@ -0,0 +1,6 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +public interface QuickSlotListener { + void onQuickSlotChanged(int slotId); + void onQuickSlotUsed(int slotId); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/QuickSlotListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/QuickSlotListeners.java new file mode 100644 index 000000000..039bf15f0 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/QuickSlotListeners.java @@ -0,0 +1,24 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.listeners.ListOfListeners; + +public class QuickSlotListeners extends ListOfListeners implements QuickSlotListener { + + private final Function1 onQuickSlotChanged = new Function1() { + @Override public void call(QuickSlotListener listener, Integer slotId) { listener.onQuickSlotChanged(slotId); } + }; + + private final Function1 onQuickSlotUsed = new Function1() { + @Override public void call(QuickSlotListener listener, Integer slotId) { listener.onQuickSlotUsed(slotId); } + }; + + @Override + public void onQuickSlotChanged(int slotId) { + callAllListeners(this.onQuickSlotChanged, slotId); + } + + @Override + public void onQuickSlotUsed(int slotId) { + callAllListeners(this.onQuickSlotUsed, slotId); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/VisualEffectFrameListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/VisualEffectFrameListener.java new file mode 100644 index 000000000..4fb6a7d96 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/VisualEffectFrameListener.java @@ -0,0 +1,8 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAnimation; + +public interface VisualEffectFrameListener { + void onNewAnimationFrame(VisualEffectAnimation animation, int tileID, int textYOffset); + void onAnimationCompleted(VisualEffectAnimation animation); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/VisualEffectFrameListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/VisualEffectFrameListeners.java new file mode 100644 index 000000000..61dbe3595 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/VisualEffectFrameListeners.java @@ -0,0 +1,25 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAnimation; +import com.gpl.rpg.AndorsTrail.model.listeners.ListOfListeners; + +public class VisualEffectFrameListeners extends ListOfListeners implements VisualEffectFrameListener { + + private final Function3 onNewAnimationFrame = new Function3() { + @Override public void call(VisualEffectFrameListener listener, VisualEffectAnimation animation, Integer tileID, Integer textYOffset) { listener.onNewAnimationFrame(animation, tileID, textYOffset); } + }; + + private final Function1 onAnimationCompleted = new Function1() { + @Override public void call(VisualEffectFrameListener listener, VisualEffectAnimation animation) { listener.onAnimationCompleted(animation); } + }; + + @Override + public void onNewAnimationFrame(VisualEffectAnimation animation, int tileID, int textYOffset) { + callAllListeners(this.onNewAnimationFrame, animation, tileID, textYOffset); + } + + @Override + public void onAnimationCompleted(VisualEffectAnimation animation) { + callAllListeners(this.onAnimationCompleted, animation); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/WorldEventListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/WorldEventListener.java new file mode 100644 index 000000000..7c6be2dda --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/WorldEventListener.java @@ -0,0 +1,19 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Monster; +import com.gpl.rpg.AndorsTrail.model.item.Loot; +import com.gpl.rpg.AndorsTrail.model.map.MapObject; + +public interface WorldEventListener { + void onPlayerStartedConversation(Monster m, String phraseID); + void onPlayerSteppedOnMonster(Monster m); + void onPlayerSteppedOnMapSignArea(MapObject area); + void onPlayerSteppedOnKeyArea(MapObject area); + void onPlayerSteppedOnRestArea(MapObject area); + void onPlayerSteppedOnGroundLoot(Loot loot); + void onPlayerPickedUpGroundLoot(Loot loot); + void onPlayerFoundMonsterLoot(Iterable loot, int exp); + void onPlayerPickedUpMonsterLoot(Iterable loot, int exp); + void onPlayerRested(); + void onPlayerDied(int lostExp); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/WorldEventListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/WorldEventListeners.java new file mode 100644 index 000000000..f951c6e54 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/WorldEventListeners.java @@ -0,0 +1,108 @@ +package com.gpl.rpg.AndorsTrail.controller.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Monster; +import com.gpl.rpg.AndorsTrail.model.item.Loot; +import com.gpl.rpg.AndorsTrail.model.listeners.ListOfListeners; +import com.gpl.rpg.AndorsTrail.model.map.MapObject; + +public class WorldEventListeners extends ListOfListeners implements WorldEventListener { + + private final Function2 onPlayerStartedConversation = new Function2() { + @Override public void call(WorldEventListener listener, Monster m, String phraseID) { listener.onPlayerStartedConversation(m, phraseID); } + }; + + private final Function1 onPlayerSteppedOnMonster = new Function1() { + @Override public void call(WorldEventListener listener, Monster m) { listener.onPlayerSteppedOnMonster(m); } + }; + + private final Function1 onPlayerSteppedOnMapSignArea = new Function1() { + @Override public void call(WorldEventListener listener, MapObject area) { listener.onPlayerSteppedOnMapSignArea(area); } + }; + + private final Function1 onPlayerSteppedOnKeyArea = new Function1() { + @Override public void call(WorldEventListener listener, MapObject area) { listener.onPlayerSteppedOnKeyArea(area); } + }; + + private final Function1 onPlayerSteppedOnRestArea = new Function1() { + @Override public void call(WorldEventListener listener, MapObject area) { listener.onPlayerSteppedOnRestArea(area); } + }; + + private final Function1 onPlayerSteppedOnGroundLoot = new Function1() { + @Override public void call(WorldEventListener listener, Loot loot) { listener.onPlayerSteppedOnGroundLoot(loot); } + }; + + private final Function1 onPlayerPickedUpGroundLoot = new Function1() { + @Override public void call(WorldEventListener listener, Loot loot) { listener.onPlayerPickedUpGroundLoot(loot); } + }; + + private final Function2, Integer> onPlayerFoundMonsterLoot = new Function2, Integer>() { + @Override public void call(WorldEventListener listener, Iterable loot, Integer exp) { listener.onPlayerFoundMonsterLoot(loot, exp); } + }; + + private final Function2, Integer> onPlayerPickedUpMonsterLoot = new Function2, Integer>() { + @Override public void call(WorldEventListener listener, Iterable loot, Integer exp) { listener.onPlayerPickedUpMonsterLoot(loot, exp); } + }; + + private final Function onPlayerRested = new Function() { + @Override public void call(WorldEventListener listener) { listener.onPlayerRested(); } + }; + + private final Function1 onPlayerDied = new Function1() { + @Override public void call(WorldEventListener listener, Integer lostExp) { listener.onPlayerDied(lostExp); } + }; + + @Override + public void onPlayerStartedConversation(Monster m, String phraseID) { + callAllListeners(this.onPlayerStartedConversation, m, phraseID); + } + + @Override + public void onPlayerSteppedOnMonster(Monster m) { + callAllListeners(this.onPlayerSteppedOnMonster, m); + } + + @Override + public void onPlayerSteppedOnMapSignArea(MapObject area) { + callAllListeners(this.onPlayerSteppedOnMapSignArea, area); + } + + @Override + public void onPlayerSteppedOnKeyArea(MapObject area) { + callAllListeners(this.onPlayerSteppedOnKeyArea, area); + } + + @Override + public void onPlayerSteppedOnRestArea(MapObject area) { + callAllListeners(this.onPlayerSteppedOnRestArea, area); + } + + @Override + public void onPlayerSteppedOnGroundLoot(Loot loot) { + callAllListeners(this.onPlayerSteppedOnGroundLoot, loot); + } + + @Override + public void onPlayerPickedUpGroundLoot(Loot loot) { + callAllListeners(this.onPlayerPickedUpGroundLoot, loot); + } + + @Override + public void onPlayerFoundMonsterLoot(Iterable loot, int exp) { + callAllListeners(this.onPlayerFoundMonsterLoot, loot, exp); + } + + @Override + public void onPlayerPickedUpMonsterLoot(Iterable loot, int exp) { + callAllListeners(this.onPlayerPickedUpMonsterLoot, loot, exp); + } + + @Override + public void onPlayerRested() { + callAllListeners(this.onPlayerRested); + } + + @Override + public void onPlayerDied(int lostExp) { + callAllListeners(this.onPlayerDied, lostExp); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ModelContainer.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ModelContainer.java index 351c8ae36..58d6ab4a8 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ModelContainer.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ModelContainer.java @@ -4,6 +4,7 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.model.map.LayeredTileMap; @@ -25,8 +26,8 @@ public final class ModelContainer { // ====== PARCELABLE =================================================================== - public ModelContainer(DataInputStream src, WorldContext world, int fileversion) throws IOException { - this.player = Player.readFromParcel(src, world, fileversion); + public ModelContainer(DataInputStream src, WorldContext world, ViewContext view, int fileversion) throws IOException { + this.player = Player.readFromParcel(src, world, view, fileversion); this.currentMap = world.maps.findPredefinedMap(src.readUTF()); this.uiSelections = new InterfaceData(src, world, fileversion); if (uiSelections.selectedPosition != null) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java index ee39db03c..25e06f50d 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java @@ -8,7 +8,6 @@ import android.util.FloatMath; import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; -import com.gpl.rpg.AndorsTrail.model.listeners.ActorConditionListeners; import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.util.CoordRect; import com.gpl.rpg.AndorsTrail.util.Range; @@ -27,7 +26,6 @@ public class Actor { public final Range ap = new Range(); public final Range health = new Range(); public final ArrayList conditions = new ArrayList(); - public final ActorConditionListeners conditionListener = new ActorConditionListeners(); public int moveCost; public int attackCost; public int attackChance; @@ -47,7 +45,9 @@ public class Actor { public boolean isImmuneToCriticalHits() { return isImmuneToCriticalHits; } public String getName() { return name; } + public int getCurrentAP() { return ap.current; } public int getMaxAP() { return ap.max; } + public int getCurrentHP() { return health.current; } public int getMaxHP() { return health.max; } public int getMoveCost() { return moveCost; } public int getAttackCost() { return attackCost; } @@ -76,18 +76,7 @@ public class Actor { public boolean isDead() { return health.current <= 0; } - public void setMaxAP() { - ap.setMax(); - } - public void setMaxHP() { - health.setMax(); - } - public boolean useAPs(int cost) { - if (ap.current < cost) return false; - ap.subtract(cost, false); - return true; - } public boolean hasAPs(int cost) { return ap.current >= cost; } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java index dd690f385..ece742a52 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java @@ -32,8 +32,8 @@ public final class Monster extends Actor { this.iconID = monsterType.iconID; this.nextPosition = new CoordRect(new Coord(), monsterType.tileSize); resetStatsToBaseTraits(); - setMaxAP(); - setMaxHP(); + this.ap.setMax(); + this.health.setMax(); } public void resetStatsToBaseTraits() { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Player.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Player.java index 855636756..b299c9c63 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Player.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Player.java @@ -11,8 +11,8 @@ import android.util.FloatMath; import android.util.SparseIntArray; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.controller.ActorStatsController; import com.gpl.rpg.AndorsTrail.controller.Constants; import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; import com.gpl.rpg.AndorsTrail.model.item.DropListCollection; @@ -48,13 +48,13 @@ public final class Player extends Actor { public final PlayerBaseTraits baseTraits = new PlayerBaseTraits(); public final Range levelExperience; // ranges from 0 to the delta-amount of exp required for next level public final Inventory inventory; + public final SparseIntArray skillLevels = new SparseIntArray(); public int availableSkillIncreases = 0; public int useItemCost; public int reequipCost; + public int totalExperience; - private int totalExperience; private final HashMap > questProgress = new HashMap >(); - private final SparseIntArray skillLevels = new SparseIntArray(); private String spawnMap; private String spawnPlace; private final HashMap alignments = new HashMap(); @@ -141,8 +141,6 @@ public final class Player extends Actor { this.spawnMap = "home"; this.spawnPlace = "rest"; } - - ActorStatsController.recalculatePlayerStats(this); } public boolean hasExactQuestProgress(QuestProgress progress) { return hasExactQuestProgress(progress.questID, progress.progress); } @@ -164,10 +162,6 @@ public final class Player extends Actor { int experienceRequiredToReachThisLevel = getRequiredExperience(level); levelExperience.set(getRequiredExperienceForNextLevel(level), totalExperience - experienceRequiredToReachThisLevel); } - public void addExperience(int v) { - totalExperience += v; - levelExperience.add(v, true); - } private static int getRequiredExperience(int currentLevel) { int v = 0; @@ -193,10 +187,6 @@ public final class Player extends Actor { public boolean hasSkill(int skillID) { return getSkillLevel(skillID) > 0; } - public void addSkillLevel(int skillID) { - skillLevels.put(skillID, skillLevels.get(skillID) + 1); - ActorStatsController.recalculatePlayerStats(this); - } public boolean nextLevelAddsNewSkillpoint() { return thisLevelAddsNewSkillpoint(level + 1); } @@ -231,6 +221,8 @@ public final class Player extends Actor { public int getAvailableSkillIncreases() { return availableSkillIncreases; } public int getLevel() { return level; } public int getTotalExperience() { return totalExperience; } + public int getCurrentLevelExperience() { return levelExperience.current; } + public int getMaxLevelExperience() { return levelExperience.max; } public int getGold() { return inventory.gold; } public String getSpawnMap() { return spawnMap; } public String getSpawnPlace() { return spawnPlace; } @@ -261,9 +253,9 @@ public final class Player extends Actor { // ====== PARCELABLE =================================================================== - public static Player readFromParcel(DataInputStream src, WorldContext world, int fileversion) throws IOException { + public static Player readFromParcel(DataInputStream src, WorldContext world, ViewContext view, int fileversion) throws IOException { Player player = new Player(src, world, fileversion); - LegacySavegameFormatReaderForPlayer.upgradeSavegame(player, world, fileversion); + LegacySavegameFormatReaderForPlayer.upgradeSavegame(player, world, view, fileversion); return player; } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Loot.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Loot.java index 6951758af..31f26e3df 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Loot.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Loot.java @@ -37,7 +37,18 @@ public final class Loot { } public boolean hasItems() { return gold != 0 || !items.isEmpty(); + } + public boolean isContainer() { + return !isVisible; } + public static Loot combine(Iterable loot) { + Loot result = new Loot(); + for (Loot l : loot) { + result.add(l); + } + return result; + } + public void clear() { exp = 0; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorStatsListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorStatsListener.java new file mode 100644 index 000000000..a1cc6befa --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorStatsListener.java @@ -0,0 +1,10 @@ +package com.gpl.rpg.AndorsTrail.model.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Actor; + +public interface ActorStatsListener { + void onActorHealthChanged(Actor actor); + void onActorAPChanged(Actor actor); + void onActorAttackCostChanged(Actor actor, int newAttackCost); + void onActorMoveCostChanged(Actor actor, int newMoveCost); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorStatsListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorStatsListeners.java new file mode 100644 index 000000000..30508bcd6 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorStatsListeners.java @@ -0,0 +1,43 @@ +package com.gpl.rpg.AndorsTrail.model.listeners; + +import com.gpl.rpg.AndorsTrail.model.actor.Actor; +import com.gpl.rpg.AndorsTrail.model.listeners.ListOfListeners; + +public class ActorStatsListeners extends ListOfListeners implements ActorStatsListener { + + private final Function1 onActorHealthChanged = new Function1() { + @Override public void call(ActorStatsListener listener, Actor actor) { listener.onActorHealthChanged(actor); } + }; + + private final Function1 onActorAPChanged = new Function1() { + @Override public void call(ActorStatsListener listener, Actor actor) { listener.onActorAPChanged(actor); } + }; + + private final Function2 onActorAttackCostChanged = new Function2() { + @Override public void call(ActorStatsListener listener, Actor actor, Integer newAttackCost) { listener.onActorAttackCostChanged(actor, newAttackCost); } + }; + + private final Function2 onActorMoveCostChanged = new Function2() { + @Override public void call(ActorStatsListener listener, Actor actor, Integer newMoveCost) { listener.onActorMoveCostChanged(actor, newMoveCost); } + }; + + @Override + public void onActorHealthChanged(Actor actor) { + callAllListeners(this.onActorHealthChanged, actor); + } + + @Override + public void onActorAPChanged(Actor actor) { + callAllListeners(this.onActorAPChanged, actor); + } + + @Override + public void onActorAttackCostChanged(Actor actor, int newAttackCost) { + callAllListeners(this.onActorAttackCostChanged, actor, newAttackCost); + } + + @Override + public void onActorMoveCostChanged(Actor actor, int newMoveCost) { + callAllListeners(this.onActorMoveCostChanged, actor, newMoveCost); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java index c968e3e46..7ef8b64bd 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java @@ -48,6 +48,13 @@ public class ListOfListeners { else e.call(listener, arg1, arg2); } } + protected void callAllListeners(Function3 e, Arg1 arg1, Arg2 arg2, Arg3 arg3) { + for (int i = listeners.size()-1; i >= 0; --i) { + T listener = listeners.get(i).get(); + if (listener == null) listeners.remove(i); + else e.call(listener, arg1, arg2, arg3); + } + } protected static interface Function { public void call(Listener listener); @@ -58,4 +65,7 @@ public class ListOfListeners { protected static interface Function2 { public void call(Listener listener, Arg1 arg1, Arg2 arg2); } + protected static interface Function3 { + public void call(Listener listener, Arg1 arg1, Arg2 arg2, Arg3 arg3); + } } \ No newline at end of file diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapCollection.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapCollection.java index 95a2dc4a8..8630417c2 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapCollection.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MapCollection.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.HashMap; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.util.L; @@ -42,12 +43,12 @@ public final class MapCollection { // ====== PARCELABLE =================================================================== - public void readFromParcel(DataInputStream src, WorldContext world, int fileversion) throws IOException { + public void readFromParcel(DataInputStream src, WorldContext world, ViewContext view, int fileversion) throws IOException { int size; if (fileversion == 5) size = 11; else size = src.readInt(); for(int i = 0; i < size; ++i) { - predefinedMaps.get(i).readFromParcel(src, world, fileversion); + predefinedMaps.get(i).readFromParcel(src, world, view, fileversion); if (i >= 40) { if (fileversion < 15) predefinedMaps.get(i).visited = false; } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MonsterSpawnArea.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MonsterSpawnArea.java index e6a600c62..0d7100e59 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MonsterSpawnArea.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MonsterSpawnArea.java @@ -6,7 +6,6 @@ import java.io.IOException; import java.util.ArrayList; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.controller.ActorStatsController; import com.gpl.rpg.AndorsTrail.controller.Constants; import com.gpl.rpg.AndorsTrail.model.actor.Monster; import com.gpl.rpg.AndorsTrail.model.actor.MonsterType; @@ -44,12 +43,6 @@ public final class MonsterSpawnArea { return null; } - public void healAllMonsters() { - for (Monster m : monsters) { - ActorStatsController.removeAllTemporaryConditions(m); - m.setMaxHP(); - } - } public void spawn(Coord p, WorldContext context) { final String monsterTypeID = monsterTypeIDs[Constants.rnd.nextInt(monsterTypeIDs.length)]; spawn(p, monsterTypeID, context); @@ -61,11 +54,12 @@ public final class MonsterSpawnArea { public void spawn(Coord p, String monsterTypeID, WorldContext context) { spawn(p, context.monsterTypes.getMonsterType(monsterTypeID)); } - public void spawn(Coord p, MonsterType type) { + public Monster spawn(Coord p, MonsterType type) { Monster m = new Monster(type); m.position.set(p); monsters.add(m); quantity.current++; + return m; } public void remove(Monster m) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/PredefinedMap.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/PredefinedMap.java index 50982e0ae..0a884d195 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/PredefinedMap.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/PredefinedMap.java @@ -6,11 +6,11 @@ import java.io.IOException; import java.util.ArrayList; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.Constants; import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.BloodSplatter; import com.gpl.rpg.AndorsTrail.model.actor.Monster; -import com.gpl.rpg.AndorsTrail.model.actor.MonsterType; import com.gpl.rpg.AndorsTrail.model.item.ItemType; import com.gpl.rpg.AndorsTrail.model.item.Loot; import com.gpl.rpg.AndorsTrail.util.Coord; @@ -121,69 +121,6 @@ public final class PredefinedMap { return null; } - private boolean spawnInArea(MonsterSpawnArea a, WorldContext context, Coord playerPosition) { - return spawnInArea(a, a.getRandomMonsterType(context), playerPosition); - } - public boolean TEST_spawnInArea(MonsterSpawnArea a, MonsterType type) { return spawnInArea(a, type, null); } - private boolean spawnInArea(MonsterSpawnArea a, MonsterType type, Coord playerPosition) { - Coord p = getRandomFreePosition(a.area, type.tileSize, playerPosition); - if (p == null) return false; - a.spawn(p, type); - return true; - } - - public Coord getRandomFreePosition(CoordRect area, Size requiredSize, Coord playerPosition) { - CoordRect p = new CoordRect(requiredSize); - for(int i = 0; i < 100; ++i) { - p.topLeft.set( - area.topLeft.x + Constants.rnd.nextInt(area.size.width) - ,area.topLeft.y + Constants.rnd.nextInt(area.size.height)); - if (!monsterCanMoveTo(p)) continue; - if (playerPosition != null && p.contains(playerPosition)) continue; - return p.topLeft; - } - return null; // Couldn't find a free spot. - } - - public boolean monsterCanMoveTo(final CoordRect p) { - if (!isWalkable(p)) return false; - if (getMonsterAt(p) != null) return false; - MapObject m = getEventObjectAt(p.topLeft); - if (m != null) { - if (m.type == MapObject.MAPEVENT_NEWMAP) return false; - } - return true; - } - - public void spawnAll(WorldContext world) { - boolean respawnUniqueMonsters = false; - if (!visited) respawnUniqueMonsters = true; - for (MonsterSpawnArea a : spawnAreas) { - spawnAllInArea(world, a, respawnUniqueMonsters); - } - } - private void spawnAllInArea(WorldContext world, MonsterSpawnArea area, boolean respawnUniqueMonsters) { - while (area.isSpawnable(respawnUniqueMonsters)) { - final boolean wasAbleToSpawn = spawnInArea(area, world, null); - if (!wasAbleToSpawn) break; - } - area.healAllMonsters(); - } - public boolean maybeSpawn(WorldContext world) { - boolean hasSpawned = false; - for (MonsterSpawnArea a : spawnAreas) { - if (!a.isSpawnable(false)) continue; - if (!a.rollShouldSpawn()) continue; - if (spawnInArea(a, world, world.model.player.position)) hasSpawned = true; - } - return hasSpawned; - } - - public void remove(Monster m) { - for (MonsterSpawnArea a : spawnAreas) { - a.remove(m); - } - } public Loot getBagAt(final Coord p) { for (Loot l : groundBags) { if (l.position.equals(p)) return l; @@ -255,7 +192,7 @@ public final class PredefinedMap { // ====== PARCELABLE =================================================================== - public void readFromParcel(DataInputStream src, WorldContext world, int fileversion) throws IOException { + public void readFromParcel(DataInputStream src, WorldContext world, ViewContext view, int fileversion) throws IOException { final int loadedSpawnAreas = src.readInt(); for(int i = 0; i < loadedSpawnAreas; ++i) { this.spawnAreas[i].readFromParcel(src, world, fileversion); @@ -289,7 +226,7 @@ public final class PredefinedMap { for(int i = loadedSpawnAreas; i < spawnAreas.length; ++i) { MonsterSpawnArea area = this.spawnAreas[i]; - if (area.isUnique && visited) spawnAllInArea(world, area, true); + if (area.isUnique && visited) view.monsterSpawnController.spawnAllInArea(this, area, true); else area.reset(); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForPlayer.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForPlayer.java index 00a1c9dc9..32a0cfea0 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForPlayer.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForPlayer.java @@ -5,8 +5,8 @@ import java.io.IOException; import android.util.FloatMath; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.controller.ActorStatsController; import com.gpl.rpg.AndorsTrail.controller.Constants; import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; import com.gpl.rpg.AndorsTrail.model.ability.SkillInfo; @@ -66,7 +66,7 @@ public final class LegacySavegameFormatReaderForPlayer { player.addQuestProgress(new QuestProgress(questID, progress)); } - public static void upgradeSavegame(Player player, WorldContext world, int fileversion) { + public static void upgradeSavegame(Player player, WorldContext world, ViewContext view, int fileversion) { if (fileversion <= 12) { player.useItemCost = 5; @@ -89,9 +89,9 @@ public final class LegacySavegameFormatReaderForPlayer { } if (fileversion <= 27) { - correctActorConditionsFromItemsPre0611b1(player, "bless", world, "elytharan_redeemer"); - correctActorConditionsFromItemsPre0611b1(player, "blackwater_misery", world, "bwm_dagger"); - correctActorConditionsFromItemsPre0611b1(player, "regen", world, "ring_shadow0"); + correctActorConditionsFromItemsPre0611b1(player, "bless", world, view, "elytharan_redeemer"); + correctActorConditionsFromItemsPre0611b1(player, "blackwater_misery", world, view, "bwm_dagger"); + correctActorConditionsFromItemsPre0611b1(player, "regen", world, view, "ring_shadow0"); } if (fileversion <= 30) { @@ -105,7 +105,7 @@ public final class LegacySavegameFormatReaderForPlayer { return 1 + (int) FloatMath.floor((float) level / Constants.NEW_SKILL_POINT_EVERY_N_LEVELS); } - private static void correctActorConditionsFromItemsPre0611b1(Player player, String conditionTypeID, WorldContext world, String itemTypeIDWithCondition) { + private static void correctActorConditionsFromItemsPre0611b1(Player player, String conditionTypeID, WorldContext world, ViewContext view, String itemTypeIDWithCondition) { if (!player.hasCondition(conditionTypeID)) return; boolean hasItemWithCondition = false; for (ItemType t : player.inventory.wear) { @@ -120,7 +120,7 @@ public final class LegacySavegameFormatReaderForPlayer { } if (hasItemWithCondition) return; - ActorStatsController.removeConditionsFromUnequippedItem(player, world.itemTypes.getItemType(itemTypeIDWithCondition)); + view.actorStatsController.removeConditionsFromUnequippedItem(player, world.itemTypes.getItemType(itemTypeIDWithCondition)); } public static void readCombatTraitsPreV034(DataInputStream src, int fileversion) throws IOException { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Range.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Range.java index 320c6fce6..4179bd846 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Range.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Range.java @@ -38,8 +38,12 @@ public final class Range { if (!mayOverflow) capAtMax(); return (this.current != valueBefore); } - public void capAtMax() { - if (current > max) current = max; + public boolean capAtMax() { + if (current > max) { + current = max; + return true; + } + return false; } public void addToMax(int value) { this.max += value; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ActorConditionList.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ActorConditionList.java index 367c27352..e10541278 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ActorConditionList.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ActorConditionList.java @@ -26,7 +26,7 @@ public final class ActorConditionList extends LinearLayout { setFocusable(false); setOrientation(LinearLayout.VERTICAL); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivityContext(context); - this.world = app.world; + this.world = app.getWorld(); } public void update(Iterable conditions) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java index 5d1ecedd1..4353b7a71 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java @@ -20,12 +20,15 @@ import com.gpl.rpg.AndorsTrail.R; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.CombatController; +import com.gpl.rpg.AndorsTrail.controller.listeners.CombatSelectionListener; +import com.gpl.rpg.AndorsTrail.controller.listeners.CombatTurnListener; +import com.gpl.rpg.AndorsTrail.model.actor.Actor; import com.gpl.rpg.AndorsTrail.model.actor.Monster; import com.gpl.rpg.AndorsTrail.model.actor.Player; +import com.gpl.rpg.AndorsTrail.model.listeners.ActorStatsListener; import com.gpl.rpg.AndorsTrail.util.Coord; -import com.gpl.rpg.AndorsTrail.util.Range; -public final class CombatView extends RelativeLayout { +public final class CombatView extends RelativeLayout implements CombatSelectionListener, CombatTurnListener, ActorStatsListener { private final TextView statusTextView; private final Button attackMoveButton; private final ImageButton monsterInfo; @@ -47,10 +50,10 @@ public final class CombatView extends RelativeLayout { public CombatView(final Context context, AttributeSet attr) { super(context, attr); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivityContext(context); - this.world = app.world; + this.world = app.getWorld(); this.player = world.model.player; - this.view = app.currentView.get(); - this.preferences = app.preferences; + this.view = app.getViewContext(); + this.preferences = app.getPreferences(); this.res = getResources(); setFocusable(false); @@ -87,7 +90,7 @@ public final class CombatView extends RelativeLayout { monsterInfo.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { - Dialogs.showMonsterInfo(view.mainActivity, currentMonster); + Dialogs.showMonsterInfo(context, currentMonster); } }); @@ -111,7 +114,7 @@ public final class CombatView extends RelativeLayout { }); } - public void updateTurnInfo(Monster currentActiveMonster) { + private void updateTurnInfo(Monster currentActiveMonster) { if (currentActiveMonster != null) { actionBar.setVisibility(View.INVISIBLE); monsterActionText.setVisibility(View.VISIBLE); @@ -122,25 +125,30 @@ public final class CombatView extends RelativeLayout { } } - private void updateMonsterHealth(Range range) { - monsterHealth.update(range); + private void updateMonsterHealth(Monster m) { + monsterHealth.update(m.getMaxHP(), m.getCurrentHP()); } - private void updatePlayerAP(Range range) { - statusTextView.setText(res.getString(R.string.combat_status_ap, range.current)); + private void updatePlayerAP(Player player) { + statusTextView.setText(res.getString(R.string.combat_status_ap, player.getCurrentAP())); } - public void updateCombatSelection(Monster selectedMonster, Coord selectedMovePosition) { + private void updateSelectedMonster(Monster selectedMonster) { if (currentMonster != null && currentMonster == selectedMonster) return; attackMoveButton.setEnabled(true); monsterBar.setVisibility(View.INVISIBLE); currentMonster = null; if (selectedMonster != null) { - attackMoveButton.setText(res.getString(R.string.combat_attack, player.getAttackCost())); monsterBar.setVisibility(View.VISIBLE); world.tileManager.setImageViewTile(monsterInfo, selectedMonster); - updateMonsterHealth(selectedMonster.health); + updateMonsterHealth(selectedMonster); currentMonster = selectedMonster; - } else if (selectedMovePosition != null) { + } + } + + private void updateAttackMoveButtonText() { + if (world.model.uiSelections.selectedMonster != null) { + attackMoveButton.setText(res.getString(R.string.combat_attack, player.getAttackCost())); + } else if (world.model.uiSelections.selectedPosition != null) { attackMoveButton.setText(res.getString(R.string.combat_move, player.getMoveCost())); } else { attackMoveButton.setText(res.getString(R.string.combat_attack, player.getAttackCost())); @@ -148,14 +156,13 @@ public final class CombatView extends RelativeLayout { } public void updateStatus() { - updatePlayerAP(player.ap); - if (world.model.uiSelections.selectedMonster != null) { - updateMonsterHealth(world.model.uiSelections.selectedMonster.health); - } - updateCombatSelection(world.model.uiSelections.selectedMonster, world.model.uiSelections.selectedPosition); + updatePlayerAP(player); + updateSelectedMonster(world.model.uiSelections.selectedMonster); + updateAttackMoveButtonText(); } public void show() { + updateStatus(); setVisibility(View.VISIBLE); bringToFront(); if (preferences.enableUiAnimations) { @@ -170,4 +177,71 @@ public final class CombatView extends RelativeLayout { setVisibility(View.GONE); } } + + public void subscribe() { + view.combatController.combatSelectionListeners.add(this); + view.combatController.combatTurnListeners.add(this); + view.actorStatsController.actorStatsListeners.add(this); + } + public void unsubscribe() { + view.actorStatsController.actorStatsListeners.remove(this); + view.combatController.combatTurnListeners.remove(this); + view.combatController.combatSelectionListeners.remove(this); + } + + @Override + public void onMonsterSelected(Monster m, Coord selectedPosition, Coord previousSelection) { + updateSelectedMonster(m); + } + + @Override + public void onMovementDestinationSelected(Coord selectedPosition, Coord previousSelection) { + updateSelectedMonster(null); + } + + @Override + public void onCombatSelectionCleared(Coord previousSelection) { + updateSelectedMonster(null); + } + + @Override + public void onCombatStarted() { + show(); + updateTurnInfo(null); + } + + @Override + public void onCombatEnded() { + hide(); + } + + @Override + public void onNewPlayerTurn() { + updateTurnInfo(null); + } + + @Override + public void onMonsterIsAttacking(Monster m) { + updateTurnInfo(m); + } + + @Override + public void onActorHealthChanged(Actor actor) { + if (actor == currentMonster) updateMonsterHealth(currentMonster); + } + + @Override + public void onActorAPChanged(Actor actor) { + if (actor == player) updatePlayerAP(player); + } + + @Override + public void onActorAttackCostChanged(Actor actor, int newAttackCost) { + if (actor == player) updateAttackMoveButtonText(); + } + + @Override + public void onActorMoveCostChanged(Actor actor, int newMoveCost) { + if (actor == player) updateAttackMoveButtonText(); + } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java index c14864707..07c27e5ae 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java @@ -16,6 +16,7 @@ import android.widget.RelativeLayout.LayoutParams; import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences; import com.gpl.rpg.AndorsTrail.R; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; import com.gpl.rpg.AndorsTrail.model.actor.Actor; @@ -26,23 +27,28 @@ public class DisplayActiveActorConditionIcons implements ActorConditionListener private final AndorsTrailPreferences preferences; private final TileManager tileManager; + private final ViewContext view; + private final WorldContext world; private final RelativeLayout activeConditions; private final ArrayList currentConditionIcons = new ArrayList(); private final WeakReference androidContext; public DisplayActiveActorConditionIcons( - final AndorsTrailPreferences preferences, - final TileManager tileManager, + final ViewContext view, + final WorldContext world, Context androidContext, RelativeLayout activeConditions) { - this.preferences = preferences; - this.tileManager = tileManager; + this.view = view; + this.world = world; + this.preferences = view.preferences; + this.tileManager = world.tileManager; this.androidContext = new WeakReference(androidContext); this.activeConditions = activeConditions; } @Override public void onActorConditionAdded(Actor actor, ActorCondition condition) { + if (actor != world.model.player) return; ActiveConditionIcon icon = getFirstFreeIcon(); icon.setActiveCondition(condition); icon.show(); @@ -50,6 +56,7 @@ public class DisplayActiveActorConditionIcons implements ActorConditionListener @Override public void onActorConditionRemoved(Actor actor, ActorCondition condition) { + if (actor != world.model.player) return; ActiveConditionIcon icon = getIconFor(condition); if (icon == null) return; icon.hide(true); @@ -61,6 +68,7 @@ public class DisplayActiveActorConditionIcons implements ActorConditionListener @Override public void onActorConditionMagnitudeChanged(Actor actor, ActorCondition condition) { + if (actor != world.model.player) return; ActiveConditionIcon icon = getIconFor(condition); if (icon == null) return; icon.setIconText(); @@ -68,22 +76,23 @@ public class DisplayActiveActorConditionIcons implements ActorConditionListener @Override public void onActorConditionRoundEffectApplied(Actor actor, ActorCondition condition) { + if (actor != world.model.player) return; ActiveConditionIcon icon = getIconFor(condition); if (icon == null) return; icon.pulseAnimate(); } - public void unsubscribe(final WorldContext world) { - world.model.player.conditionListener.remove(this); + public void unsubscribe() { + view.actorStatsController.actorConditionListeners.remove(this); for (ActiveConditionIcon icon : currentConditionIcons) icon.condition = null; } - public void subscribe(final WorldContext world) { + public void subscribe() { for (ActiveConditionIcon icon : currentConditionIcons) icon.hide(false); for (ActorCondition condition : world.model.player.conditions) { getFirstFreeIcon().setActiveCondition(condition); } - world.model.player.conditionListener.add(this); + view.actorStatsController.actorConditionListeners.add(this); } private final class ActiveConditionIcon implements AnimationListener { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/MainView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/MainView.java index 177ba4c89..ce2036b93 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/MainView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/MainView.java @@ -7,6 +7,12 @@ import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.InputController; import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.BloodSplatter; import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAnimation; +import com.gpl.rpg.AndorsTrail.controller.listeners.CombatSelectionListener; +import com.gpl.rpg.AndorsTrail.controller.listeners.LootBagListener; +import com.gpl.rpg.AndorsTrail.controller.listeners.MonsterMovementListener; +import com.gpl.rpg.AndorsTrail.controller.listeners.MonsterSpawnListener; +import com.gpl.rpg.AndorsTrail.controller.listeners.PlayerMovementListener; +import com.gpl.rpg.AndorsTrail.controller.listeners.VisualEffectFrameListener; import com.gpl.rpg.AndorsTrail.model.ModelContainer; import com.gpl.rpg.AndorsTrail.model.actor.Monster; import com.gpl.rpg.AndorsTrail.model.item.Loot; @@ -31,7 +37,14 @@ import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; -public final class MainView extends SurfaceView implements SurfaceHolder.Callback { +public final class MainView extends SurfaceView + implements SurfaceHolder.Callback, + PlayerMovementListener, + CombatSelectionListener, + MonsterSpawnListener, + MonsterMovementListener, + LootBagListener, + VisualEffectFrameListener { private final int tileSize; private float scale; @@ -64,12 +77,12 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac this.holder = getHolder(); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivityContext(context); - this.view = app.currentView.get(); - this.model = app.world.model; - this.world = app.world; + this.view = app.getViewContext(); + this.world = app.getWorld(); + this.model = world.model; this.tileSize = world.tileManager.tileSize; this.inputController = view.inputController; - this.preferences = app.preferences; + this.preferences = app.getPreferences(); holder.addCallback(this); @@ -110,10 +123,10 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac ); if (model.currentMap != null) { - notifyMapChanged(model); + onPlayerEnteredNewMap(model.currentMap, model.player.position); + } else { + redrawAll(REDRAW_ALL_SURFACE_CHANGED); } - - redrawAll(REDRAW_ALL_SURFACE_CHANGED); } @Override @@ -152,16 +165,18 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac return true; } - public static final int REDRAW_ALL_SURFACE_CHANGED = 1; - public static final int REDRAW_ALL_MAP_CHANGED = 2; - public static final int REDRAW_ALL_PLAYER_MOVED = 3; - public static final int REDRAW_ALL_MONSTER_MOVED = 4; - public static final int REDRAW_ALL_MONSTER_KILLED = 10; - public static final int REDRAW_AREA_EFFECT_STARTING = 5; - public static final int REDRAW_AREA_EFFECT_COMPLETED = 6; - public static final int REDRAW_TILE_SELECTION_REMOVED = 7; - public static final int REDRAW_TILE_SELECTION_ADDED = 8; - public static final int REDRAW_TILE_BAG = 9; + private static final int REDRAW_ALL_SURFACE_CHANGED = 1; + private static final int REDRAW_ALL_MAP_CHANGED = 2; + private static final int REDRAW_ALL_PLAYER_MOVED = 3; + private static final int REDRAW_AREA_MONSTER_MOVED = 4; + private static final int REDRAW_AREA_MONSTER_KILLED = 10; + private static final int REDRAW_AREA_EFFECT_STARTING = 5; + private static final int REDRAW_AREA_EFFECT_COMPLETED = 6; + private static final int REDRAW_AREA_MONSTER_SPAWNED = 11; + private static final int REDRAW_TILE_SELECTION_REMOVED = 7; + private static final int REDRAW_TILE_SELECTION_ADDED = 8; + private static final int REDRAW_TILE_BAG = 9; + private static final int REDRAW_TILE_SPLATTER = 12; public void redrawAll(int why) { redrawArea_(mapViewArea); @@ -205,7 +220,7 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac return true; } private final Rect redrawRect = new Rect(); - public void redrawAreaWithEffect(final VisualEffectAnimation effect, int tileID, int textYOffset, Paint textPaint) { + public void redrawAreaWithEffect(final VisualEffectAnimation effect, int tileID, int textYOffset) { CoordRect area = effect.area; if (!hasSurface) return; if (shouldRedrawEverythingForVisualEffect()) area = mapViewArea; @@ -222,7 +237,7 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac doDrawRect(c, area); drawFromMapPosition(c, area, effect.position, tileID); if (effect.displayText != null) { - drawEffectText(c, area, effect, textYOffset, textPaint); + drawEffectText(c, area, effect, textYOffset, effect.textPaint); } } } } finally { @@ -338,9 +353,10 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac canvas.drawText(e.displayText, x, y, textPaint); } - public void notifyMapChanged(ModelContainer model) { + @Override + public void onPlayerEnteredNewMap(PredefinedMap map, Coord p) { synchronized (holder) { - currentMap = model.currentMap; + currentMap = map; currentTileMap = model.currentTileMap; tiles = world.tileManager.currentMapTiles; @@ -379,9 +395,99 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac } } } - - public void notifyPlayerMoved(Coord newPosition) { + + @Override + public void onPlayerMoved(Coord newPosition, Coord previousPosition) { recalculateMapTopLeft(newPosition); redrawAll(REDRAW_ALL_PLAYER_MOVED); } + + public void subscribe() { + view.effectController.visualEffectFrameListeners.add(this); + view.itemController.lootBagListeners.add(this); + view.movementController.playerMovementListeners.add(this); + view.combatController.combatSelectionListeners.add(this); + view.monsterSpawnController.monsterSpawnListeners.add(this); + view.monsterMovementController.monsterMovementListeners.add(this); + } + public void unsubscribe() { + view.monsterMovementController.monsterMovementListeners.remove(this); + view.monsterSpawnController.monsterSpawnListeners.remove(this); + view.combatController.combatSelectionListeners.remove(this); + view.movementController.playerMovementListeners.remove(this); + view.itemController.lootBagListeners.remove(this); + view.effectController.visualEffectFrameListeners.remove(this); + } + + @Override + public void onMonsterSelected(Monster m, Coord selectedPosition, Coord previousSelection) { + if (previousSelection != null) redrawTile(previousSelection, REDRAW_TILE_SELECTION_REMOVED); + redrawTile(selectedPosition, REDRAW_TILE_SELECTION_ADDED); + } + + @Override + public void onMovementDestinationSelected(Coord selectedPosition, Coord previousSelection) { + if (previousSelection != null) redrawTile(previousSelection, REDRAW_TILE_SELECTION_REMOVED); + redrawTile(selectedPosition, REDRAW_TILE_SELECTION_ADDED); + } + + @Override + public void onCombatSelectionCleared(Coord previousSelection) { + redrawTile(previousSelection, REDRAW_TILE_SELECTION_REMOVED); + } + + @Override + public void onMonsterSpawned(Monster m) { + redrawArea(m.rectPosition, REDRAW_AREA_MONSTER_SPAWNED); + } + + @Override + public void onMonsterRemoved(Monster m, CoordRect previousPosition) { + redrawArea(previousPosition, REDRAW_AREA_MONSTER_KILLED); + } + + @Override + public void onMonsterSteppedOnPlayer(Monster m) { + } + + @Override + public void onMonsterMoved(Monster m, CoordRect previousPosition) { + redrawArea(previousPosition, REDRAW_AREA_MONSTER_MOVED); + redrawArea(m.rectPosition, REDRAW_AREA_MONSTER_MOVED); + } + + @Override + public void onSplatterAdded(Coord p) { + redrawTile(p, REDRAW_TILE_SPLATTER); + } + + @Override + public void onSplatterChanged(Coord p) { + redrawTile(p, REDRAW_TILE_SPLATTER); + } + + @Override + public void onSplatterRemoved(Coord p) { + redrawTile(p, REDRAW_TILE_SPLATTER); + } + + @Override + public void onLootBagCreated(Coord p) { + redrawTile(p, REDRAW_TILE_BAG); + } + + @Override + public void onLootBagRemoved(Coord p) { + redrawTile(p, REDRAW_TILE_BAG); + } + + @Override + public void onNewAnimationFrame(VisualEffectAnimation animation, int tileID, int textYOffset) { + redrawAreaWithEffect(animation, tileID, textYOffset); + } + + @Override + public void onAnimationCompleted(VisualEffectAnimation animation) { + redrawArea(animation.area, REDRAW_AREA_EFFECT_COMPLETED); + } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/QuickitemView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/QuickitemView.java index 049673024..8c2d11a7b 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/QuickitemView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/QuickitemView.java @@ -16,11 +16,12 @@ import com.gpl.rpg.AndorsTrail.R; import com.gpl.rpg.AndorsTrail.activity.MainActivity; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.controller.listeners.QuickSlotListener; import com.gpl.rpg.AndorsTrail.model.item.Inventory; import com.gpl.rpg.AndorsTrail.model.item.ItemType; import com.gpl.rpg.AndorsTrail.resource.tiles.TileCollection; -public class QuickitemView extends LinearLayout implements OnClickListener { +public class QuickitemView extends LinearLayout implements OnClickListener, QuickSlotListener { private static final int NUM_QUICK_SLOTS = Inventory.NUM_QUICK_SLOTS; private final WorldContext world; @@ -32,8 +33,8 @@ public class QuickitemView extends LinearLayout implements OnClickListener { public QuickitemView(Context context, AttributeSet attrs) { super(context, attrs); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivityContext(context); - this.world = app.world; - this.view = app.currentView.get(); + this.world = app.getWorld(); + this.view = app.getViewContext(); setFocusable(false); setOrientation(LinearLayout.HORIZONTAL); @@ -110,4 +111,21 @@ public class QuickitemView extends LinearLayout implements OnClickListener { for(QuickButton item: buttons) mainActivity.registerForContextMenu(item); } + + @Override + public void onQuickSlotChanged(int slotId) { + refreshQuickitems(); + } + + @Override + public void onQuickSlotUsed(int slotId) { + refreshQuickitems(); + } + + public void subscribe() { + view.itemController.quickSlotListeners.add(this); + } + public void unsubscribe() { + view.itemController.quickSlotListeners.remove(this); + } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/RangeBar.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/RangeBar.java index 13fdf89c7..ed67c73a3 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/RangeBar.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/RangeBar.java @@ -32,12 +32,13 @@ public final class RangeBar extends RelativeLayout { labelText.setText(labelTextID); } - public void update(final Range range) { + public void update(final Range range) { update(range.max, range.current); } + public void update(final int max, final int current) { progressBar.setProgress(0); // http://stackoverflow.com/questions/4348032/android-progressbar-does-not-update-progress-view-drawable - progressBar.setMax(range.max); - progressBar.setProgress(Math.min(range.current, range.max)); - progressBarText.setText(range.toString()); + progressBar.setMax(max); + progressBar.setProgress(Math.min(current, max)); + progressBarText.setText(current + "/" + max); invalidate(); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java index c6edb3ce6..18f52742d 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java @@ -3,8 +3,12 @@ package com.gpl.rpg.AndorsTrail.view; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.R; import com.gpl.rpg.AndorsTrail.activity.HeroinfoActivity; +import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.controller.listeners.PlayerStatsListener; +import com.gpl.rpg.AndorsTrail.model.actor.Actor; import com.gpl.rpg.AndorsTrail.model.actor.Player; +import com.gpl.rpg.AndorsTrail.model.listeners.ActorStatsListener; import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager; import android.content.Context; @@ -17,8 +21,9 @@ import android.view.View; import android.widget.RelativeLayout; import android.widget.ImageButton; -public final class StatusView extends RelativeLayout { +public final class StatusView extends RelativeLayout implements PlayerStatsListener, ActorStatsListener { + private final ViewContext view; private final WorldContext world; private final Player player; @@ -33,8 +38,9 @@ public final class StatusView extends RelativeLayout { public StatusView(final Context context, AttributeSet attr) { super(context, attr); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivityContext(context); - this.world = app.world; - this.player = app.world.model.player; + this.view = app.getViewContext(); + this.world = app.getWorld(); + this.player = world.model.player; setFocusable(false); inflate(context, R.layout.statusview, this); @@ -80,8 +86,24 @@ public final class StatusView extends RelativeLayout { } public void updateStatus() { - healthBar.update(player.health); - expBar.update(player.levelExperience); + updateHealth(); + updateExperience(); + } + + public void subscribe() { + view.actorStatsController.actorStatsListeners.add(this); + view.actorStatsController.playerStatsListeners.add(this); + } + public void unsubscribe() { + view.actorStatsController.playerStatsListeners.remove(this); + view.actorStatsController.actorStatsListeners.remove(this); + } + + private void updateHealth() { + healthBar.update(player.getMaxHP(), player.getCurrentHP()); + } + private void updateExperience() { + expBar.update(player.getMaxLevelExperience(), player.getCurrentLevelExperience()); boolean canLevelUp = player.canLevelup(); if (showingLevelup != canLevelUp) { updateIcon(canLevelUp); @@ -96,4 +118,23 @@ public final class StatusView extends RelativeLayout { world.tileManager.setImageViewTile(heroImage, player); } } + + @Override + public void onActorHealthChanged(Actor actor) { + if (actor == player) updateHealth(); + } + + @Override + public void onActorAPChanged(Actor actor) { } + + @Override + public void onActorAttackCostChanged(Actor actor, int newAttackCost) { } + + @Override + public void onActorMoveCostChanged(Actor actor, int newMoveCost) { } + + @Override + public void onPlayerExperienceChanged(Player p) { + updateExperience(); + } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ToolboxView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ToolboxView.java index c4caa9e4b..3ecb0a79a 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ToolboxView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ToolboxView.java @@ -30,8 +30,8 @@ public class ToolboxView extends LinearLayout implements OnClickListener { public ToolboxView(final Context context, AttributeSet attrs) { super(context, attrs); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivityContext(context); - this.world = app.world; - this.preferences = app.preferences; + this.world = app.getWorld(); + this.preferences = app.getPreferences(); inflate(context, R.layout.toolboxview, this); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/VirtualDpadView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/VirtualDpadView.java index 6f6b84d5a..a3c2f5366 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/VirtualDpadView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/VirtualDpadView.java @@ -35,8 +35,8 @@ public final class VirtualDpadView extends ImageView implements OnClickListener public VirtualDpadView(final Context context, AttributeSet attr) { super(context, attr); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivityContext(context); - this.world = app.world; - this.view = app.currentView.get(); + this.world = app.getWorld(); + this.view = app.getViewContext(); this.inputController = this.view.inputController; setImageResource(R.drawable.ui_dpad);