mirror of
https://github.com/OMGeeky/andors-trail.git
synced 2026-02-23 15:38:29 +01:00
Merge branch 'refactor_listener'
This commit is contained in:
10
AndorsTrail/.gitignore
vendored
10
AndorsTrail/.gitignore
vendored
@@ -1,8 +1,8 @@
|
||||
# Android ignores
|
||||
gen
|
||||
bin
|
||||
assets
|
||||
target
|
||||
gen/
|
||||
bin/
|
||||
assets/
|
||||
target/
|
||||
|
||||
#IntelliJ
|
||||
.idea/
|
||||
@@ -15,4 +15,4 @@ local.properties
|
||||
|
||||
# Other
|
||||
.metadata
|
||||
.svn
|
||||
.svn/
|
||||
|
||||
@@ -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<ViewContext> 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);
|
||||
|
||||
@@ -4,7 +4,7 @@ import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
public class AndorsTrailPreferences {
|
||||
public final class AndorsTrailPreferences {
|
||||
public static final int DISPLAYLOOT_DIALOG = 0;
|
||||
public static final int DISPLAYLOOT_TOAST = 1;
|
||||
public static final int DISPLAYLOOT_NONE = 2;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package com.gpl.rpg.AndorsTrail;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
@@ -19,7 +20,6 @@ import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.activity.ActorConditionInfoActivity;
|
||||
import com.gpl.rpg.AndorsTrail.activity.BulkSelectionInterface;
|
||||
import com.gpl.rpg.AndorsTrail.activity.ConversationActivity;
|
||||
@@ -33,14 +33,11 @@ import com.gpl.rpg.AndorsTrail.activity.LevelUpActivity;
|
||||
import com.gpl.rpg.AndorsTrail.activity.MonsterEncounterActivity;
|
||||
import com.gpl.rpg.AndorsTrail.activity.MonsterInfoActivity;
|
||||
import com.gpl.rpg.AndorsTrail.activity.Preferences;
|
||||
import com.gpl.rpg.AndorsTrail.activity.HeroinfoActivity_Quests;
|
||||
import com.gpl.rpg.AndorsTrail.activity.ShopActivity;
|
||||
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,89 @@ 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<Loot> 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<Loot> copy = new HashSet<Loot>(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) {
|
||||
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<Loot> lootBags, final int exp, final int title, String msg, boolean isContainer) {
|
||||
//if (ItemController.updateLootVisibility(context, lootBags)) return;
|
||||
|
||||
final Loot combinedLoot = new Loot();
|
||||
for (Loot l : lootBags) {
|
||||
combinedLoot.add(l);
|
||||
public static String getGroundLootMessage(final Context ctx, final Loot loot) {
|
||||
StringBuilder sb = new StringBuilder(60);
|
||||
if (!loot.items.isEmpty()) {
|
||||
sb.append(ctx.getString(R.string.dialog_groundloot_message));
|
||||
}
|
||||
if (loot.gold > 0) {
|
||||
sb.append(' ');
|
||||
sb.append(ctx.getString(R.string.dialog_loot_foundgold, loot.gold));
|
||||
}
|
||||
appendLootMessage(ctx, loot, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
public static String getMonsterLootMessage(final Context ctx, final Loot combinedLoot, final int exp) {
|
||||
StringBuilder sb = new StringBuilder(60);
|
||||
sb.append(ctx.getString(R.string.dialog_monsterloot_message));
|
||||
|
||||
if (exp > 0) {
|
||||
msg += mainActivity.getString(R.string.dialog_monsterloot_gainedexp, exp);
|
||||
sb.append(' ');
|
||||
sb.append(ctx.getString(R.string.dialog_monsterloot_gainedexp, exp));
|
||||
}
|
||||
if (combinedLoot.gold > 0) {
|
||||
msg += mainActivity.getString(R.string.dialog_loot_foundgold, combinedLoot.gold);
|
||||
appendLootMessage(ctx, combinedLoot, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
private static void appendLootMessage(final Context ctx, final Loot loot, final StringBuilder sb) {
|
||||
if (loot.gold > 0) {
|
||||
sb.append(' ');
|
||||
sb.append(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) {
|
||||
sb.append(' ');
|
||||
sb.append(ctx.getString(R.string.dialog_loot_pickedupitem));
|
||||
} else if (numItems > 1){
|
||||
sb.append(' ');
|
||||
sb.append(ctx.getString(R.string.dialog_loot_pickedupitems, numItems));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void showMonsterLoot(final MainActivity mainActivity, final ViewContext view, final WorldContext world, final Collection<Loot> lootBags, final Loot combinedLoot, final String msg) {
|
||||
// CombatController will do killedMonsterBags.clear() after this method has been called,
|
||||
// so we need to keep the list of objects. Therefore, we create a shallow copy of the list of bags.
|
||||
ArrayList<Loot> bags = new ArrayList<Loot>(lootBags);
|
||||
showLoot(mainActivity, view, world, combinedLoot, bags, 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, Collections.singletonList(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<Loot> 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 +199,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 +230,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 +268,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;
|
||||
}
|
||||
@@ -287,11 +285,6 @@ public final class Dialogs {
|
||||
currentActivity.startActivityForResult(intent, StartScreenActivity.INTENTREQUEST_LOADGAME);
|
||||
}
|
||||
|
||||
public static void showQuestLog(final Activity currentActivity) {
|
||||
Intent intent = new Intent(currentActivity, HeroinfoActivity_Quests.class);
|
||||
currentActivity.startActivity(intent);
|
||||
}
|
||||
|
||||
public static void showActorConditionInfo(final Context context, ActorConditionType conditionType) {
|
||||
Intent intent = new Intent(context, ActorConditionInfoActivity.class);
|
||||
intent.setData(Uri.parse("content://com.gpl.rpg.AndorsTrail/actorconditioninfo/" + conditionType.conditionTypeID));
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
|
||||
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;
|
||||
import com.gpl.rpg.AndorsTrail.model.ModelContainer;
|
||||
import com.gpl.rpg.AndorsTrail.util.L;
|
||||
|
||||
public final class Savegames {
|
||||
public static final int SLOT_QUICKSAVE = 0;
|
||||
|
||||
public static final int LOAD_RESULT_SUCCESS = 0;
|
||||
public static final int LOAD_RESULT_UNKNOWN_ERROR = 1;
|
||||
public static final int LOAD_RESULT_FUTURE_VERSION = 2;
|
||||
|
||||
public static boolean saveWorld(WorldContext world, Context androidContext, int slot, String displayInfo) {
|
||||
try {
|
||||
// Create the savegame in a temporary memorystream first to ensure that the savegame can
|
||||
// be created correctly. We don't want to trash the user's file unneccessarily if there is an error.
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
saveWorld(world, bos, displayInfo);
|
||||
byte[] savegame = bos.toByteArray();
|
||||
bos.close();
|
||||
bos = null;
|
||||
|
||||
FileOutputStream fos = getOutputFile(androidContext, slot);
|
||||
fos.write(savegame);
|
||||
fos.close();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
L.log("Error saving world: " + e.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static int loadWorld(WorldContext world, Context androidContext, int slot) {
|
||||
try {
|
||||
FileInputStream fos = getInputFile(androidContext, slot);
|
||||
int result = loadWorld(world, fos);
|
||||
fos.close();
|
||||
return result;
|
||||
} catch (IOException e) {
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
|
||||
L.log("Error loading world: " + e.toString());
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
L.log("Load error: " + sw.toString());
|
||||
}
|
||||
return LOAD_RESULT_UNKNOWN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
private static FileOutputStream getOutputFile(Context androidContext, int slot) throws IOException {
|
||||
if (slot == SLOT_QUICKSAVE) {
|
||||
return androidContext.openFileOutput(Constants.FILENAME_SAVEGAME_QUICKSAVE, Context.MODE_PRIVATE);
|
||||
} else {
|
||||
ensureSavegameDirectoryExists();
|
||||
return new FileOutputStream(getSlotFile(slot));
|
||||
}
|
||||
}
|
||||
private static void ensureSavegameDirectoryExists() {
|
||||
File root = Environment.getExternalStorageDirectory();
|
||||
File dir = new File(root, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
if (!dir.exists()) dir.mkdir();
|
||||
}
|
||||
private static FileInputStream getInputFile(Context androidContext, int slot) throws IOException {
|
||||
if (slot == SLOT_QUICKSAVE) {
|
||||
return androidContext.openFileInput(Constants.FILENAME_SAVEGAME_QUICKSAVE);
|
||||
} else {
|
||||
return new FileInputStream(getSlotFile(slot));
|
||||
}
|
||||
}
|
||||
private static File getSlotFile(int slot) {
|
||||
File root = getSavegameDirectory();
|
||||
return new File(root, Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + slot);
|
||||
}
|
||||
|
||||
private static File getSavegameDirectory() {
|
||||
File root = Environment.getExternalStorageDirectory();
|
||||
return new File(root, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
}
|
||||
|
||||
public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException {
|
||||
DataOutputStream dest = new DataOutputStream(outStream);
|
||||
final int flags = 0;
|
||||
FileHeader.writeToParcel(dest, world.model.player.getName(), displayInfo);
|
||||
world.maps.writeToParcel(dest, flags);
|
||||
world.model.writeToParcel(dest, flags);
|
||||
dest.close();
|
||||
}
|
||||
|
||||
public static int loadWorld(WorldContext world, InputStream inState) throws IOException {
|
||||
DataInputStream src = new DataInputStream(inState);
|
||||
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);
|
||||
src.close();
|
||||
|
||||
onWorldLoaded(world);
|
||||
|
||||
return LOAD_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
private static void onWorldLoaded(WorldContext world) {
|
||||
ActorStatsController.recalculatePlayerStats(world.model.player);
|
||||
Controller.resetMapsNotRecentlyVisited(world);
|
||||
MovementController.moveBlockedActors(world);
|
||||
}
|
||||
|
||||
public static FileHeader quickload(Context androidContext, int slot) {
|
||||
try {
|
||||
if (slot != SLOT_QUICKSAVE) {
|
||||
File f = getSlotFile(slot);
|
||||
if (!f.exists()) return null;
|
||||
}
|
||||
FileInputStream fos = getInputFile(androidContext, slot);
|
||||
DataInputStream src = new DataInputStream(fos);
|
||||
final FileHeader header = new FileHeader(src);
|
||||
src.close();
|
||||
fos.close();
|
||||
return header;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Pattern savegameFilenamePattern = Pattern.compile(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + "(\\d+)");
|
||||
public static List<Integer> getUsedSavegameSlots(Context androidContext) {
|
||||
try {
|
||||
final List<Integer> result = new ArrayList<Integer>();
|
||||
getSavegameDirectory().listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File f, String filename) {
|
||||
Matcher m = savegameFilenamePattern.matcher(filename);
|
||||
if (m != null && m.matches()) {
|
||||
result.add(Integer.parseInt(m.group(1)));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
Collections.sort(result);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class FileHeader {
|
||||
public final int fileversion;
|
||||
public final String playerName;
|
||||
public final String displayInfo;
|
||||
|
||||
public FileHeader(String playerName, String displayInfo) {
|
||||
this.fileversion = AndorsTrailApplication.CURRENT_VERSION;
|
||||
this.playerName = playerName;
|
||||
this.displayInfo = displayInfo;
|
||||
}
|
||||
|
||||
public String describe() {
|
||||
return playerName + ", " + displayInfo;
|
||||
}
|
||||
|
||||
|
||||
// ====== PARCELABLE ===================================================================
|
||||
|
||||
public FileHeader(DataInputStream src) throws IOException {
|
||||
int fileversion = src.readInt();
|
||||
if (fileversion == 11) fileversion = 5; // Fileversion 5 had no version identifier, but the first byte was 11.
|
||||
this.fileversion = fileversion;
|
||||
if (fileversion >= 14) { // Before fileversion 14 (0.6.7), we had no file header.
|
||||
this.playerName = src.readUTF();
|
||||
this.displayInfo = src.readUTF();
|
||||
} else {
|
||||
this.playerName = null;
|
||||
this.displayInfo = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeToParcel(DataOutputStream dest, String playerName, String displayInfo) throws IOException {
|
||||
dest.writeInt(AndorsTrailApplication.CURRENT_VERSION);
|
||||
dest.writeUTF(playerName);
|
||||
dest.writeUTF(displayInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.gpl.rpg.AndorsTrail;
|
||||
|
||||
import android.graphics.Color;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.resource.DynamicTileLoader;
|
||||
import com.gpl.rpg.AndorsTrail.util.ConstRange;
|
||||
|
||||
@@ -30,7 +28,7 @@ public final class VisualEffectCollection {
|
||||
return new VisualEffect(frameIconIDs, duration, textColor);
|
||||
}
|
||||
|
||||
public final static class VisualEffect {
|
||||
public static final class VisualEffect {
|
||||
public final int[] frameIconIDs;
|
||||
public final int duration; // milliseconds
|
||||
public final int textColor;
|
||||
|
||||
@@ -6,15 +6,16 @@ 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;
|
||||
import com.gpl.rpg.AndorsTrail.savegames.Savegames;
|
||||
|
||||
public final class WorldSetup {
|
||||
|
||||
private final WorldContext world;
|
||||
private final ViewContext view;
|
||||
private final WeakReference<Context> 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<Context>(androidContext);
|
||||
}
|
||||
|
||||
@@ -44,7 +46,7 @@ public final class WorldSetup {
|
||||
}
|
||||
}
|
||||
|
||||
public void startResourceLoader(final Resources r, final AndorsTrailPreferences preferences) {
|
||||
public void startResourceLoader(final Resources r) {
|
||||
if (isResourcesInitialized) return;
|
||||
|
||||
synchronized (this) {
|
||||
@@ -137,9 +139,9 @@ public final class WorldSetup {
|
||||
|
||||
private int continueWorld() {
|
||||
Context ctx = androidContext.get();
|
||||
int result = Savegames.loadWorld(world, ctx, loadFromSlot);
|
||||
int result = Savegames.loadWorld(world, view, ctx, loadFromSlot);
|
||||
if (result == Savegames.LOAD_RESULT_SUCCESS) {
|
||||
MovementController.cacheCurrentMapData(ctx.getResources(), world, world.model.currentMap);
|
||||
view.movementController.cacheCurrentMapData(ctx.getResources(), world.model.currentMap);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -148,8 +150,10 @@ public final class WorldSetup {
|
||||
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(ctx.getResources());
|
||||
view.controller.lotsOfTimePassed();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
@@ -67,7 +67,7 @@ public final class AboutActivity extends Activity implements ImageGetter {
|
||||
tv.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
|
||||
TextView t = (TextView) findViewById(R.id.about_version);
|
||||
t.setText("v" + AndorsTrailApplication.CURRENT_VERSION_DISPLAY);
|
||||
t.setText('v' + AndorsTrailApplication.CURRENT_VERSION_DISPLAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,12 +78,13 @@ public final class AboutActivity extends Activity implements ImageGetter {
|
||||
Drawable r = res.getDrawable(R.drawable.ui_quickslots);
|
||||
r.setBounds(0, 0, r.getIntrinsicWidth(), r.getIntrinsicHeight());
|
||||
return r;
|
||||
} else if (s.equals("char_hero.png")) {
|
||||
}
|
||||
if (s.equals("char_hero.png")) {
|
||||
Drawable r = res.getDrawable(R.drawable.char_hero);
|
||||
r.setBounds(0, 0, r.getIntrinsicWidth(), r.getIntrinsicHeight()*4/5);
|
||||
return r;
|
||||
}
|
||||
else if (s.equals("monster.png")) d = res.getDrawable(R.drawable.monsters_eye4);
|
||||
if (s.equals("monster.png")) d = res.getDrawable(R.drawable.monsters_eye4);
|
||||
else if (s.equals("flee_example.png")) d = res.getDrawable(R.drawable.ui_flee_example);
|
||||
else if (s.equals("doubleattackexample.png")) d = res.getDrawable(R.drawable.ui_doubleattackexample);
|
||||
else return null;
|
||||
|
||||
@@ -17,7 +17,7 @@ import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionType;
|
||||
import com.gpl.rpg.AndorsTrail.view.AbilityModifierInfoView;
|
||||
import com.gpl.rpg.AndorsTrail.view.ItemEffectsView_OnUse;
|
||||
|
||||
public class ActorConditionInfoActivity extends Activity {
|
||||
public final class ActorConditionInfoActivity extends Activity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
@@ -25,9 +25,9 @@ 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();
|
||||
String conditionTypeID = getIntent().getData().getLastPathSegment();
|
||||
ActorConditionType conditionType = world.actorConditionsTypes.getActorConditionType(conditionTypeID);
|
||||
|
||||
setContentView(R.layout.actorconditioninfo);
|
||||
|
||||
@@ -28,32 +28,33 @@ import com.gpl.rpg.AndorsTrail.model.item.ItemType;
|
||||
* @author ejwessel
|
||||
* Creates the BulkSelectionInterface dialog that allows for buy/drop/selling
|
||||
*/
|
||||
public class BulkSelectionInterface extends Activity implements TextWatcher {
|
||||
public final class BulkSelectionInterface extends Activity implements TextWatcher {
|
||||
|
||||
// class variables
|
||||
final public static int BULK_INTERFACE_BUY = 0;
|
||||
final public static int BULK_INTERFACE_SELL = 1;
|
||||
final public static int BULK_INTERFACE_DROP = 2;
|
||||
public static final int BULK_INTERFACE_BUY = 0;
|
||||
public static final int BULK_INTERFACE_SELL = 1;
|
||||
public static final int BULK_INTERFACE_DROP = 2;
|
||||
|
||||
final private static int BUTTON_REPEAT_FIRST_TIME = 300; // Delay after the touch before the counting starts
|
||||
final private static int BUTTON_REPEAT_FURTHER_TIMES = 50; // Delay between two count events
|
||||
final private static int BUTTON_REPEAT_DOUBLE_AFTER = 10; // after how many count events the countValue doubles?
|
||||
private static final int BUTTON_REPEAT_FIRST_TIME = 300; // Delay after the touch before the counting starts
|
||||
private static final int BUTTON_REPEAT_FURTHER_TIMES = 50; // Delay between two count events
|
||||
private static final int BUTTON_REPEAT_DOUBLE_AFTER = 10; // after how many count events the countValue doubles?
|
||||
|
||||
private WorldContext world;
|
||||
private int interfaceType; // the type of interface either: BULK_INTERFACE_BUY, BULK_INTERFACE_SELL or BULK_INTERFACE_DROP
|
||||
private ItemType itemType;
|
||||
private int totalAvailableAmount;
|
||||
private int pricePerUnit;
|
||||
|
||||
private TextView bulkselection_amount_available;
|
||||
|
||||
private TextView bulkselection_summary_totalgold;
|
||||
private EditText bulkselection_amount_taken; // the amount we're going to take from the totalAmount
|
||||
private SeekBar bulkselection_slider;
|
||||
private Button okButton;
|
||||
|
||||
private final Handler timedEventHandler = new Handler(); // variables to count up or down on long presses on the buttons
|
||||
private int countValue, countTime;
|
||||
private int countValue;
|
||||
private int countTime;
|
||||
private final Runnable countEvent = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
incrementValueAndRepeat(BUTTON_REPEAT_FURTHER_TIMES);
|
||||
}
|
||||
@@ -73,8 +74,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();
|
||||
|
||||
@@ -92,7 +93,7 @@ public class BulkSelectionInterface extends Activity implements TextWatcher {
|
||||
// initialize UI variables
|
||||
TextView bulkselection_action_type = (TextView)findViewById(R.id.bulkselection_action_type);
|
||||
bulkselection_amount_taken = (EditText)findViewById(R.id.bulkselection_amount_taken);
|
||||
bulkselection_amount_available = (TextView)findViewById(R.id.bulkselection_amount_available);
|
||||
TextView bulkselection_amount_available = (TextView) findViewById(R.id.bulkselection_amount_available);
|
||||
bulkselection_slider = (SeekBar)findViewById(R.id.bulkselection_slider);
|
||||
bulkselection_summary_totalgold = (TextView)findViewById(R.id.bulkselection_summary_totalgold);
|
||||
okButton = (Button)findViewById(R.id.bulkselection_finalize_button);
|
||||
@@ -122,7 +123,7 @@ public class BulkSelectionInterface extends Activity implements TextWatcher {
|
||||
|
||||
// initialize the visual components visuals
|
||||
okButton.setText(actionText);
|
||||
bulkselection_action_type.setText(actionText + " ");
|
||||
bulkselection_action_type.setText(actionText + ' ');
|
||||
bulkselection_amount_available.setText(Integer.toString(totalAvailableAmount));
|
||||
bulkselection_slider.setMax(totalAvailableAmount - 1);
|
||||
|
||||
@@ -188,7 +189,7 @@ public class BulkSelectionInterface extends Activity implements TextWatcher {
|
||||
okButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (requiresConfirmation(itemType)) {
|
||||
if (requiresConfirmation()) {
|
||||
final String displayType = ItemInfoActivity.getDisplayTypeString(res, itemType).toLowerCase();
|
||||
final String message = res.getString(R.string.bulkselection_sell_confirmation, itemType.getName(world.model.player), displayType);
|
||||
|
||||
@@ -201,7 +202,7 @@ public class BulkSelectionInterface extends Activity implements TextWatcher {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
itemsResult(intent);
|
||||
}
|
||||
})
|
||||
})
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show();
|
||||
} else {
|
||||
@@ -209,7 +210,7 @@ public class BulkSelectionInterface extends Activity implements TextWatcher {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean requiresConfirmation(ItemType itemType) {
|
||||
private boolean requiresConfirmation() {
|
||||
if (interfaceType != BULK_INTERFACE_SELL) return false;
|
||||
if (itemType.isOrdinaryItem()) return false;
|
||||
return true;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -19,7 +19,7 @@ import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment.WorldMapSegmentMap;
|
||||
import com.gpl.rpg.AndorsTrail.util.L;
|
||||
|
||||
public class DisplayWorldMapActivity extends Activity {
|
||||
public final class DisplayWorldMapActivity extends Activity {
|
||||
private WorldContext world;
|
||||
|
||||
private WebView displayworldmap_webview;
|
||||
@@ -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);
|
||||
|
||||
@@ -76,9 +76,9 @@ public class DisplayWorldMapActivity extends Activity {
|
||||
WorldMapSegmentMap map = segment.maps.get(world.model.currentMap.name);
|
||||
if (map == null) this.finish();
|
||||
|
||||
String url = "file://" + worldmap.getAbsolutePath() + "?"
|
||||
String url = "file://" + worldmap.getAbsolutePath() + '?'
|
||||
+ (world.model.player.position.x + map.worldPosition.x) * WorldMapController.WORLDMAP_DISPLAY_TILESIZE
|
||||
+ ","
|
||||
+ ','
|
||||
+ (world.model.player.position.y + map.worldPosition.y-1) * WorldMapController.WORLDMAP_DISPLAY_TILESIZE;
|
||||
L.log("Showing " + url);
|
||||
displayworldmap_webview.loadUrl(url);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -35,11 +35,9 @@ public final class HeroinfoActivity_Inventory extends Activity {
|
||||
private TileCollection wornTiles;
|
||||
|
||||
private Player player;
|
||||
private ItemContainer container;
|
||||
private ItemContainerAdapter inventoryListAdapter;
|
||||
|
||||
private ListView inventoryList;
|
||||
private TextView heroinfo_stats_gold;
|
||||
private TextView heroinfo_stats_gold;
|
||||
private TextView heroinfo_stats_attack;
|
||||
private TextView heroinfo_stats_defense;
|
||||
|
||||
@@ -53,22 +51,22 @@ 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);
|
||||
|
||||
inventoryList = (ListView) findViewById(R.id.inventorylist_root);
|
||||
|
||||
ListView inventoryList = (ListView) findViewById(R.id.inventorylist_root);
|
||||
registerForContextMenu(inventoryList);
|
||||
inventoryList.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) {
|
||||
ItemType itemType = inventoryListAdapter.getItem(position).itemType;
|
||||
showInventoryItemInfo(itemType.id);
|
||||
}
|
||||
});
|
||||
container = player.inventory;
|
||||
ItemContainer container = player.inventory;
|
||||
wornTiles = world.tileManager.loadTilesFor(player.inventory, getResources());
|
||||
inventoryListAdapter = new ItemContainerAdapter(this, world.tileManager, container, player, wornTiles);
|
||||
inventoryList.setAdapter(inventoryListAdapter);
|
||||
@@ -95,17 +93,17 @@ public final class HeroinfoActivity_Inventory extends Activity {
|
||||
}
|
||||
|
||||
private void setWearSlot(final int inventorySlot, int viewId, int resourceId) {
|
||||
final ImageView view = (ImageView) findViewById(viewId);
|
||||
wornItemImage[inventorySlot] = view;
|
||||
final ImageView imageView = (ImageView) findViewById(viewId);
|
||||
wornItemImage[inventorySlot] = imageView;
|
||||
defaultWornItemImageResourceIDs[inventorySlot] = resourceId;
|
||||
view.setOnClickListener(new OnClickListener() {
|
||||
imageView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (player.inventory.isEmptySlot(inventorySlot)) return;
|
||||
view.setClickable(false); // Will be enabled again on update()
|
||||
imageView.setClickable(false); // Will be enabled again on update()
|
||||
showEquippedItemInfo(player.inventory.wear[inventorySlot], inventorySlot);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -120,7 +118,7 @@ public final class HeroinfoActivity_Inventory extends Activity {
|
||||
if (actionType == ItemInfoActivity.ITEMACTION_UNEQUIP) {
|
||||
view.itemController.unequipSlot(itemType, data.getExtras().getInt("inventorySlot"));
|
||||
} else if (actionType == ItemInfoActivity.ITEMACTION_EQUIP) {
|
||||
int slot = suggestInventorySlot(itemType, player);
|
||||
int slot = suggestInventorySlot(itemType);
|
||||
view.itemController.equipItem(itemType, slot);
|
||||
} else if (actionType == ItemInfoActivity.ITEMACTION_USE) {
|
||||
view.itemController.useItem(itemType);
|
||||
@@ -136,13 +134,12 @@ public final class HeroinfoActivity_Inventory extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
private static int suggestInventorySlot(ItemType itemType, Player player) {
|
||||
private int suggestInventorySlot(ItemType itemType) {
|
||||
int slot = itemType.category.inventorySlot;
|
||||
if (player.inventory.isEmptySlot(slot)) return slot;
|
||||
|
||||
if (slot == Inventory.WEARSLOT_LEFTRING) {
|
||||
return Inventory.WEARSLOT_RIGHTRING;
|
||||
} else if (itemType.isOffhandCapableWeapon()) {
|
||||
if (slot == Inventory.WEARSLOT_LEFTRING) return Inventory.WEARSLOT_RIGHTRING;
|
||||
if (itemType.isOffhandCapableWeapon()) {
|
||||
ItemType mainWeapon = player.inventory.wear[Inventory.WEARSLOT_WEAPON];
|
||||
if (mainWeapon != null && mainWeapon.isTwohandWeapon()) return slot;
|
||||
else if (player.inventory.isEmptySlot(Inventory.WEARSLOT_SHIELD)) return Inventory.WEARSLOT_SHIELD;
|
||||
@@ -164,7 +161,7 @@ public final class HeroinfoActivity_Inventory extends Activity {
|
||||
private void updateTraits() {
|
||||
heroinfo_stats_gold.setText(getResources().getString(R.string.heroinfo_gold, player.inventory.gold));
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringBuilder sb = new StringBuilder(10);
|
||||
ItemController.describeAttackEffect(
|
||||
player.getAttackChance(),
|
||||
player.getDamagePotential().current,
|
||||
@@ -174,7 +171,7 @@ public final class HeroinfoActivity_Inventory extends Activity {
|
||||
sb);
|
||||
heroinfo_stats_attack.setText(sb.toString());
|
||||
|
||||
sb = new StringBuilder();
|
||||
sb = new StringBuilder(10);
|
||||
ItemController.describeBlockEffect(player.getBlockChance(), player.getDamageResistance(), sb);
|
||||
heroinfo_stats_defense.setText(sb.toString());
|
||||
}
|
||||
@@ -185,13 +182,13 @@ public final class HeroinfoActivity_Inventory extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateWornImage(ImageView view, int resourceIDEmptyImage, ItemType type) {
|
||||
private void updateWornImage(ImageView imageView, int resourceIDEmptyImage, ItemType type) {
|
||||
if (type != null) {
|
||||
world.tileManager.setImageViewTile(view, type, wornTiles);
|
||||
world.tileManager.setImageViewTile(imageView, type, wornTiles);
|
||||
} else {
|
||||
view.setImageResource(resourceIDEmptyImage);
|
||||
imageView.setImageResource(resourceIDEmptyImage);
|
||||
}
|
||||
view.setClickable(true);
|
||||
imageView.setClickable(true);
|
||||
}
|
||||
|
||||
private void updateItemList() {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
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.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.controller.SkillController;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Player;
|
||||
import com.gpl.rpg.AndorsTrail.view.SkillListAdapter;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
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.model.actor.Player;
|
||||
import com.gpl.rpg.AndorsTrail.view.SkillListAdapter;
|
||||
|
||||
public final class HeroinfoActivity_Skills extends Activity {
|
||||
private WorldContext world;
|
||||
private ViewContext view;
|
||||
|
||||
private Player player;
|
||||
|
||||
@@ -29,7 +29,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);
|
||||
@@ -39,7 +40,7 @@ public final class HeroinfoActivity_Skills extends Activity {
|
||||
skillList.setAdapter(skillListAdapter);
|
||||
skillList.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) {
|
||||
Dialogs.showSkillInfo(HeroinfoActivity_Skills.this, (int) id);
|
||||
}
|
||||
});
|
||||
@@ -59,7 +60,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, world.skills.getSkill(skillID));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,7 @@ import android.widget.TableLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
public final class HeroinfoActivity_Stats extends Activity {
|
||||
private WorldContext world;
|
||||
|
||||
|
||||
private Player player;
|
||||
|
||||
private Button levelUpButton;
|
||||
@@ -50,7 +49,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;
|
||||
final WorldContext world = app.getWorld();
|
||||
this.player = world.model.player;
|
||||
|
||||
setContentView(R.layout.heroinfo_stats);
|
||||
@@ -114,15 +113,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(
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.gpl.rpg.AndorsTrail.activity;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
@@ -10,13 +8,14 @@ import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
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.item.ItemType;
|
||||
import com.gpl.rpg.AndorsTrail.view.ItemEffectsView;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public final class ItemInfoActivity extends Activity {
|
||||
|
||||
public static int ITEMACTION_NONE = 1;
|
||||
@@ -25,17 +24,15 @@ public final class ItemInfoActivity extends Activity {
|
||||
public static int ITEMACTION_UNEQUIP = 4;
|
||||
public static int ITEMACTION_BUY = 5;
|
||||
public static int ITEMACTION_SELL = 6;
|
||||
|
||||
private WorldContext world;
|
||||
|
||||
@Override
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
|
||||
if (!app.isInitialized()) { finish(); return; }
|
||||
this.world = app.world;
|
||||
final WorldContext world = app.getWorld();
|
||||
|
||||
AndorsTrailApplication.setWindowParameters(this, app.preferences);
|
||||
app.setWindowParameters(this);
|
||||
|
||||
final Intent intent = getIntent();
|
||||
Bundle params = intent.getExtras();
|
||||
@@ -55,9 +52,9 @@ public final class ItemInfoActivity extends Activity {
|
||||
|
||||
((ItemEffectsView) findViewById(R.id.iteminfo_effects)).update(
|
||||
itemType.effects_equip,
|
||||
itemType.effects_use == null ? null : Arrays.asList(itemType.effects_use),
|
||||
itemType.effects_hit == null ? null : Arrays.asList(itemType.effects_hit),
|
||||
itemType.effects_kill == null ? null : Arrays.asList(itemType.effects_kill),
|
||||
itemType.effects_use == null ? null : Collections.singletonList(itemType.effects_use),
|
||||
itemType.effects_hit == null ? null : Collections.singletonList(itemType.effects_hit),
|
||||
itemType.effects_kill == null ? null : Collections.singletonList(itemType.effects_kill),
|
||||
itemType.isWeapon()
|
||||
);
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ import android.widget.TextView;
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences;
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.Savegames;
|
||||
import com.gpl.rpg.AndorsTrail.Savegames.FileHeader;
|
||||
import com.gpl.rpg.AndorsTrail.savegames.Savegames;
|
||||
import com.gpl.rpg.AndorsTrail.savegames.Savegames.FileHeader;
|
||||
import com.gpl.rpg.AndorsTrail.model.ModelContainer;
|
||||
|
||||
public final class LoadSaveActivity extends Activity implements OnClickListener {
|
||||
@@ -34,11 +34,11 @@ 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();
|
||||
String loadsave = getIntent().getData().getLastPathSegment();
|
||||
isLoading = (loadsave.equalsIgnoreCase("load"));
|
||||
|
||||
setContentView(R.layout.loadsave);
|
||||
@@ -105,7 +105,8 @@ public final class LoadSaveActivity extends Activity implements OnClickListener
|
||||
|
||||
if (preferences.displayOverwriteSavegame == AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_ALWAYS) {
|
||||
return getString(R.string.loadsave_save_overwrite_confirmation_all);
|
||||
} else if (preferences.displayOverwriteSavegame == AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_NEVER) {
|
||||
}
|
||||
if (preferences.displayOverwriteSavegame == AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_NEVER) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -126,7 +127,7 @@ public final class LoadSaveActivity extends Activity implements OnClickListener
|
||||
|
||||
if (message != null) {
|
||||
final String title =
|
||||
getString(R.string.loadsave_save_overwrite_confirmation_title) + " "
|
||||
getString(R.string.loadsave_save_overwrite_confirmation_title) + ' '
|
||||
+ getString(R.string.loadsave_save_overwrite_confirmation_slot, slot);
|
||||
new AlertDialog.Builder(this)
|
||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||
|
||||
@@ -11,7 +11,7 @@ import android.os.Bundle;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.Savegames;
|
||||
import com.gpl.rpg.AndorsTrail.savegames.Savegames;
|
||||
import com.gpl.rpg.AndorsTrail.WorldSetup;
|
||||
import com.gpl.rpg.AndorsTrail.WorldSetup.OnResourcesLoadedListener;
|
||||
import com.gpl.rpg.AndorsTrail.WorldSetup.OnSceneLoadedListener;
|
||||
@@ -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
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
package com.gpl.rpg.AndorsTrail.activity;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences;
|
||||
import com.gpl.rpg.AndorsTrail.Dialogs;
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.Savegames;
|
||||
import com.gpl.rpg.AndorsTrail.savegames.Savegames;
|
||||
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 +48,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 +85,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<ViewContext>(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 +109,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 +149,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 +182,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 +200,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 +243,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;
|
||||
}
|
||||
});
|
||||
@@ -228,12 +263,12 @@ public final class MainActivity extends Activity {
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
if(quickitemview.isQuickButtonId(v.getId())){
|
||||
createQuickButtonMenu(menu, v, menuInfo);
|
||||
createQuickButtonMenu(menu);
|
||||
}
|
||||
lastSelectedMenu = null;
|
||||
}
|
||||
|
||||
private void createQuickButtonMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo){
|
||||
private void createQuickButtonMenu(ContextMenu menu){
|
||||
menu.add(Menu.NONE, R.id.quick_menu_unassign, Menu.NONE, R.string.inventory_unassign);
|
||||
SubMenu assignMenu = menu.addSubMenu(Menu.NONE, R.id.quick_menu_assign, Menu.NONE, R.string.inventory_assign);
|
||||
for(int i=0; i<world.model.player.inventory.items.size(); ++i){
|
||||
@@ -266,21 +301,15 @@ 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) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
private void message(String msg) {
|
||||
StringBuilder sb = new StringBuilder(100);
|
||||
for(int i = 0; i < NUM_MESSAGES-1; ++i) {
|
||||
messages[i] = messages[i + 1];
|
||||
if (messages[i].length() > 0) {
|
||||
@@ -294,7 +323,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 +342,145 @@ public final class MainActivity extends Activity {
|
||||
}
|
||||
t.show();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPlayerMoved(Coord newPosition, Coord previousPosition) { }
|
||||
|
||||
@Override
|
||||
public void onPlayerEnteredNewMap(PredefinedMap map, Coord p) { }
|
||||
|
||||
@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(Collection<Loot> 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(Collection<Loot> 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,18 +11,19 @@ import android.widget.TextView;
|
||||
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.model.actor.Monster;
|
||||
|
||||
public final class MonsterEncounterActivity extends Activity {
|
||||
private WorldContext world;
|
||||
|
||||
@Override
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
|
||||
if (!app.isInitialized()) { finish(); return; }
|
||||
this.world = app.world;
|
||||
final WorldContext world = app.getWorld();
|
||||
final ViewContext view = app.getViewContext();
|
||||
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
@@ -34,7 +35,7 @@ public final class MonsterEncounterActivity extends Activity {
|
||||
|
||||
setContentView(R.layout.monsterencounter);
|
||||
|
||||
CharSequence difficulty = getText(MonsterInfoActivity.getMonsterDifficultyResource(world, monster));
|
||||
CharSequence difficulty = getText(MonsterInfoActivity.getMonsterDifficultyResource(view, monster));
|
||||
|
||||
TextView tv = (TextView) findViewById(R.id.monsterencounter_title);
|
||||
tv.setText(monster.getName());
|
||||
@@ -50,7 +51,7 @@ public final class MonsterEncounterActivity extends Activity {
|
||||
setResult(RESULT_OK);
|
||||
MonsterEncounterActivity.this.finish();
|
||||
}
|
||||
});
|
||||
});
|
||||
b = (Button) findViewById(R.id.monsterencounter_cancel);
|
||||
b.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
@@ -58,13 +59,13 @@ public final class MonsterEncounterActivity extends Activity {
|
||||
setResult(RESULT_CANCELED);
|
||||
MonsterEncounterActivity.this.finish();
|
||||
}
|
||||
});
|
||||
});
|
||||
b = (Button) findViewById(R.id.monsterencounter_info);
|
||||
b.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
Dialogs.showMonsterInfo(MonsterEncounterActivity.this, monster);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
package com.gpl.rpg.AndorsTrail.activity;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
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.CombatController;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
|
||||
import com.gpl.rpg.AndorsTrail.view.ItemEffectsView;
|
||||
import com.gpl.rpg.AndorsTrail.view.RangeBar;
|
||||
import com.gpl.rpg.AndorsTrail.view.TraitsInfoView;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
public final class MonsterInfoActivity extends Activity {
|
||||
|
||||
private WorldContext world;
|
||||
private ViewContext view;
|
||||
|
||||
private TextView monsterinfo_title;
|
||||
private TextView monsterinfo_difficulty;
|
||||
@@ -36,7 +36,8 @@ 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();
|
||||
this.view = app.getViewContext();
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
setContentView(R.layout.monsterinfo);
|
||||
@@ -76,7 +77,7 @@ public final class MonsterInfoActivity extends Activity {
|
||||
private void updateTitle(Monster monster) {
|
||||
monsterinfo_title.setText(monster.getName());
|
||||
world.tileManager.setImageViewTile(monsterinfo_title, monster);
|
||||
monsterinfo_difficulty.setText(getMonsterDifficultyResource(world, monster));
|
||||
monsterinfo_difficulty.setText(getMonsterDifficultyResource(view, monster));
|
||||
}
|
||||
|
||||
private void updateTraits(Monster monster) {
|
||||
@@ -87,17 +88,17 @@ 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) {
|
||||
final int difficulty = CombatController.getMonsterDifficulty(world, monster);
|
||||
public static int getMonsterDifficultyResource(ViewContext viewContext, Monster monster) {
|
||||
final int difficulty = viewContext.combatController.getMonsterDifficulty(monster);
|
||||
if (difficulty >= 80) return R.string.monster_difficulty_veryeasy;
|
||||
else if (difficulty >= 60) return R.string.monster_difficulty_easy;
|
||||
else if (difficulty >= 40) return R.string.monster_difficulty_normal;
|
||||
else if (difficulty >= 20) return R.string.monster_difficulty_hard;
|
||||
else if (difficulty == 0) return R.string.monster_difficulty_impossible;
|
||||
else return R.string.monster_difficulty_veryhard;
|
||||
if (difficulty >= 60) return R.string.monster_difficulty_easy;
|
||||
if (difficulty >= 40) return R.string.monster_difficulty_normal;
|
||||
if (difficulty >= 20) return R.string.monster_difficulty_hard;
|
||||
if (difficulty == 0) return R.string.monster_difficulty_impossible;
|
||||
return R.string.monster_difficulty_veryhard;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,6 @@ public final class ShopActivity extends TabActivity implements OnContainerItemCl
|
||||
private WorldContext world;
|
||||
private Player player;
|
||||
|
||||
private ListView shoplist_buy;
|
||||
private ListView shoplist_sell;
|
||||
private ItemContainer container_buy;
|
||||
private TextView shop_buy_gc;
|
||||
private TextView shop_sell_gc;
|
||||
@@ -43,14 +41,13 @@ 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;
|
||||
|
||||
|
||||
setContentView(R.layout.shop);
|
||||
|
||||
final Resources res = getResources();
|
||||
@@ -65,9 +62,9 @@ public final class ShopActivity extends TabActivity implements OnContainerItemCl
|
||||
h.setup();
|
||||
shop_buy_gc = (TextView) h.findViewById(R.id.shop_buy_gc);
|
||||
shop_sell_gc = (TextView) h.findViewById(R.id.shop_sell_gc);
|
||||
|
||||
shoplist_buy = (ListView) h.findViewById(R.id.shop_buy_list);
|
||||
shoplist_sell = (ListView) h.findViewById(R.id.shop_sell_list);
|
||||
|
||||
ListView shoplist_buy = (ListView) h.findViewById(R.id.shop_buy_list);
|
||||
ListView shoplist_sell = (ListView) h.findViewById(R.id.shop_sell_list);
|
||||
|
||||
container_buy = npc.getShopItems(player);
|
||||
|
||||
@@ -95,7 +92,7 @@ public final class ShopActivity extends TabActivity implements OnContainerItemCl
|
||||
public void onItemInfoClicked(int position, ItemType itemType, boolean isSelling) {
|
||||
int price;
|
||||
int resid;
|
||||
boolean enableButton = true;
|
||||
boolean enableButton;
|
||||
int action;
|
||||
if (isSelling) {
|
||||
resid = R.string.shop_sellitem;
|
||||
|
||||
@@ -21,18 +21,16 @@ import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
public final class SkillInfoActivity extends Activity {
|
||||
private WorldContext world;
|
||||
private Player player;
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
|
||||
if (!app.isInitialized()) { finish(); return; }
|
||||
this.world = app.world;
|
||||
this.player = world.model.player;
|
||||
final WorldContext world = app.getWorld();
|
||||
final Player player = world.model.player;
|
||||
|
||||
AndorsTrailApplication.setWindowParameters(this, app.preferences);
|
||||
app.setWindowParameters(this);
|
||||
|
||||
setContentView(R.layout.skill_info_view);
|
||||
|
||||
|
||||
@@ -4,10 +4,11 @@ import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences;
|
||||
import com.gpl.rpg.AndorsTrail.Dialogs;
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.Savegames;
|
||||
import com.gpl.rpg.AndorsTrail.savegames.Savegames;
|
||||
import com.gpl.rpg.AndorsTrail.WorldSetup;
|
||||
import com.gpl.rpg.AndorsTrail.Savegames.FileHeader;
|
||||
import com.gpl.rpg.AndorsTrail.savegames.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,14 +40,15 @@ 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);
|
||||
|
||||
TextView tv = (TextView) findViewById(R.id.startscreen_version);
|
||||
tv.setText("v" + AndorsTrailApplication.CURRENT_VERSION_DISPLAY);
|
||||
tv.setText('v' + AndorsTrailApplication.CURRENT_VERSION_DISPLAY);
|
||||
|
||||
startscreen_currenthero = (TextView) findViewById(R.id.startscreen_currenthero);
|
||||
startscreen_enterheroname = (EditText) findViewById(R.id.startscreen_enterheroname);
|
||||
@@ -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);
|
||||
|
||||
if (AndorsTrailApplication.DEVELOPMENT_FORCE_STARTNEWGAME) {
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES) {
|
||||
@@ -123,7 +126,7 @@ public final class StartScreenActivity extends Activity {
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
String playerName = null;
|
||||
String playerName;
|
||||
String displayInfo = null;
|
||||
|
||||
FileHeader header = Savegames.quickload(this, Savegames.SLOT_QUICKSAVE);
|
||||
@@ -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;
|
||||
|
||||
@@ -1,49 +1,61 @@
|
||||
package com.gpl.rpg.AndorsTrail.context;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
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 final 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 WeakReference<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 = new WeakReference<AndorsTrailApplication>(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.get().getResources();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import com.gpl.rpg.AndorsTrail.model.map.MapCollection;
|
||||
import com.gpl.rpg.AndorsTrail.model.quest.QuestCollection;
|
||||
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
|
||||
|
||||
public class WorldContext {
|
||||
public final class WorldContext {
|
||||
//Objectcollections
|
||||
public final ConversationLoader conversationLoader;
|
||||
public final ItemTypeCollection itemTypes;
|
||||
|
||||
@@ -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.model.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 {
|
||||
public final 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,66 +118,66 @@ 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) {
|
||||
ActorCondition c = actor.conditions.get(i);
|
||||
if (!type.conditionTypeID.equals(c.conditionType.conditionTypeID)) continue;
|
||||
if (c.magnitude > e.magnitude) return;
|
||||
else if (c.magnitude == e.magnitude) {
|
||||
if (c.magnitude == e.magnitude) {
|
||||
if (c.duration >= duration) return;
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.ArrayList;
|
||||
|
||||
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;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
|
||||
@@ -25,21 +24,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<Loot> killedMonsterBags = new HashSet<Loot>();
|
||||
private final ArrayList<Loot> killedMonsterBags = new ArrayList<Loot>();
|
||||
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 +46,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;
|
||||
if (!killedMonsterBags.isEmpty()) {
|
||||
world.model.uiSelections.selectedPosition = null;
|
||||
world.model.uiSelections.selectedMonster = null;
|
||||
if (killedMonsterBags.isEmpty()) {
|
||||
view.gameRoundController.resume();
|
||||
} else {
|
||||
if (pickupLootBags) {
|
||||
lootCurrentMonsterBags();
|
||||
view.itemController.lootMonsterBags(killedMonsterBags, totalExpThisFight);
|
||||
}
|
||||
killedMonsterBags.clear();
|
||||
} else {
|
||||
context.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,27 +114,24 @@ 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) {
|
||||
if (isMonsterTurn()) {
|
||||
return;
|
||||
} else if (world.model.uiSelections.selectedMonster != null) {
|
||||
if (isMonsterTurn()) return;
|
||||
|
||||
if (world.model.uiSelections.selectedMonster != null) {
|
||||
executePlayerAttack();
|
||||
} else if (world.model.uiSelections.selectedPosition != null) {
|
||||
executeCombatMove(world.model.uiSelections.selectedPosition);
|
||||
@@ -157,46 +149,31 @@ 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);
|
||||
}
|
||||
|
||||
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;
|
||||
this.currentlyAttackedMonster = target;
|
||||
|
||||
final AttackResult attack = playerAttacks(world, target);
|
||||
if (view.effectController.isRunningVisualEffect()) return;
|
||||
if (!useAPs(world.model.player.getAttackCost())) return;
|
||||
final Monster target = world.model.uiSelections.selectedMonster;
|
||||
|
||||
final AttackResult attack = playerAttacks(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);
|
||||
playerKilledMonster(target);
|
||||
}
|
||||
|
||||
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 +193,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,12 +256,12 @@ 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);
|
||||
}
|
||||
|
||||
private final Handler monsterTurnHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
monsterTurnHandler.removeMessages(0);
|
||||
CombatController.this.handleNextMonsterAction();
|
||||
@@ -295,14 +269,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 +285,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 +298,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(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 +336,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 +360,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) {
|
||||
@@ -432,26 +393,26 @@ public final class CombatController implements VisualEffectCompletedCallback {
|
||||
if (averageDamagePerTurn <= 0) return 100;
|
||||
return (int) FloatMath.ceil(target.getMaxHP() / averageDamagePerTurn);
|
||||
}
|
||||
public static int getMonsterDifficulty(WorldContext world, Monster monster) {
|
||||
public int getMonsterDifficulty(Monster monster) {
|
||||
// returns [0..100) . 100 == easy.
|
||||
int turnsToKillMonster = getTurnsToKillTarget(world.model.player, monster);
|
||||
if (turnsToKillMonster >= 999) return 0;
|
||||
int turnsToKillPlayer = getTurnsToKillTarget(monster, world.model.player);
|
||||
int result = 50 + (turnsToKillPlayer - turnsToKillMonster) * 2;
|
||||
if (result <= 1) return 1;
|
||||
else if (result > 100) return 100;
|
||||
if (result > 100) return 100;
|
||||
return result;
|
||||
}
|
||||
|
||||
private AttackResult playerAttacks(WorldContext world, Monster currentMonster) {
|
||||
private AttackResult playerAttacks(Monster currentMonster) {
|
||||
AttackResult result = attack(world.model.player, currentMonster);
|
||||
SkillController.applySkillEffectsFromPlayerAttack(result, world, currentMonster);
|
||||
view.skillController.applySkillEffectsFromPlayerAttack(result, currentMonster);
|
||||
return result;
|
||||
}
|
||||
|
||||
private AttackResult monsterAttacks(ModelContainer model, Monster currentMonster) {
|
||||
AttackResult result = attack(currentMonster, model.player);
|
||||
SkillController.applySkillEffectsFromMonsterAttack(result, world, currentMonster);
|
||||
private AttackResult monsterAttacks(Monster currentMonster) {
|
||||
AttackResult result = attack(currentMonster, world.model.player);
|
||||
view.skillController.applySkillEffectsFromMonsterAttack(result, currentMonster);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -479,7 +440,7 @@ public final class CombatController implements VisualEffectCompletedCallback {
|
||||
}
|
||||
damage -= target.getDamageResistance();
|
||||
if (damage < 0) damage = 0;
|
||||
target.health.subtract(damage, false);
|
||||
view.actorStatsController.removeActorHealth(target, damage);
|
||||
|
||||
applyAttackHitStatusEffects(attacker, target);
|
||||
|
||||
@@ -491,7 +452,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 +463,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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ public final class Constants {
|
||||
public static final int FULLROUND_DURATION = 25000;
|
||||
public static final int TICKS_PER_ROUND = ROUND_DURATION / TICK_DELAY;
|
||||
public static final int TICKS_PER_FULLROUND = FULLROUND_DURATION / TICK_DELAY;
|
||||
public static final int SPLATTER_DURATION_MS = 20000;
|
||||
|
||||
public static final ConstRange monsterWaitTurns = new ConstRange(30,4);
|
||||
public static final long MAP_UNVISITED_RESPAWN_DURATION_MS = 3 * 60 * 1000; // 3 min in milliseconds
|
||||
|
||||
@@ -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,90 +14,91 @@ 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;
|
||||
int offset_x = position.x - o.position.topLeft.x;
|
||||
int offset_y = position.y - o.position.topLeft.y;
|
||||
view.movementController.placePlayerAt(MapObject.MAPEVENT_NEWMAP, o.map, o.place, offset_x, offset_y);
|
||||
view.movementController.placePlayerAsyncAt(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) {
|
||||
worldEventListeners.onPlayerSteppedOnRestArea(area);
|
||||
} else {
|
||||
rest(area);
|
||||
}
|
||||
}
|
||||
|
||||
public void steppedOnMonster(Monster m, Coord p) {
|
||||
if (m.isAgressive()) {
|
||||
view.combatController.setCombatSelection(m, p);
|
||||
if (!view.preferences.confirmAttack) {
|
||||
view.combatController.enterCombat(CombatController.BEGIN_TURN_PLAYER);
|
||||
if (view.preferences.confirmAttack) {
|
||||
worldEventListeners.onPlayerSteppedOnMonster(m);
|
||||
} else {
|
||||
Dialogs.showMonsterEncounter(view.mainActivity, view, m);
|
||||
view.combatController.enterCombat(CombatController.BEGIN_TURN_PLAYER);
|
||||
}
|
||||
} 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.respawnPlayerAsync();
|
||||
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;
|
||||
}
|
||||
|
||||
public static void resetMapsNotRecentlyVisited(final WorldContext world) {
|
||||
public void resetMapsNotRecentlyVisited() {
|
||||
for (PredefinedMap m : world.maps.predefinedMaps) {
|
||||
if (m == world.model.currentMap) continue;
|
||||
if (m.isRecentlyVisited()) continue;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,29 +2,29 @@ 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.GameRoundListeners;
|
||||
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 final GameRoundListeners gameRoundListeners = new GameRoundListeners();
|
||||
|
||||
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;
|
||||
|
||||
@Override
|
||||
public boolean onTick(TimedMessageTask task) {
|
||||
if (!world.model.uiSelections.isMainActivityVisible) return false;
|
||||
if (world.model.uiSelections.isInCombat) return false;
|
||||
|
||||
onNewTick();
|
||||
|
||||
@@ -44,8 +44,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,33 +60,34 @@ 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.controller.resetMapsNotRecentlyVisited();
|
||||
view.actorStatsController.applyConditionsToMonsters(world.model.currentMap, true);
|
||||
view.actorStatsController.applyConditionsToPlayer(world.model.player, true);
|
||||
gameRoundListeners.onNewFullRound();
|
||||
}
|
||||
|
||||
public void onNewRound() {
|
||||
onNewMonsterRound();
|
||||
onNewPlayerRound();
|
||||
gameRoundListeners.onNewRound();
|
||||
}
|
||||
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);
|
||||
gameRoundListeners.onNewTick();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
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 +18,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 +55,78 @@ 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 (loot.isVisible && pickupLootBagWithoutConfirmation()) {
|
||||
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(Collection<Loot> killedMonsterBags, int totalExpThisFight) {
|
||||
if (pickupLootBagWithoutConfirmation()) {
|
||||
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() {
|
||||
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,44 @@ 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<Loot> lootBags, ModelContainer model) {
|
||||
public void consumeNonItemLoot(Iterable<Loot> 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<Loot> lootBags, ModelContainer model) {
|
||||
public void pickupAll(Iterable<Loot> lootBags) {
|
||||
for(Loot l : lootBags) {
|
||||
pickupAll(l, model);
|
||||
pickupAll(l);
|
||||
}
|
||||
}
|
||||
public static boolean removeEmptyLoot(Loot loot, ModelContainer model) {
|
||||
if (!loot.hasItems()) {
|
||||
model.currentMap.removeGroundLoot(loot);
|
||||
return true; // The bag was removed.
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
public boolean removeLootBagIfEmpty(final Loot loot) {
|
||||
if (loot.hasItems()) return false;
|
||||
|
||||
world.model.currentMap.removeGroundLoot(loot);
|
||||
lootBagListeners.onLootBagRemoved(world.model.currentMap, loot.position);
|
||||
return true; // The bag was removed.
|
||||
}
|
||||
|
||||
public static boolean updateLootVisibility(final ViewContext context, final Iterable<Loot> lootBags) {
|
||||
public boolean removeLootBagIfEmpty(final Iterable<Loot> 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 +337,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,54 +2,65 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
PredefinedMap map = world.model.currentMap;
|
||||
m.nextActionTime += getMillisecondsPerMove(m);
|
||||
if (m.movementDestination == null) {
|
||||
// Monster has waited and should start to move again.
|
||||
@@ -69,25 +80,26 @@ public final class MonsterMovementController {
|
||||
,m.position.y + sgn(m.movementDestination.y - m.position.y)
|
||||
);
|
||||
|
||||
if (!model.currentMap.monsterCanMoveTo(m.nextPosition)) {
|
||||
if (!monsterCanMoveTo(map, 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(new Coord(m.position), m.rectPosition.size);
|
||||
m.position.set(m.nextPosition.topLeft);
|
||||
monsterMovementListeners.onMonsterMoved(map, m, previousPosition);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void cancelCurrentMonsterMovement(final Monster m) {
|
||||
private static void cancelCurrentMonsterMovement(final Monster m) {
|
||||
m.movementDestination = null;
|
||||
m.nextActionTime += getMillisecondsPerMove(m) * Constants.rollValue(Constants.monsterWaitTurns);
|
||||
}
|
||||
@@ -98,7 +110,7 @@ public final class MonsterMovementController {
|
||||
|
||||
private static int sgn(int i) {
|
||||
if (i <= -1) return -1;
|
||||
else if (i >= 1) return 1;
|
||||
if (i >= 1) return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(map, 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(map, m, m.rectPosition);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,24 +24,23 @@ 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);
|
||||
}
|
||||
|
||||
public void placePlayerAt(final int objectType, final String mapName, final String placeName, final int offset_x, final int offset_y) {
|
||||
public void placePlayerAsyncAt(final int objectType, final String mapName, final String placeName, final int offset_x, final int offset_y) {
|
||||
|
||||
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
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,9 +48,8 @@ public final class MovementController implements TimedMessageTask.Callback {
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
super.onPostExecute(result);
|
||||
view.mainActivity.clearMessages();
|
||||
view.mainActivity.mainview.notifyMapChanged(model);
|
||||
stopMovement();
|
||||
playerMovementListeners.onPlayerEnteredNewMap(world.model.currentMap, world.model.player.position);
|
||||
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) {
|
||||
@@ -74,33 +73,34 @@ public final class MovementController implements TimedMessageTask.Callback {
|
||||
final ModelContainer model = world.model;
|
||||
|
||||
if (model.currentMap != null) model.currentMap.updateLastVisitTime();
|
||||
cacheCurrentMapData(res, world, newMap);
|
||||
cacheCurrentMapData(res, newMap);
|
||||
model.currentMap = newMap;
|
||||
model.player.position.set(place.position.topLeft);
|
||||
model.player.position.x += Math.min(offset_x, place.position.size.width-1);
|
||||
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) playerVisitsMap(newMap);
|
||||
else playerVisitsMapFirstTime(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;
|
||||
private boolean mayMovePlayer() {
|
||||
return !world.model.uiSelections.isInCombat;
|
||||
}
|
||||
|
||||
private void movePlayer(int dx, int dy) {
|
||||
@@ -109,16 +109,16 @@ 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;
|
||||
}
|
||||
|
||||
moveToNextIfPossible(true);
|
||||
}
|
||||
|
||||
public boolean findWalkablePosition(int dx, int dy) {
|
||||
private boolean findWalkablePosition(int dx, int dy) {
|
||||
// try to move with movementAggresiveness, if that fails fall back to MOVEMENTAGGRESSIVENESS_NORMAL
|
||||
if (findWalkablePosition(dx, dy, view.preferences.movementAggressiveness)) return true;
|
||||
|
||||
@@ -127,21 +127,21 @@ public final class MovementController implements TimedMessageTask.Callback {
|
||||
return findWalkablePosition(dx, dy, AndorsTrailPreferences.MOVEMENTAGGRESSIVENESS_NORMAL);
|
||||
}
|
||||
|
||||
public boolean findWalkablePosition(int dx, int dy, int aggressiveness) {
|
||||
public boolean findWalkablePosition(int dx, int dy, int aggressiveness) {
|
||||
if (view.preferences.movementMethod == AndorsTrailPreferences.MOVEMENTMETHOD_STRAIGHT) {
|
||||
return findWalkablePosition_straight(dx, dy, aggressiveness);
|
||||
} else {
|
||||
return findWalkablePosition_directional(dx, dy, aggressiveness);
|
||||
}
|
||||
}
|
||||
public boolean findWalkablePosition_straight(int dx, int dy, int aggressiveness) {
|
||||
private boolean findWalkablePosition_straight(int dx, int dy, int aggressiveness) {
|
||||
if (tryWalkablePosition(sgn(dx), sgn(dy), aggressiveness)) return true; // try moving into the direction player is pointing at
|
||||
if (dx == 0 || dy == 0) return false; // if moving purely east, west, north or south failed - do nothing
|
||||
if (abs(dx) == abs(dy) && tryWalkablePosition(sgn(dx), 0, aggressiveness)) return true; // try moving horizontally or vertically otherwise (prefer the direction where he is pointing more)
|
||||
if (abs(dx) > abs(dy)) return tryWalkablePosition(sgn(dx), 0, aggressiveness);
|
||||
return tryWalkablePosition(0, sgn(dy), aggressiveness);
|
||||
}
|
||||
public boolean findWalkablePosition_directional(int dx, int dy, int aggressiveness) {
|
||||
private boolean findWalkablePosition_directional(int dx, int dy, int aggressiveness) {
|
||||
if (tryWalkablePosition(sgn(dx), sgn(dy), aggressiveness)) return true; // try moving into the direction player is pointing at
|
||||
|
||||
if (dx == 0) { // player wants to move north or south but there is an obstacle
|
||||
@@ -166,26 +166,26 @@ public final class MovementController implements TimedMessageTask.Callback {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean tryWalkablePosition(int dx, int dy, int aggressiveness) {
|
||||
final Player player = model.player;
|
||||
|
||||
private boolean tryWalkablePosition(int dx, int dy, int aggressiveness) {
|
||||
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;
|
||||
else if (aggressiveness == AndorsTrailPreferences.MOVEMENTAGGRESSIVENESS_DEFENSIVE && m != null) return false;
|
||||
if (aggressiveness == AndorsTrailPreferences.MOVEMENTAGGRESSIVENESS_DEFENSIVE && m != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -202,14 +202,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 +217,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,15 +228,19 @@ 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(Resources res) {
|
||||
placePlayerAt(res, MapObject.MAPEVENT_REST, world.model.player.getSpawnMap(), world.model.player.getSpawnPlace(), 0, 0);
|
||||
playerMovementListeners.onPlayerEnteredNewMap(world.model.currentMap, world.model.player.position);
|
||||
}
|
||||
public void respawnPlayerAsync() {
|
||||
placePlayerAsyncAt(MapObject.MAPEVENT_REST, world.model.player.getSpawnMap(), world.model.player.getSpawnPlace(), 0, 0);
|
||||
}
|
||||
|
||||
public static void moveBlockedActors(final WorldContext world) {
|
||||
public void moveBlockedActors() {
|
||||
final ModelContainer model = world.model;
|
||||
if (!world.model.currentMap.isWalkable(world.model.player.position)) {
|
||||
// If the player somehow spawned on an unwalkable tile, we move the player to the first mapchange area.
|
||||
@@ -257,7 +261,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);
|
||||
}
|
||||
@@ -266,7 +270,7 @@ public final class MovementController implements TimedMessageTask.Callback {
|
||||
}
|
||||
}
|
||||
|
||||
public static void cacheCurrentMapData(final Resources res, final WorldContext world, final PredefinedMap nextMap) {
|
||||
public void cacheCurrentMapData(final Resources res, final PredefinedMap nextMap) {
|
||||
LayeredTileMap mapTiles = TMXMapTranslator.readLayeredTileMap(res, world.tileManager.tileCache, nextMap);
|
||||
TileCollection cachedTiles = world.tileManager.loadTilesFor(nextMap, mapTiles, world, res);
|
||||
world.model.currentTileMap = mapTiles;
|
||||
@@ -280,7 +284,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 (!mayMovePlayer()) return;
|
||||
if (dx == 0 && dy == 0) return;
|
||||
|
||||
movementDx = dx;
|
||||
@@ -291,10 +295,11 @@ public final class MovementController implements TimedMessageTask.Callback {
|
||||
public void stopMovement() {
|
||||
movementHandler.stop();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
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);
|
||||
|
||||
|
||||
@@ -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,15 @@ 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 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 +36,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;
|
||||
@@ -87,14 +96,20 @@ public final class SkillController {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static void levelUpSkillManually(Player player, SkillInfo skill) {
|
||||
public void levelUpSkillManually(Player player, SkillInfo skill) {
|
||||
if (!canLevelupSkillManually(player, skill)) return;
|
||||
player.availableSkillIncreases -= 1;
|
||||
player.addSkillLevel(skill.id);
|
||||
addSkillLevel(skill.id);
|
||||
}
|
||||
public static void levelUpSkillByQuest(Player player, SkillInfo skill) {
|
||||
public void levelUpSkillByQuest(Player player, SkillInfo skill) {
|
||||
if (!canLevelupSkillWithQuest(player, skill)) return;
|
||||
player.addSkillLevel(skill.id);
|
||||
addSkillLevel(skill.id);
|
||||
}
|
||||
|
||||
private void addSkillLevel(int skillID) {
|
||||
Player player = world.model.player;
|
||||
player.skillLevels.put(skillID, player.skillLevels.get(skillID) + 1);
|
||||
view.actorStatsController.recalculatePlayerStats(player);
|
||||
}
|
||||
|
||||
public static int getActorConditionEffectChanceRollBias(ActorConditionEffect effect, Player player) {
|
||||
@@ -132,38 +147,38 @@ 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, 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, Monster monster) {
|
||||
if (!result.isHit) return;
|
||||
|
||||
Player player = world.model.player;
|
||||
|
||||
if (player.getAttackChance() - monster.getBlockChance() > SkillCollection.CONCUSSION_THRESHOLD) {
|
||||
if (rollForSkillChance(player, SkillCollection.SKILL_CONCUSSION, SkillCollection.PER_SKILLPOINT_INCREASE_CONCUSSION_CHANCE)) {
|
||||
addConditionToActor(monster, world, "concussion", 1, 5);
|
||||
addConditionToActor(monster, "concussion", 1, 5);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.isCriticalHit) {
|
||||
if (rollForSkillChance(player, SkillCollection.SKILL_CRIT2, SkillCollection.PER_SKILLPOINT_INCREASE_CRIT2_CHANCE)) {
|
||||
addConditionToActor(monster, world, "crit2", 1, 5);
|
||||
addConditionToActor(monster, "crit2", 1, 5);
|
||||
}
|
||||
|
||||
if (rollForSkillChance(player, SkillCollection.SKILL_CRIT1, SkillCollection.PER_SKILLPOINT_INCREASE_CRIT1_CHANCE)) {
|
||||
addConditionToActor(monster, world, "crit1", 1, 5);
|
||||
addConditionToActor(monster, "crit1", 1, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void applySkillEffectsFromMonsterAttack(AttackResult result, WorldContext world, Monster monster) {
|
||||
public void applySkillEffectsFromMonsterAttack(AttackResult result, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
private 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;
|
||||
}
|
||||
}
|
||||
@@ -106,9 +112,6 @@ public final class VisualEffectController {
|
||||
|
||||
|
||||
public static final class BloodSplatter {
|
||||
public static final int TYPE_RED = 0;
|
||||
public static final int TYPE_BROWN = 2;
|
||||
public static final int TYPE_WHITE = 3;
|
||||
public final long removeAfter;
|
||||
public final long reduceIconAfter;
|
||||
public final Coord position;
|
||||
@@ -117,32 +120,33 @@ public final class VisualEffectController {
|
||||
public BloodSplatter(int iconID, Coord position) {
|
||||
this.iconID = iconID;
|
||||
this.position = position;
|
||||
long now = System.currentTimeMillis();
|
||||
removeAfter = now + 20000;
|
||||
reduceIconAfter = now + 10000;
|
||||
final long now = System.currentTimeMillis();
|
||||
removeAfter = now + Constants.SPLATTER_DURATION_MS;
|
||||
reduceIconAfter = now + Constants.SPLATTER_DURATION_MS / 2;
|
||||
}
|
||||
}
|
||||
|
||||
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(map, b.position);
|
||||
} else if (!b.reducedIcon && b.reduceIconAfter <= now) {
|
||||
b.reducedIcon = true;
|
||||
b.iconID++;
|
||||
hasChanges = true;
|
||||
view.monsterSpawnController.monsterSpawnListeners.onSplatterChanged(map, 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(map, m.position);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getSplatterIconFromMonsterClass(int monsterClass) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
import android.content.Context;
|
||||
@@ -167,7 +168,7 @@ public final class WorldMapController {
|
||||
private static String getWorldMapSegmentAsHtml(Resources res, WorldContext world, String segmentName) throws IOException {
|
||||
WorldMapSegment segment = world.maps.worldMapSegments.get(segmentName);
|
||||
|
||||
HashSet<String> displayedMapNames = new HashSet<String>();
|
||||
Collection<String> displayedMapNames = new HashSet<String>();
|
||||
Coord offsetWorldmapTo = new Coord(999999, 999999);
|
||||
for (WorldMapSegmentMap map : segment.maps.values()) {
|
||||
if (!shouldDisplayMapOnWorldmap(map.mapName)) continue;
|
||||
@@ -178,8 +179,8 @@ public final class WorldMapController {
|
||||
}
|
||||
|
||||
Coord bottomRight = new Coord(0, 0);
|
||||
|
||||
StringBuffer mapsAsHtml = new StringBuffer();
|
||||
|
||||
StringBuilder mapsAsHtml = new StringBuilder(1000);
|
||||
for (WorldMapSegmentMap segmentMap : segment.maps.values()) {
|
||||
File f = WorldMapController.getFileForMap(segmentMap.mapName);
|
||||
if (!f.exists()) continue;
|
||||
@@ -199,7 +200,7 @@ public final class WorldMapController {
|
||||
.append("px; top:")
|
||||
.append((segmentMap.worldPosition.y - offsetWorldmapTo.y) * WorldMapController.WORLDMAP_DISPLAY_TILESIZE)
|
||||
.append("px;\" />");
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) mapsAsHtml.append("\n");
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) mapsAsHtml.append('\n');
|
||||
|
||||
bottomRight.x = Math.max(bottomRight.x, segmentMap.worldPosition.x + size.width);
|
||||
bottomRight.y = Math.max(bottomRight.y, segmentMap.worldPosition.y + size.height);
|
||||
@@ -208,8 +209,8 @@ public final class WorldMapController {
|
||||
(bottomRight.x - offsetWorldmapTo.x) * WorldMapController.WORLDMAP_DISPLAY_TILESIZE
|
||||
,(bottomRight.y - offsetWorldmapTo.y) * WorldMapController.WORLDMAP_DISPLAY_TILESIZE
|
||||
);
|
||||
|
||||
StringBuffer namedAreasAsHtml = new StringBuffer();
|
||||
|
||||
StringBuilder namedAreasAsHtml = new StringBuilder(500);
|
||||
for (NamedWorldMapArea area : segment.namedAreas.values()) {
|
||||
CoordRect r = determineNamedAreaBoundary(area, segment, world, displayedMapNames);
|
||||
if (r == null) continue;
|
||||
@@ -227,7 +228,7 @@ public final class WorldMapController {
|
||||
.append("px;\"><span>")
|
||||
.append(area.name)
|
||||
.append("</span></div>");
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) namedAreasAsHtml.append("\n");
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) namedAreasAsHtml.append('\n');
|
||||
}
|
||||
|
||||
return res.getString(R.string.worldmap_template)
|
||||
@@ -243,7 +244,7 @@ public final class WorldMapController {
|
||||
return world.maps.findPredefinedMap(map.mapName).size;
|
||||
}
|
||||
|
||||
private static CoordRect determineNamedAreaBoundary(NamedWorldMapArea area, WorldMapSegment segment, WorldContext world, HashSet<String> displayedMapNames) {
|
||||
private static CoordRect determineNamedAreaBoundary(NamedWorldMapArea area, WorldMapSegment segment, WorldContext world, Collection<String> displayedMapNames) {
|
||||
Coord topLeft = null;
|
||||
Coord bottomRight = null;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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.util.ListOfListeners;
|
||||
|
||||
public final class CombatActionListeners extends ListOfListeners<CombatActionListener> implements CombatActionListener {
|
||||
|
||||
private final Function2<CombatActionListener, Monster, AttackResult> onPlayerAttackMissed = new Function2<CombatActionListener, Monster, AttackResult>() {
|
||||
@Override public void call(CombatActionListener listener, Monster target, AttackResult attackResult) { listener.onPlayerAttackMissed(target, attackResult); }
|
||||
};
|
||||
|
||||
private final Function2<CombatActionListener, Monster, AttackResult> onPlayerAttackSuccess = new Function2<CombatActionListener, Monster, AttackResult>() {
|
||||
@Override public void call(CombatActionListener listener, Monster target, AttackResult attackResult) { listener.onPlayerAttackSuccess(target, attackResult); }
|
||||
};
|
||||
|
||||
private final Function2<CombatActionListener, Monster, AttackResult> onMonsterAttackMissed = new Function2<CombatActionListener, Monster, AttackResult>() {
|
||||
@Override public void call(CombatActionListener listener, Monster attacker, AttackResult attackResult) { listener.onMonsterAttackMissed(attacker, attackResult); }
|
||||
};
|
||||
|
||||
private final Function2<CombatActionListener, Monster, AttackResult> onMonsterAttackSuccess = new Function2<CombatActionListener, Monster, AttackResult>() {
|
||||
@Override public void call(CombatActionListener listener, Monster attacker, AttackResult attackResult) { listener.onMonsterAttackSuccess(attacker, attackResult); }
|
||||
};
|
||||
|
||||
private final Function1<CombatActionListener, Monster> onPlayerKilledMonster = new Function1<CombatActionListener, Monster>() {
|
||||
@Override public void call(CombatActionListener listener, Monster target) { listener.onPlayerKilledMonster(target); }
|
||||
};
|
||||
|
||||
private final Function<CombatActionListener> onPlayerStartedFleeing = new Function<CombatActionListener>() {
|
||||
@Override public void call(CombatActionListener listener) { listener.onPlayerStartedFleeing(); }
|
||||
};
|
||||
|
||||
private final Function<CombatActionListener> onPlayerFailedFleeing = new Function<CombatActionListener>() {
|
||||
@Override public void call(CombatActionListener listener) { listener.onPlayerFailedFleeing(); }
|
||||
};
|
||||
|
||||
private final Function<CombatActionListener> onPlayerDoesNotHaveEnoughAP = new Function<CombatActionListener>() {
|
||||
@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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
import com.gpl.rpg.AndorsTrail.util.Coord;
|
||||
|
||||
public final class CombatSelectionListeners extends ListOfListeners<CombatSelectionListener> implements CombatSelectionListener {
|
||||
|
||||
private final Function3<CombatSelectionListener, Monster, Coord, Coord> onMonsterSelected = new Function3<CombatSelectionListener, Monster, Coord, Coord>() {
|
||||
@Override public void call(CombatSelectionListener listener, Monster monster, Coord selectedPosition, Coord previousSelection) { listener.onMonsterSelected(monster, selectedPosition, previousSelection); }
|
||||
};
|
||||
|
||||
private final Function2<CombatSelectionListener, Coord, Coord> onMovementDestinationSelected = new Function2<CombatSelectionListener, Coord, Coord>() {
|
||||
@Override public void call(CombatSelectionListener listener, Coord selectedPosition, Coord previousSelection) { listener.onMovementDestinationSelected(selectedPosition, previousSelection); }
|
||||
};
|
||||
|
||||
private final Function1<CombatSelectionListener, Coord> onCombatSelectionCleared = new Function1<CombatSelectionListener, Coord>() {
|
||||
@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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
|
||||
public final class CombatTurnListeners extends ListOfListeners<CombatTurnListener> implements CombatTurnListener {
|
||||
|
||||
private final Function<CombatTurnListener> onCombatStarted = new Function<CombatTurnListener>() {
|
||||
@Override public void call(CombatTurnListener listener) { listener.onCombatStarted(); }
|
||||
};
|
||||
|
||||
private final Function<CombatTurnListener> onCombatEnded = new Function<CombatTurnListener>() {
|
||||
@Override public void call(CombatTurnListener listener) { listener.onCombatEnded(); }
|
||||
};
|
||||
|
||||
private final Function<CombatTurnListener> onNewPlayerTurn = new Function<CombatTurnListener>() {
|
||||
@Override public void call(CombatTurnListener listener) { listener.onNewPlayerTurn(); }
|
||||
};
|
||||
|
||||
private final Function1<CombatTurnListener, Monster> onMonsterIsAttacking = new Function1<CombatTurnListener, Monster>() {
|
||||
@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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
public interface GameRoundListener {
|
||||
void onNewTick();
|
||||
void onNewRound();
|
||||
void onNewFullRound();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
|
||||
public final class GameRoundListeners extends ListOfListeners<GameRoundListener> implements GameRoundListener {
|
||||
|
||||
private final Function<GameRoundListener> onNewTick = new Function<GameRoundListener>() {
|
||||
@Override public void call(GameRoundListener listener) { listener.onNewTick(); }
|
||||
};
|
||||
|
||||
private final Function<GameRoundListener> onNewRound = new Function<GameRoundListener>() {
|
||||
@Override public void call(GameRoundListener listener) { listener.onNewRound(); }
|
||||
};
|
||||
|
||||
private final Function<GameRoundListener> onNewFullRound = new Function<GameRoundListener>() {
|
||||
@Override public void call(GameRoundListener listener) { listener.onNewFullRound(); }
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onNewTick() {
|
||||
callAllListeners(this.onNewTick);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewRound() {
|
||||
callAllListeners(this.onNewRound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewFullRound() {
|
||||
callAllListeners(this.onNewFullRound);
|
||||
}
|
||||
}
|
||||
@@ -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 LootBagListener {
|
||||
void onLootBagCreated(PredefinedMap map, Coord p);
|
||||
void onLootBagRemoved(PredefinedMap map, Coord p);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
|
||||
import com.gpl.rpg.AndorsTrail.util.Coord;
|
||||
|
||||
public final class LootBagListeners extends ListOfListeners<LootBagListener> implements LootBagListener {
|
||||
|
||||
private final Function2<LootBagListener, PredefinedMap, Coord> onLootBagCreated = new Function2<LootBagListener, PredefinedMap, Coord>() {
|
||||
@Override public void call(LootBagListener listener, PredefinedMap map, Coord p) { listener.onLootBagCreated(map, p); }
|
||||
};
|
||||
|
||||
private final Function2<LootBagListener, PredefinedMap, Coord> onLootBagRemoved = new Function2<LootBagListener, PredefinedMap, Coord>() {
|
||||
@Override public void call(LootBagListener listener, PredefinedMap map, Coord p) { listener.onLootBagRemoved(map, p); }
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onLootBagCreated(PredefinedMap map, Coord p) {
|
||||
callAllListeners(this.onLootBagCreated, map, p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLootBagRemoved(PredefinedMap map, Coord p) {
|
||||
callAllListeners(this.onLootBagRemoved, map, p);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
|
||||
import com.gpl.rpg.AndorsTrail.util.CoordRect;
|
||||
|
||||
public interface MonsterMovementListener {
|
||||
void onMonsterSteppedOnPlayer(Monster m);
|
||||
void onMonsterMoved(PredefinedMap map, Monster m, CoordRect previousPosition);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
|
||||
import com.gpl.rpg.AndorsTrail.util.CoordRect;
|
||||
|
||||
public final class MonsterMovementListeners extends ListOfListeners<MonsterMovementListener> implements MonsterMovementListener {
|
||||
|
||||
private final Function1<MonsterMovementListener, Monster> onMonsterSteppedOnPlayer = new Function1<MonsterMovementListener, Monster>() {
|
||||
@Override public void call(MonsterMovementListener listener, Monster monster) { listener.onMonsterSteppedOnPlayer(monster); }
|
||||
};
|
||||
|
||||
private final Function3<MonsterMovementListener, PredefinedMap, Monster, CoordRect> onMonsterMoved = new Function3<MonsterMovementListener, PredefinedMap, Monster, CoordRect>() {
|
||||
@Override public void call(MonsterMovementListener listener, PredefinedMap map, Monster monster, CoordRect previousPosition) { listener.onMonsterMoved(map, monster, previousPosition); }
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onMonsterSteppedOnPlayer(Monster m) {
|
||||
callAllListeners(this.onMonsterSteppedOnPlayer, m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMonsterMoved(PredefinedMap map, Monster m, CoordRect previousPosition) {
|
||||
callAllListeners(this.onMonsterMoved, map, m, previousPosition);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
|
||||
import com.gpl.rpg.AndorsTrail.util.Coord;
|
||||
import com.gpl.rpg.AndorsTrail.util.CoordRect;
|
||||
|
||||
public interface MonsterSpawnListener {
|
||||
void onMonsterSpawned(PredefinedMap map, Monster m);
|
||||
void onMonsterRemoved(PredefinedMap map, Monster m, CoordRect previousPosition);
|
||||
void onSplatterAdded(PredefinedMap map, Coord p);
|
||||
void onSplatterChanged(PredefinedMap map, Coord p);
|
||||
void onSplatterRemoved(PredefinedMap map, Coord p);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
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 MonsterSpawnListeners extends ListOfListeners<MonsterSpawnListener> implements MonsterSpawnListener {
|
||||
|
||||
private final Function2<MonsterSpawnListener, PredefinedMap, Monster> onMonsterSpawned = new Function2<MonsterSpawnListener, PredefinedMap, Monster>() {
|
||||
@Override public void call(MonsterSpawnListener listener, PredefinedMap map, Monster monster) { listener.onMonsterSpawned(map, monster); }
|
||||
};
|
||||
|
||||
private final Function3<MonsterSpawnListener, PredefinedMap, Monster, CoordRect> onMonsterRemoved = new Function3<MonsterSpawnListener, PredefinedMap, Monster, CoordRect>() {
|
||||
@Override public void call(MonsterSpawnListener listener, PredefinedMap map, Monster monster, CoordRect previousPosition) { listener.onMonsterRemoved(map, monster, previousPosition); }
|
||||
};
|
||||
|
||||
private final Function2<MonsterSpawnListener, PredefinedMap, Coord> onSplatterAdded = new Function2<MonsterSpawnListener, PredefinedMap, Coord>() {
|
||||
@Override public void call(MonsterSpawnListener listener, PredefinedMap map, Coord p) { listener.onSplatterAdded(map, p); }
|
||||
};
|
||||
|
||||
private final Function2<MonsterSpawnListener, PredefinedMap, Coord> onSplatterChanged = new Function2<MonsterSpawnListener, PredefinedMap, Coord>() {
|
||||
@Override public void call(MonsterSpawnListener listener, PredefinedMap map, Coord p) { listener.onSplatterChanged(map, p); }
|
||||
};
|
||||
|
||||
private final Function2<MonsterSpawnListener, PredefinedMap, Coord> onSplatterRemoved = new Function2<MonsterSpawnListener, PredefinedMap, Coord>() {
|
||||
@Override public void call(MonsterSpawnListener listener, PredefinedMap map, Coord p) { listener.onSplatterRemoved(map, p); }
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onMonsterSpawned(PredefinedMap map, Monster m) {
|
||||
callAllListeners(this.onMonsterSpawned, map, m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMonsterRemoved(PredefinedMap map, Monster m, CoordRect previousPosition) {
|
||||
callAllListeners(this.onMonsterRemoved, map, m, previousPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplatterAdded(PredefinedMap map, Coord p) {
|
||||
callAllListeners(this.onSplatterAdded, map, p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplatterChanged(PredefinedMap map, Coord p) {
|
||||
callAllListeners(this.onSplatterChanged, map, p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplatterRemoved(PredefinedMap map, Coord p) {
|
||||
callAllListeners(this.onSplatterRemoved, map, p);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
|
||||
import com.gpl.rpg.AndorsTrail.util.Coord;
|
||||
|
||||
public final class PlayerMovementListeners extends ListOfListeners<PlayerMovementListener> implements PlayerMovementListener {
|
||||
|
||||
private final Function2<PlayerMovementListener, Coord, Coord> onPlayerMoved = new Function2<PlayerMovementListener, Coord, Coord>() {
|
||||
@Override public void call(PlayerMovementListener listener, Coord newPosition, Coord previousPosition) { listener.onPlayerMoved(newPosition, previousPosition); }
|
||||
};
|
||||
|
||||
private final Function2<PlayerMovementListener, PredefinedMap, Coord> onPlayerEnteredNewMap = new Function2<PlayerMovementListener, PredefinedMap, Coord>() {
|
||||
@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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
public interface QuickSlotListener {
|
||||
void onQuickSlotChanged(int slotId);
|
||||
void onQuickSlotUsed(int slotId);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
|
||||
public final class QuickSlotListeners extends ListOfListeners<QuickSlotListener> implements QuickSlotListener {
|
||||
|
||||
private final Function1<QuickSlotListener, Integer> onQuickSlotChanged = new Function1<QuickSlotListener, Integer>() {
|
||||
@Override public void call(QuickSlotListener listener, Integer slotId) { listener.onQuickSlotChanged(slotId); }
|
||||
};
|
||||
|
||||
private final Function1<QuickSlotListener, Integer> onQuickSlotUsed = new Function1<QuickSlotListener, Integer>() {
|
||||
@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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
|
||||
public final class VisualEffectFrameListeners extends ListOfListeners<VisualEffectFrameListener> implements VisualEffectFrameListener {
|
||||
|
||||
private final Function3<VisualEffectFrameListener, VisualEffectAnimation, Integer, Integer> onNewAnimationFrame = new Function3<VisualEffectFrameListener, VisualEffectAnimation, Integer, Integer>() {
|
||||
@Override public void call(VisualEffectFrameListener listener, VisualEffectAnimation animation, Integer tileID, Integer textYOffset) { listener.onNewAnimationFrame(animation, tileID, textYOffset); }
|
||||
};
|
||||
|
||||
private final Function1<VisualEffectFrameListener, VisualEffectAnimation> onAnimationCompleted = new Function1<VisualEffectFrameListener, VisualEffectAnimation>() {
|
||||
@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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
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;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
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(Collection<Loot> loot, int exp);
|
||||
void onPlayerPickedUpMonsterLoot(Collection<Loot> loot, int exp);
|
||||
void onPlayerRested();
|
||||
void onPlayerDied(int lostExp);
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
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.util.ListOfListeners;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.MapObject;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public final class WorldEventListeners extends ListOfListeners<WorldEventListener> implements WorldEventListener {
|
||||
|
||||
private final Function2<WorldEventListener, Monster, String> onPlayerStartedConversation = new Function2<WorldEventListener, Monster, String>() {
|
||||
@Override public void call(WorldEventListener listener, Monster m, String phraseID) { listener.onPlayerStartedConversation(m, phraseID); }
|
||||
};
|
||||
|
||||
private final Function1<WorldEventListener, Monster> onPlayerSteppedOnMonster = new Function1<WorldEventListener, Monster>() {
|
||||
@Override public void call(WorldEventListener listener, Monster m) { listener.onPlayerSteppedOnMonster(m); }
|
||||
};
|
||||
|
||||
private final Function1<WorldEventListener, MapObject> onPlayerSteppedOnMapSignArea = new Function1<WorldEventListener, MapObject>() {
|
||||
@Override public void call(WorldEventListener listener, MapObject area) { listener.onPlayerSteppedOnMapSignArea(area); }
|
||||
};
|
||||
|
||||
private final Function1<WorldEventListener, MapObject> onPlayerSteppedOnKeyArea = new Function1<WorldEventListener, MapObject>() {
|
||||
@Override public void call(WorldEventListener listener, MapObject area) { listener.onPlayerSteppedOnKeyArea(area); }
|
||||
};
|
||||
|
||||
private final Function1<WorldEventListener, MapObject> onPlayerSteppedOnRestArea = new Function1<WorldEventListener, MapObject>() {
|
||||
@Override public void call(WorldEventListener listener, MapObject area) { listener.onPlayerSteppedOnRestArea(area); }
|
||||
};
|
||||
|
||||
private final Function1<WorldEventListener, Loot> onPlayerSteppedOnGroundLoot = new Function1<WorldEventListener, Loot>() {
|
||||
@Override public void call(WorldEventListener listener, Loot loot) { listener.onPlayerSteppedOnGroundLoot(loot); }
|
||||
};
|
||||
|
||||
private final Function1<WorldEventListener, Loot> onPlayerPickedUpGroundLoot = new Function1<WorldEventListener, Loot>() {
|
||||
@Override public void call(WorldEventListener listener, Loot loot) { listener.onPlayerPickedUpGroundLoot(loot); }
|
||||
};
|
||||
|
||||
private final Function2<WorldEventListener, Collection<Loot>, Integer> onPlayerFoundMonsterLoot = new Function2<WorldEventListener, Collection<Loot>, Integer>() {
|
||||
@Override public void call(WorldEventListener listener, Collection<Loot> loot, Integer exp) { listener.onPlayerFoundMonsterLoot(loot, exp); }
|
||||
};
|
||||
|
||||
private final Function2<WorldEventListener, Collection<Loot>, Integer> onPlayerPickedUpMonsterLoot = new Function2<WorldEventListener, Collection<Loot>, Integer>() {
|
||||
@Override public void call(WorldEventListener listener, Collection<Loot> loot, Integer exp) { listener.onPlayerPickedUpMonsterLoot(loot, exp); }
|
||||
};
|
||||
|
||||
private final Function<WorldEventListener> onPlayerRested = new Function<WorldEventListener>() {
|
||||
@Override public void call(WorldEventListener listener) { listener.onPlayerRested(); }
|
||||
};
|
||||
|
||||
private final Function1<WorldEventListener, Integer> onPlayerDied = new Function1<WorldEventListener, Integer>() {
|
||||
@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(Collection<Loot> loot, int exp) {
|
||||
callAllListeners(this.onPlayerFoundMonsterLoot, loot, exp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerPickedUpMonsterLoot(Collection<Loot> 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);
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.io.IOException;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
|
||||
public class ActorCondition {
|
||||
public final class ActorCondition {
|
||||
public static final int MAGNITUDE_REMOVE_ALL = -99;
|
||||
public static final int DURATION_FOREVER = 999;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.resource.parsers.ActorConditionsTypeParser;
|
||||
import com.gpl.rpg.AndorsTrail.util.L;
|
||||
|
||||
public class ActorConditionTypeCollection {
|
||||
public final class ActorConditionTypeCollection {
|
||||
private final HashMap<String, ActorConditionType> conditionTypes = new HashMap<String, ActorConditionType>();
|
||||
|
||||
public ActorConditionType getActorConditionType(String conditionTypeID) {
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.gpl.rpg.AndorsTrail.model.ability;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Player;
|
||||
|
||||
public class SkillInfo {
|
||||
public final class SkillInfo {
|
||||
public static final int MAXLEVEL_NONE = -1;
|
||||
public static final int LEVELUP_TYPE_ALWAYS_SHOWN = 0;
|
||||
public static final int LEVELUP_TYPE_ONLY_BY_QUESTS = 1;
|
||||
|
||||
@@ -46,12 +46,6 @@ public final class AbilityModifierTraits {
|
||||
this.increaseDamageResistance = increaseDamageResistance;
|
||||
}
|
||||
|
||||
public boolean hasAttackChanceEffect() { return increaseAttackChance != 0; }
|
||||
public boolean hasAttackDamageEffect() { return increaseMinDamage != 0 || increaseMaxDamage != 0; }
|
||||
public boolean hasBlockEffect() { return increaseBlockChance != 0; }
|
||||
public boolean hasCriticalSkillEffect() { return increaseCriticalSkill != 0; }
|
||||
public boolean hasCriticalMultiplierEffect() { return setCriticalMultiplier != 0 && setCriticalMultiplier != 1; }
|
||||
|
||||
public int calculateCost(boolean isWeapon) {
|
||||
final int costBC = (int) (3*Math.pow(Math.max(0, increaseBlockChance), 2.5) + 28*increaseBlockChance);
|
||||
final int costAC = (int) (0.4*Math.pow(Math.max(0,increaseAttackChance), 2.5) - 6*Math.pow(Math.abs(Math.min(0,increaseAttackChance)),2.7));
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.gpl.rpg.AndorsTrail.model.ability.traits;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.util.ConstRange;
|
||||
|
||||
public class StatsModifierTraits {
|
||||
public final class StatsModifierTraits {
|
||||
public static final int VISUAL_EFFECT_NONE = -1;
|
||||
public final int visualEffectID;
|
||||
public final ConstRange currentHPBoost;
|
||||
|
||||
@@ -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<ActorCondition> conditions = new ArrayList<ActorCondition>();
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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<String, HashSet<Integer> > questProgress = new HashMap<String, HashSet<Integer> >();
|
||||
private final SparseIntArray skillLevels = new SparseIntArray();
|
||||
private String spawnMap;
|
||||
private String spawnPlace;
|
||||
private final HashMap<String, Integer> alignments = new HashMap<String, Integer>();
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
Loot result = new Loot();
|
||||
for (Loot l : loot) {
|
||||
result.add(l);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public void clear() {
|
||||
exp = 0;
|
||||
|
||||
@@ -2,8 +2,9 @@ package com.gpl.rpg.AndorsTrail.model.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
|
||||
public class ActorConditionListeners extends ListOfListeners<ActorConditionListener> implements ActorConditionListener {
|
||||
public final class ActorConditionListeners extends ListOfListeners<ActorConditionListener> implements ActorConditionListener {
|
||||
|
||||
private final Function2<ActorConditionListener, Actor, ActorCondition> onActorConditionAdded = new Function2<ActorConditionListener, Actor, ActorCondition>() {
|
||||
@Override public void call(ActorConditionListener listener, Actor actor, ActorCondition condition) { listener.onActorConditionAdded(actor, condition); }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.gpl.rpg.AndorsTrail.model.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
|
||||
public final class ActorStatsListeners extends ListOfListeners<ActorStatsListener> implements ActorStatsListener {
|
||||
|
||||
private final Function1<ActorStatsListener, Actor> onActorHealthChanged = new Function1<ActorStatsListener, Actor>() {
|
||||
@Override public void call(ActorStatsListener listener, Actor actor) { listener.onActorHealthChanged(actor); }
|
||||
};
|
||||
|
||||
private final Function1<ActorStatsListener, Actor> onActorAPChanged = new Function1<ActorStatsListener, Actor>() {
|
||||
@Override public void call(ActorStatsListener listener, Actor actor) { listener.onActorAPChanged(actor); }
|
||||
};
|
||||
|
||||
private final Function2<ActorStatsListener, Actor, Integer> onActorAttackCostChanged = new Function2<ActorStatsListener, Actor, Integer>() {
|
||||
@Override public void call(ActorStatsListener listener, Actor actor, Integer newAttackCost) { listener.onActorAttackCostChanged(actor, newAttackCost); }
|
||||
};
|
||||
|
||||
private final Function2<ActorStatsListener, Actor, Integer> onActorMoveCostChanged = new Function2<ActorStatsListener, Actor, Integer>() {
|
||||
@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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.gpl.rpg.AndorsTrail.model.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Player;
|
||||
|
||||
public interface PlayerStatsListener {
|
||||
void onPlayerExperienceChanged(Player p);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.gpl.rpg.AndorsTrail.model.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Player;
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
|
||||
public final class PlayerStatsListeners extends ListOfListeners<PlayerStatsListener> implements PlayerStatsListener {
|
||||
|
||||
private final Function1<PlayerStatsListener, Player> onPlayerExperienceChanged = new Function1<PlayerStatsListener, Player>() {
|
||||
@Override public void call(PlayerStatsListener listener, Player p) { listener.onPlayerExperienceChanged(p); }
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onPlayerExperienceChanged(Player p) {
|
||||
callAllListeners(this.onPlayerExperienceChanged, p);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ public class ResourceFileTokenizer {
|
||||
private static final String columnSeparator = "\\|";
|
||||
private static final String fieldPattern = "([^\\|]*?|\\{\\s*\\{.*?\\}\\s*\\})" + columnSeparator;
|
||||
private static String repeat(String s, int count) {
|
||||
String result = s;
|
||||
for(int i = 1; i < count; ++i) result += s;
|
||||
return result;
|
||||
StringBuilder result = new StringBuilder(s);
|
||||
for(int i = 1; i < count; ++i) result.append(s);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public class ResourceFileTokenizer {
|
||||
|
||||
public ResourceFileTokenizer(int columns) {
|
||||
this.columns = columns;
|
||||
this.pattern = Pattern.compile("^" + repeat(fieldPattern, columns) + "$", Pattern.MULTILINE | Pattern.DOTALL);
|
||||
this.pattern = Pattern.compile('^' + repeat(fieldPattern, columns) + '$', Pattern.MULTILINE | Pattern.DOTALL);
|
||||
this.parts = new String[columns];
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class ResourceFileTokenizer {
|
||||
}
|
||||
}
|
||||
|
||||
public <T> Collection<String> tokenizeRows(String input, HashMap<String, T> dest, ResourceObjectParser<Pair<String, T>> parser) {
|
||||
public final <T> Collection<String> tokenizeRows(String input, HashMap<String, T> dest, ResourceObjectParser<Pair<String, T>> parser) {
|
||||
HashSet<String> ids = new HashSet<String>();
|
||||
ArrayList<Pair<String, T>> objects = new ArrayList<Pair<String, T>>();
|
||||
tokenizeRows(input, objects, parser);
|
||||
@@ -74,7 +74,7 @@ public class ResourceFileTokenizer {
|
||||
private static final Pattern outerPattern = Pattern.compile("^\\{(.*)\\}$", Pattern.MULTILINE | Pattern.DOTALL);
|
||||
private static final Pattern innerPattern = Pattern.compile("\\{(.*?)\\}", Pattern.MULTILINE | Pattern.DOTALL);
|
||||
|
||||
public <T> void tokenizeArray(String input, ArrayList<T> dest, ResourceObjectParser<T> parser) {
|
||||
public final <T> void tokenizeArray(String input, ArrayList<T> dest, ResourceObjectParser<T> parser) {
|
||||
Matcher matcher = outerPattern.matcher(input);
|
||||
if (!matcher.find()) return;
|
||||
|
||||
@@ -88,8 +88,8 @@ public class ResourceFileTokenizer {
|
||||
T parseRow(String[] parts);
|
||||
}
|
||||
|
||||
public static abstract class ResourceParserFor<T> extends ResourceFileTokenizer implements ResourceObjectParser<Pair<String, T>> {
|
||||
public ResourceParserFor(int columns) {
|
||||
public abstract static class ResourceParserFor<T> extends ResourceFileTokenizer implements ResourceObjectParser<Pair<String, T>> {
|
||||
protected ResourceParserFor(int columns) {
|
||||
super(columns);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
|
||||
public class TileCollection {
|
||||
public final class TileCollection {
|
||||
private final Bitmap[] bitmaps;
|
||||
public final int maxTileID;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.BitmapFactory.Options;
|
||||
|
||||
public class TileCutter {
|
||||
public final class TileCutter {
|
||||
private final ResourceFileTileset sourceFile;
|
||||
private final Bitmap tilesetImage;
|
||||
private boolean recycle = true;
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.gpl.rpg.AndorsTrail.model.actor.Monster;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.MonsterType;
|
||||
import com.gpl.rpg.AndorsTrail.util.Coord;
|
||||
|
||||
public class LegacySavegameFormatReaderForMonster {
|
||||
public final class LegacySavegameFormatReaderForMonster {
|
||||
public static Monster readFromParcel_pre_v25(DataInputStream src, int fileversion, MonsterType monsterType) throws IOException {
|
||||
Monster m = new Monster(monsterType);
|
||||
m.position.set(new Coord(src, fileversion));
|
||||
|
||||
@@ -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 {
|
||||
|
||||
209
AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/Savegames.java
Normal file
209
AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/Savegames.java
Normal file
@@ -0,0 +1,209 @@
|
||||
package com.gpl.rpg.AndorsTrail.savegames;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
|
||||
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.model.ModelContainer;
|
||||
import com.gpl.rpg.AndorsTrail.util.L;
|
||||
|
||||
public final class Savegames {
|
||||
public static final int SLOT_QUICKSAVE = 0;
|
||||
|
||||
public static final int LOAD_RESULT_SUCCESS = 0;
|
||||
public static final int LOAD_RESULT_UNKNOWN_ERROR = 1;
|
||||
public static final int LOAD_RESULT_FUTURE_VERSION = 2;
|
||||
|
||||
public static boolean saveWorld(WorldContext world, Context androidContext, int slot, String displayInfo) {
|
||||
try {
|
||||
// Create the savegame in a temporary memorystream first to ensure that the savegame can
|
||||
// be created correctly. We don't want to trash the user's file unneccessarily if there is an error.
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
saveWorld(world, bos, displayInfo);
|
||||
byte[] savegame = bos.toByteArray();
|
||||
bos.close();
|
||||
|
||||
FileOutputStream fos = getOutputFile(androidContext, slot);
|
||||
fos.write(savegame);
|
||||
fos.close();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
L.log("Error saving world: " + e.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static int loadWorld(WorldContext world, ViewContext view, Context androidContext, int slot) {
|
||||
try {
|
||||
FileInputStream fos = getInputFile(androidContext, slot);
|
||||
int result = loadWorld(world, view, fos);
|
||||
fos.close();
|
||||
return result;
|
||||
} catch (IOException e) {
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
|
||||
L.log("Error loading world: " + e.toString());
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
L.log("Load error: " + sw.toString());
|
||||
}
|
||||
return LOAD_RESULT_UNKNOWN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
private static FileOutputStream getOutputFile(Context androidContext, int slot) throws IOException {
|
||||
if (slot == SLOT_QUICKSAVE) {
|
||||
return androidContext.openFileOutput(Constants.FILENAME_SAVEGAME_QUICKSAVE, Context.MODE_PRIVATE);
|
||||
} else {
|
||||
ensureSavegameDirectoryExists();
|
||||
return new FileOutputStream(getSlotFile(slot));
|
||||
}
|
||||
}
|
||||
private static void ensureSavegameDirectoryExists() {
|
||||
File root = Environment.getExternalStorageDirectory();
|
||||
File dir = new File(root, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
if (!dir.exists()) dir.mkdir();
|
||||
}
|
||||
private static FileInputStream getInputFile(Context androidContext, int slot) throws IOException {
|
||||
if (slot == SLOT_QUICKSAVE) {
|
||||
return androidContext.openFileInput(Constants.FILENAME_SAVEGAME_QUICKSAVE);
|
||||
} else {
|
||||
return new FileInputStream(getSlotFile(slot));
|
||||
}
|
||||
}
|
||||
private static File getSlotFile(int slot) {
|
||||
File root = getSavegameDirectory();
|
||||
return new File(root, Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + slot);
|
||||
}
|
||||
|
||||
private static File getSavegameDirectory() {
|
||||
File root = Environment.getExternalStorageDirectory();
|
||||
return new File(root, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
}
|
||||
|
||||
public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException {
|
||||
DataOutputStream dest = new DataOutputStream(outStream);
|
||||
final int flags = 0;
|
||||
FileHeader.writeToParcel(dest, world.model.player.getName(), displayInfo);
|
||||
world.maps.writeToParcel(dest, flags);
|
||||
world.model.writeToParcel(dest, flags);
|
||||
dest.close();
|
||||
}
|
||||
|
||||
public static int loadWorld(WorldContext world, ViewContext view, InputStream inState) throws IOException {
|
||||
DataInputStream src = new DataInputStream(inState);
|
||||
final FileHeader header = new FileHeader(src);
|
||||
if (header.fileversion > AndorsTrailApplication.CURRENT_VERSION) return LOAD_RESULT_FUTURE_VERSION;
|
||||
|
||||
world.maps.readFromParcel(src, world, view, header.fileversion);
|
||||
world.model = new ModelContainer(src, world, view, header.fileversion);
|
||||
src.close();
|
||||
|
||||
onWorldLoaded(world, view);
|
||||
|
||||
return LOAD_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
private static void onWorldLoaded(WorldContext world, ViewContext view) {
|
||||
view.actorStatsController.recalculatePlayerStats(world.model.player);
|
||||
view.controller.resetMapsNotRecentlyVisited();
|
||||
view.movementController.moveBlockedActors();
|
||||
}
|
||||
|
||||
public static FileHeader quickload(Context androidContext, int slot) {
|
||||
try {
|
||||
if (slot != SLOT_QUICKSAVE) {
|
||||
File f = getSlotFile(slot);
|
||||
if (!f.exists()) return null;
|
||||
}
|
||||
FileInputStream fos = getInputFile(androidContext, slot);
|
||||
DataInputStream src = new DataInputStream(fos);
|
||||
final FileHeader header = new FileHeader(src);
|
||||
src.close();
|
||||
fos.close();
|
||||
return header;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Pattern savegameFilenamePattern = Pattern.compile(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + "(\\d+)");
|
||||
public static List<Integer> getUsedSavegameSlots(Context androidContext) {
|
||||
try {
|
||||
final List<Integer> result = new ArrayList<Integer>();
|
||||
getSavegameDirectory().listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File f, String filename) {
|
||||
Matcher m = savegameFilenamePattern.matcher(filename);
|
||||
if (m != null && m.matches()) {
|
||||
result.add(Integer.parseInt(m.group(1)));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
Collections.sort(result);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class FileHeader {
|
||||
public final int fileversion;
|
||||
public final String playerName;
|
||||
public final String displayInfo;
|
||||
|
||||
public FileHeader(String playerName, String displayInfo) {
|
||||
this.fileversion = AndorsTrailApplication.CURRENT_VERSION;
|
||||
this.playerName = playerName;
|
||||
this.displayInfo = displayInfo;
|
||||
}
|
||||
|
||||
public String describe() {
|
||||
return playerName + ", " + displayInfo;
|
||||
}
|
||||
|
||||
|
||||
// ====== PARCELABLE ===================================================================
|
||||
|
||||
public FileHeader(DataInputStream src) throws IOException {
|
||||
int fileversion = src.readInt();
|
||||
if (fileversion == 11) fileversion = 5; // Fileversion 5 had no version identifier, but the first byte was 11.
|
||||
this.fileversion = fileversion;
|
||||
if (fileversion >= 14) { // Before fileversion 14 (0.6.7), we had no file header.
|
||||
this.playerName = src.readUTF();
|
||||
this.displayInfo = src.readUTF();
|
||||
} else {
|
||||
this.playerName = null;
|
||||
this.displayInfo = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeToParcel(DataOutputStream dest, String playerName, String displayInfo) throws IOException {
|
||||
dest.writeInt(AndorsTrailApplication.CURRENT_VERSION);
|
||||
dest.writeUTF(playerName);
|
||||
dest.writeUTF(displayInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ public final class Coord {
|
||||
public Coord(int x, int y) { this.x = x; this.y = y; }
|
||||
public Coord(Coord p) { this.x = p.x; this.y = p.y; }
|
||||
|
||||
public String toString() { return "(" + x + "," + y + ")"; }
|
||||
public String toString() { return "(" + x + ',' + y + ')'; }
|
||||
public void set(int x, int y) { this.x = x; this.y = y; }
|
||||
public void set(Coord r) {
|
||||
this.x = r.x;
|
||||
@@ -26,8 +26,8 @@ public final class Coord {
|
||||
final int dx = x - p.x;
|
||||
final int dy = y - p.y;
|
||||
if (dx == 0 && dy == 0) return false;
|
||||
else if (Math.abs(dx) > 1) return false;
|
||||
else if (Math.abs(dy) > 1) return false;
|
||||
if (Math.abs(dx) > 1) return false;
|
||||
if (Math.abs(dy) > 1) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,17 +17,17 @@ public final class CoordRect {
|
||||
}
|
||||
public boolean contains(Coord p) {
|
||||
if (p.x < topLeft.x) return false;
|
||||
else if (p.y < topLeft.y) return false;
|
||||
else if (p.x - topLeft.x >= size.width) return false;
|
||||
else if (p.y - topLeft.y >= size.height) return false;
|
||||
else return true;
|
||||
if (p.y < topLeft.y) return false;
|
||||
if (p.x - topLeft.x >= size.width) return false;
|
||||
if (p.y - topLeft.y >= size.height) return false;
|
||||
return true;
|
||||
}
|
||||
public boolean contains(final int x, final int y) {
|
||||
if (x < topLeft.x) return false;
|
||||
else if (y < topLeft.y) return false;
|
||||
else if (x - topLeft.x >= size.width) return false;
|
||||
else if (y - topLeft.y >= size.height) return false;
|
||||
else return true;
|
||||
if (y < topLeft.y) return false;
|
||||
if (x - topLeft.x >= size.width) return false;
|
||||
if (y - topLeft.y >= size.height) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -51,9 +51,9 @@ public final class CoordRect {
|
||||
final int dx = p.x - topLeft.x;
|
||||
final int dy = p.y - topLeft.y;
|
||||
if (dx < -1) return false;
|
||||
else if (dy < -1) return false;
|
||||
else if (dx > size.width) return false;
|
||||
else if (dy > size.height) return false;
|
||||
if (dy < -1) return false;
|
||||
if (dx > size.width) return false;
|
||||
if (dy > size.height) return false;
|
||||
return true;
|
||||
}
|
||||
public Coord findPositionAdjacentTo(Coord p) {
|
||||
@@ -69,6 +69,6 @@ public final class CoordRect {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "{" + topLeft.toString() + ", " + size.toString() + "}";
|
||||
return '{' + topLeft.toString() + ", " + size.toString() + '}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class L {
|
||||
public final class L {
|
||||
private static final String TAG = "AndorsTrail";
|
||||
|
||||
public static void log(String s) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.gpl.rpg.AndorsTrail.model.listeners;
|
||||
package com.gpl.rpg.AndorsTrail.util;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
@@ -8,7 +8,7 @@ import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
public class ListOfListeners<T> {
|
||||
private final ArrayList<WeakReference<T>> listeners = new ArrayList<WeakReference<T>>();
|
||||
|
||||
public void add(T listener) {
|
||||
public final void add(T listener) {
|
||||
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) {
|
||||
for (WeakReference<T> ref : listeners) {
|
||||
if (ref.get() == listener) {
|
||||
@@ -18,7 +18,7 @@ public class ListOfListeners<T> {
|
||||
}
|
||||
listeners.add(new WeakReference<T>(listener));
|
||||
}
|
||||
public void remove(T listenerToRemove) {
|
||||
public final void remove(T listenerToRemove) {
|
||||
for (int i = listeners.size()-1; i >= 0; --i) {
|
||||
T listener = listeners.get(i).get();
|
||||
if (listener == null || listener == listenerToRemove) {
|
||||
@@ -27,27 +27,34 @@ public class ListOfListeners<T> {
|
||||
}
|
||||
}
|
||||
|
||||
protected void callAllListeners(Function<T> e) {
|
||||
protected final void callAllListeners(Function<T> e) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
protected <Arg1> void callAllListeners(Function1<T, Arg1> e, Arg1 arg) {
|
||||
protected final <Arg1> void callAllListeners(Function1<T, Arg1> e, Arg1 arg) {
|
||||
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, arg);
|
||||
}
|
||||
}
|
||||
protected <Arg1, Arg2> void callAllListeners(Function2<T, Arg1, Arg2> e, Arg1 arg1, Arg2 arg2) {
|
||||
protected final <Arg1, Arg2> void callAllListeners(Function2<T, Arg1, Arg2> e, Arg1 arg1, Arg2 arg2) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
protected final <Arg1, Arg2, Arg3> void callAllListeners(Function3<T, Arg1, Arg2, Arg3> 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<Listener> {
|
||||
public void call(Listener listener);
|
||||
@@ -58,4 +65,7 @@ public class ListOfListeners<T> {
|
||||
protected static interface Function2<Listener, Arg1, Arg2> {
|
||||
public void call(Listener listener, Arg1 arg1, Arg2 arg2);
|
||||
}
|
||||
protected static interface Function3<Listener, Arg1, Arg2, Arg3> {
|
||||
public void call(Listener listener, Arg1 arg1, Arg2 arg2, Arg3 arg3);
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ import java.util.Map;
|
||||
* framework's implementation. See the framework SDK documentation for a class
|
||||
* overview.
|
||||
*/
|
||||
public class LruCache<K, V> {
|
||||
public final class LruCache<K, V> {
|
||||
private final LinkedHashMap<K, V> map;
|
||||
|
||||
/** Size of this cache in units. Not necessarily the number of elements. */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<ActorCondition> conditions) {
|
||||
|
||||
@@ -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() {
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActorAttackCostChanged(Actor actor, int newAttackCost) {
|
||||
if (actor == player) updateAttackMoveButtonText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActorMoveCostChanged(Actor actor, int newMoveCost) {
|
||||
if (actor == player) updateAttackMoveButtonText();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,33 +16,39 @@ 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;
|
||||
import com.gpl.rpg.AndorsTrail.model.listeners.ActorConditionListener;
|
||||
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
|
||||
|
||||
public class DisplayActiveActorConditionIcons implements ActorConditionListener {
|
||||
public final 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<ActiveConditionIcon> currentConditionIcons = new ArrayList<ActiveConditionIcon>();
|
||||
private final WeakReference<Context> 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<Context>(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 {
|
||||
@@ -168,7 +177,7 @@ public class DisplayActiveActorConditionIcons implements ActorConditionListener
|
||||
@Override public void onAnimationStart(Animation animation) { }
|
||||
}
|
||||
|
||||
protected void rearrangeIconsLeftOf(ActiveConditionIcon icon) {
|
||||
private void rearrangeIconsLeftOf(ActiveConditionIcon icon) {
|
||||
int i = currentConditionIcons.indexOf(icon);
|
||||
currentConditionIcons.remove(i);
|
||||
currentConditionIcons.add(icon);
|
||||
|
||||
@@ -7,6 +7,7 @@ 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.*;
|
||||
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 +32,15 @@ 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,
|
||||
GameRoundListener {
|
||||
|
||||
private final int tileSize;
|
||||
private float scale;
|
||||
@@ -58,18 +67,19 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac
|
||||
private TileCollection tiles;
|
||||
private final Coord playerPosition = new Coord();
|
||||
private Size surfaceSize;
|
||||
private boolean redrawNextTick = false;
|
||||
|
||||
public MainView(Context context, AttributeSet attr) {
|
||||
super(context, attr);
|
||||
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);
|
||||
|
||||
@@ -97,7 +107,7 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
||||
public void surfaceChanged(SurfaceHolder sh, int format, int w, int h) {
|
||||
if (w <= 0 || h <= 0) return;
|
||||
|
||||
this.scale = world.tileManager.scale;
|
||||
@@ -110,19 +120,19 @@ 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
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
public void surfaceCreated(SurfaceHolder sh) {
|
||||
hasSurface = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
public void surfaceDestroyed(SurfaceHolder sh) {
|
||||
hasSurface = false;
|
||||
}
|
||||
|
||||
@@ -152,25 +162,26 @@ 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;
|
||||
|
||||
public void redrawAll(int why) {
|
||||
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_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;
|
||||
|
||||
private void redrawAll(int why) {
|
||||
redrawArea_(mapViewArea);
|
||||
}
|
||||
public void redrawTile(final Coord p, int why) {
|
||||
private void redrawTile(final Coord p, int why) {
|
||||
p1x1.topLeft.set(p);
|
||||
redrawArea_(p1x1);
|
||||
}
|
||||
public void redrawArea(final CoordRect area, int why) {
|
||||
private void redrawArea(final CoordRect area, int why) {
|
||||
redrawArea_(area);
|
||||
}
|
||||
private void redrawArea_(CoordRect area) {
|
||||
@@ -205,7 +216,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) {
|
||||
private void redrawAreaWithEffect(final VisualEffectAnimation effect, int tileID, int textYOffset) {
|
||||
CoordRect area = effect.area;
|
||||
if (!hasSurface) return;
|
||||
if (shouldRedrawEverythingForVisualEffect()) area = mapViewArea;
|
||||
@@ -222,7 +233,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 {
|
||||
@@ -266,7 +277,7 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac
|
||||
private void doDrawRect(Canvas canvas, CoordRect area) {
|
||||
|
||||
drawMapLayer(canvas, area, currentTileMap.layers[LayeredTileMap.LAYER_GROUND]);
|
||||
tryDrawMapLayer(canvas, area, currentTileMap, LayeredTileMap.LAYER_OBJECTS);
|
||||
tryDrawMapLayer(canvas, area, LayeredTileMap.LAYER_OBJECTS);
|
||||
|
||||
for (BloodSplatter splatter : currentMap.splatters) {
|
||||
drawFromMapPosition(canvas, area, splatter.position, splatter.iconID);
|
||||
@@ -285,7 +296,7 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac
|
||||
}
|
||||
}
|
||||
|
||||
tryDrawMapLayer(canvas, area, currentTileMap, LayeredTileMap.LAYER_ABOVE);
|
||||
tryDrawMapLayer(canvas, area, LayeredTileMap.LAYER_ABOVE);
|
||||
|
||||
if (model.uiSelections.selectedPosition != null) {
|
||||
if (model.uiSelections.selectedMonster != null) {
|
||||
@@ -296,7 +307,7 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac
|
||||
}
|
||||
}
|
||||
|
||||
private void tryDrawMapLayer(Canvas canvas, final CoordRect area, final LayeredTileMap currentTileMap, final int layerIndex) {
|
||||
private void tryDrawMapLayer(Canvas canvas, final CoordRect area, final int layerIndex) {
|
||||
if (currentTileMap.layers.length > layerIndex) drawMapLayer(canvas, area, currentTileMap.layers[layerIndex]);
|
||||
}
|
||||
|
||||
@@ -338,9 +349,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 +391,131 @@ 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.gameRoundController.gameRoundListeners.add(this);
|
||||
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);
|
||||
view.gameRoundController.gameRoundListeners.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(PredefinedMap map, Monster m) {
|
||||
if (map != currentMap) return;
|
||||
if (!mapViewArea.intersects(m.rectPosition)) return;
|
||||
redrawNextTick = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMonsterRemoved(PredefinedMap map, Monster m, CoordRect previousPosition) {
|
||||
if (map != currentMap) return;
|
||||
if (!mapViewArea.intersects(m.rectPosition)) return;
|
||||
redrawArea(previousPosition, REDRAW_AREA_MONSTER_KILLED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMonsterSteppedOnPlayer(Monster m) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMonsterMoved(PredefinedMap map, Monster m, CoordRect previousPosition) {
|
||||
if (map != currentMap) return;
|
||||
if (!mapViewArea.intersects(m.rectPosition)) return;
|
||||
redrawNextTick = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplatterAdded(PredefinedMap map, Coord p) {
|
||||
if (map != currentMap) return;
|
||||
if (!mapViewArea.contains(p)) return;
|
||||
redrawNextTick = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplatterChanged(PredefinedMap map, Coord p) {
|
||||
if (map != currentMap) return;
|
||||
if (!mapViewArea.contains(p)) return;
|
||||
redrawNextTick = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplatterRemoved(PredefinedMap map, Coord p) {
|
||||
if (map != currentMap) return;
|
||||
if (!mapViewArea.contains(p)) return;
|
||||
redrawNextTick = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLootBagCreated(PredefinedMap map, Coord p) {
|
||||
if (map != currentMap) return;
|
||||
if (!mapViewArea.contains(p)) return;
|
||||
redrawTile(p, REDRAW_TILE_BAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLootBagRemoved(PredefinedMap map, Coord p) {
|
||||
if (map != currentMap) return;
|
||||
if (!mapViewArea.contains(p)) return;
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewTick() {
|
||||
if (!redrawNextTick) return;
|
||||
|
||||
redrawAll(REDRAW_ALL_PLAYER_MOVED);
|
||||
|
||||
redrawNextTick = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewRound() { }
|
||||
|
||||
@Override
|
||||
public void onNewFullRound() { }
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user