Compare commits
2 Commits
v0.8.4_com
...
v0.8.2_com
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32c3fe063e | ||
|
|
cbe6678ed6 |
BIN
AndorsTrail/.gradle/7.3.3/fileChanges/last-build.bin
Normal file
0
AndorsTrail/.gradle/7.3.3/gc.properties
Normal file
0
AndorsTrail/.gradle/vcs-1/gc.properties
Normal file
6
AndorsTrail/.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="11" />
|
||||
</component>
|
||||
</project>
|
||||
20
AndorsTrail/.idea/gradle.xml
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="1.8" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
25
AndorsTrail/.idea/jarRepositories.xml
generated
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="BintrayJCenter" />
|
||||
<option name="name" value="BintrayJCenter" />
|
||||
<option name="url" value="https://jcenter.bintray.com/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="Google" />
|
||||
<option name="name" value="Google" />
|
||||
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
||||
10
AndorsTrail/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
||||
6
AndorsTrail/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,13 +1,13 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 31
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion "30.0.3"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.gpl.rpg.AndorsTrail"
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 31
|
||||
targetSdkVersion 30
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
||||
@@ -3,11 +3,15 @@
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.gpl.rpg.AndorsTrail"
|
||||
android:versionCode="68"
|
||||
android:versionName="0.8.4"
|
||||
android:versionCode="66"
|
||||
android:versionName="0.8.2"
|
||||
android:installLocation="auto"
|
||||
>
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="4"
|
||||
android:targetSdkVersion="30"
|
||||
/>
|
||||
|
||||
<supports-screens
|
||||
android:smallScreens="true"
|
||||
android:normalScreens="true"
|
||||
@@ -33,7 +37,6 @@
|
||||
>
|
||||
<activity
|
||||
android:name="com.gpl.rpg.AndorsTrail.activity.StartScreenActivity"
|
||||
android:exported="true"
|
||||
android:clearTaskOnLaunch="true"
|
||||
>
|
||||
<intent-filter>
|
||||
|
||||
@@ -28,11 +28,11 @@ public final class AndorsTrailApplication extends Application {
|
||||
public static final boolean DEVELOPMENT_FASTSPEED = false;
|
||||
public static final boolean DEVELOPMENT_VALIDATEDATA = false;
|
||||
public static final boolean DEVELOPMENT_DEBUGMESSAGES = false;
|
||||
public static final String CURRENT_VERSION_DISPLAY = "0.8.4";
|
||||
public static final String CURRENT_VERSION_DISPLAY = "0.8.2";
|
||||
public static final boolean IS_RELEASE_VERSION = !CURRENT_VERSION_DISPLAY.matches(".*[a-d].*");
|
||||
public static final boolean DEVELOPMENT_INCOMPATIBLE_SAVEGAMES = DEVELOPMENT_DEBUGRESOURCES || DEVELOPMENT_DEBUGBUTTONS || DEVELOPMENT_FASTSPEED || !IS_RELEASE_VERSION;
|
||||
public static final int DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION = 999;
|
||||
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 68;
|
||||
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 66;
|
||||
|
||||
private final AndorsTrailPreferences preferences = new AndorsTrailPreferences();
|
||||
private WorldContext world = new WorldContext();
|
||||
|
||||
@@ -46,15 +46,14 @@ import com.gpl.rpg.AndorsTrail.model.item.Loot;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.MapObject;
|
||||
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
|
||||
import com.gpl.rpg.AndorsTrail.view.ItemContainerAdapter;
|
||||
|
||||
public final class Dialogs {
|
||||
|
||||
private static void showDialogAndPause(CustomDialog d, final ControllerContext context) {
|
||||
private static void showDialogAndPause(Dialog d, final ControllerContext context) {
|
||||
showDialogAndPause(d, context, null);
|
||||
}
|
||||
private static void showDialogAndPause(CustomDialog d, final ControllerContext context, final OnDismissListener onDismiss) {
|
||||
private static void showDialogAndPause(Dialog d, final ControllerContext context, final OnDismissListener onDismiss) {
|
||||
context.gameRoundController.pause();
|
||||
CustomDialogFactory.setDismissListener(d, new OnDismissListener() {
|
||||
@Override
|
||||
@@ -196,7 +195,7 @@ public final class Dialogs {
|
||||
// itemList.setPadding(20, 0, 20, 20);
|
||||
itemList.setAdapter(new ItemContainerAdapter(mainActivity, world.tileManager, combinedLoot.items, world.model.player));
|
||||
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(mainActivity,
|
||||
final Dialog d = CustomDialogFactory.createDialog(mainActivity,
|
||||
mainActivity.getResources().getString(title),
|
||||
mainActivity.getResources().getDrawable(R.drawable.ui_icon_equipment),
|
||||
msg,
|
||||
@@ -250,7 +249,7 @@ public final class Dialogs {
|
||||
}
|
||||
|
||||
public static void showHeroDied(final MainActivity mainActivity, final ControllerContext controllers) {
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(mainActivity,
|
||||
final Dialog d = CustomDialogFactory.createDialog(mainActivity,
|
||||
mainActivity.getResources().getString(R.string.dialog_game_over_title),
|
||||
mainActivity.getResources().getDrawable(R.drawable.ui_icon_combat),
|
||||
mainActivity.getResources().getString(R.string.dialog_game_over_text),
|
||||
@@ -287,7 +286,7 @@ public final class Dialogs {
|
||||
}
|
||||
|
||||
public static void showConfirmRest(final Activity currentActivity, final ControllerContext controllerContext, final MapObject area) {
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(currentActivity,
|
||||
final Dialog d = CustomDialogFactory.createDialog(currentActivity,
|
||||
currentActivity.getResources().getString(R.string.dialog_rest_title),
|
||||
null,
|
||||
currentActivity.getResources().getString(R.string.dialog_rest_confirm_message),
|
||||
@@ -311,7 +310,7 @@ public final class Dialogs {
|
||||
// .setMessage(R.string.dialog_rest_message)
|
||||
// .setNeutralButton(android.R.string.ok, null)
|
||||
// .create();
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(currentActivity,
|
||||
final Dialog d = CustomDialogFactory.createDialog(currentActivity,
|
||||
currentActivity.getResources().getString(R.string.dialog_rest_title),
|
||||
null,
|
||||
currentActivity.getResources().getString(R.string.dialog_rest_message),
|
||||
@@ -337,7 +336,7 @@ public final class Dialogs {
|
||||
text += currentActivity.getResources().getString(R.string.dialog_newversion_permission_information);
|
||||
}
|
||||
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(currentActivity,
|
||||
final Dialog d = CustomDialogFactory.createDialog(currentActivity,
|
||||
currentActivity.getResources().getString(R.string.dialog_newversion_title),
|
||||
null,
|
||||
text,
|
||||
@@ -372,7 +371,7 @@ public final class Dialogs {
|
||||
}
|
||||
|
||||
if (!world.model.statistics.hasUnlimitedSaves()) {
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(mainActivity,
|
||||
final Dialog d = CustomDialogFactory.createDialog(mainActivity,
|
||||
mainActivity.getResources().getString(R.string.menu_save_switch_character_title),
|
||||
null,
|
||||
mainActivity.getResources().getString(R.string.menu_save_switch_character),
|
||||
@@ -461,7 +460,7 @@ public final class Dialogs {
|
||||
itemList.setAdapter(new ArrayAdapter<String>(context, R.layout.combatlog_row, android.R.id.text1, combatLogMessages));
|
||||
view = itemList;
|
||||
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(context,
|
||||
final Dialog d = CustomDialogFactory.createDialog(context,
|
||||
context.getResources().getString(R.string.combat_log_title),
|
||||
context.getResources().getDrawable(R.drawable.ui_icon_combat),
|
||||
null,
|
||||
|
||||
@@ -23,7 +23,6 @@ import com.gpl.rpg.AndorsTrail.controller.ItemController;
|
||||
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
|
||||
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
|
||||
|
||||
/**
|
||||
* @author ejwessel
|
||||
@@ -207,7 +206,7 @@ public final class BulkSelectionInterface extends AndorsTrailBaseActivity implem
|
||||
// })
|
||||
// .setNegativeButton(android.R.string.no, null)
|
||||
// .show();
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(v.getContext(),
|
||||
final Dialog d = CustomDialogFactory.createDialog(v.getContext(),
|
||||
v.getContext().getResources().getString(R.string.bulkselection_sell_confirmation_title),
|
||||
v.getContext().getResources().getDrawable(android.R.drawable.ic_dialog_info),
|
||||
message,
|
||||
|
||||
@@ -20,12 +20,11 @@ import com.gpl.rpg.AndorsTrail.savegames.Savegames;
|
||||
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
|
||||
import com.gpl.rpg.AndorsTrail.view.CloudsAnimatorView;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
|
||||
|
||||
public final class LoadingActivity extends AndorsTrailBaseActivity implements OnResourcesLoadedListener, OnSceneLoadedListener {
|
||||
|
||||
private WorldSetup setup;
|
||||
private CustomDialog progressDialog;
|
||||
private Dialog progressDialog;
|
||||
private CloudsAnimatorView clouds_back, clouds_mid, clouds_front;
|
||||
boolean loaded = false;
|
||||
|
||||
@@ -166,7 +165,7 @@ public final class LoadingActivity extends AndorsTrailBaseActivity implements On
|
||||
}
|
||||
|
||||
private void showLoadingFailedDialog(int messageResourceID) {
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(this, getResources().getString(R.string.dialog_loading_failed_title), null, getResources().getString(messageResourceID), null, true);
|
||||
final Dialog d = CustomDialogFactory.createDialog(this, getResources().getString(R.string.dialog_loading_failed_title), null, getResources().getString(messageResourceID), null, true);
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.ok);
|
||||
CustomDialogFactory.setDismissListener(d, new OnDismissListener() {
|
||||
@Override
|
||||
|
||||
@@ -43,7 +43,6 @@ import com.gpl.rpg.AndorsTrail.util.Coord;
|
||||
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
|
||||
import com.gpl.rpg.AndorsTrail.view.CombatView;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
|
||||
import com.gpl.rpg.AndorsTrail.view.DisplayActiveActorConditionIcons;
|
||||
import com.gpl.rpg.AndorsTrail.view.ItemContainerAdapter;
|
||||
import com.gpl.rpg.AndorsTrail.view.MainView;
|
||||
@@ -248,7 +247,7 @@ public final class MainActivity
|
||||
final ItemContainerAdapter inventoryListAdapter = new QuickslotsItemContainerAdapter(lv.getContext(), world.tileManager, world.model.player.inventory.usableItems(), world.model.player, wornTiles);
|
||||
lv.setAdapter(inventoryListAdapter);
|
||||
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(v.getContext(),
|
||||
final Dialog d = CustomDialogFactory.createDialog(v.getContext(),
|
||||
v.getResources().getString(R.string.inventory_assign),
|
||||
v.getResources().getDrawable(R.drawable.ui_icon_equipment),
|
||||
v.getResources().getString(R.string.inventory_selectitem), view, false);
|
||||
|
||||
@@ -11,7 +11,6 @@ import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
|
||||
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
|
||||
import com.gpl.rpg.AndorsTrail.view.CloudsAnimatorView;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
@@ -115,7 +114,7 @@ public final class StartScreenActivity extends AndorsTrailBaseFragmentActivity i
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
|
||||
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(this,
|
||||
final Dialog d = CustomDialogFactory.createDialog(this,
|
||||
getResources().getString(R.string.dialog_permission_information_title),
|
||||
getResources().getDrawable(android.R.drawable.ic_dialog_info),
|
||||
getResources().getString(R.string.dialog_permission_information),
|
||||
|
||||
@@ -38,26 +38,25 @@ import com.gpl.rpg.AndorsTrail.util.AndroidStorage;
|
||||
import com.gpl.rpg.AndorsTrail.util.L;
|
||||
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
|
||||
|
||||
public class StartScreenActivity_MainMenu extends Fragment {
|
||||
|
||||
private static final int INTENTREQUEST_PREFERENCES = 7;
|
||||
public static final int INTENTREQUEST_LOADGAME = 9;
|
||||
private static final int INTENTREQUEST_PREFERENCES = 7;
|
||||
public static final int INTENTREQUEST_LOADGAME = 9;
|
||||
|
||||
private boolean hasExistingGame = false;
|
||||
private Button startscreen_continue;
|
||||
private Button startscreen_newgame;
|
||||
private Button startscreen_load;
|
||||
private ViewGroup save_preview_holder;
|
||||
private ImageView save_preview_hero_icon;
|
||||
private TextView save_preview_hero_desc;
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
updatePreferences(false);
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
private boolean hasExistingGame = false;
|
||||
private Button startscreen_continue;
|
||||
private Button startscreen_newgame;
|
||||
private Button startscreen_load;
|
||||
private ViewGroup save_preview_holder;
|
||||
private ImageView save_preview_hero_icon;
|
||||
private TextView save_preview_hero_desc;
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
updatePreferences(false);
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
|
||||
if (container != null) {
|
||||
@@ -65,11 +64,11 @@ public class StartScreenActivity_MainMenu extends Fragment {
|
||||
}
|
||||
|
||||
View root = inflater.inflate(R.layout.startscreen_mainmenu, container, false);
|
||||
|
||||
|
||||
save_preview_holder = (ViewGroup) root.findViewById(R.id.save_preview_holder);
|
||||
save_preview_hero_icon = (ImageView) root.findViewById(R.id.save_preview_hero_icon);
|
||||
save_preview_hero_desc = (TextView) root.findViewById(R.id.save_preview_hero_desc);
|
||||
|
||||
|
||||
|
||||
startscreen_continue = (Button) root.findViewById(R.id.startscreen_continue);
|
||||
startscreen_continue.setOnClickListener(new OnClickListener() {
|
||||
@@ -115,7 +114,7 @@ public class StartScreenActivity_MainMenu extends Fragment {
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(getActivity());
|
||||
if (hasExistingGame && app != null && app.getWorld() != null && app.getWorld().model != null
|
||||
&& app.getWorld().model.statistics != null && !app.getWorld().model.statistics.hasUnlimitedSaves()) {
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(getActivity(),
|
||||
final Dialog d = CustomDialogFactory.createDialog(getActivity(),
|
||||
getString(R.string.startscreen_load_game),
|
||||
getResources().getDrawable(android.R.drawable.ic_delete),
|
||||
getString(R.string.startscreen_load_game_confirm),
|
||||
@@ -135,7 +134,7 @@ public class StartScreenActivity_MainMenu extends Fragment {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
if (AndorsTrailApplication.DEVELOPMENT_FORCE_STARTNEWGAME) {
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES) {
|
||||
@@ -153,14 +152,14 @@ public class StartScreenActivity_MainMenu extends Fragment {
|
||||
checkAndRequestPermissions(getActivity());
|
||||
migrateDataOnDemand(getActivity());
|
||||
}
|
||||
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
|
||||
String playerName;
|
||||
String displayInfo = null;
|
||||
int iconID = TileManager.CHAR_HERO;
|
||||
@@ -190,10 +189,14 @@ public class StartScreenActivity_MainMenu extends Fragment {
|
||||
setCurrentVersionForVersionCheck();
|
||||
checkAndRequestPermissions(getActivity());
|
||||
migrateDataOnDemand(getActivity());
|
||||
boolean hasSavegames = !Savegames.getUsedSavegameSlots(getActivity()).isEmpty();
|
||||
startscreen_load.setEnabled(hasSavegames);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
boolean hasSavegames = !Savegames.getUsedSavegameSlots(getActivity()).isEmpty();
|
||||
startscreen_load.setEnabled(hasSavegames);
|
||||
}
|
||||
|
||||
@TargetApi(29)
|
||||
@@ -201,16 +204,23 @@ public class StartScreenActivity_MainMenu extends Fragment {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
if (AndroidStorage.shouldMigrateToInternalStorage(activity.getApplicationContext())) {
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(activity,
|
||||
final Dialog d = CustomDialogFactory.createDialog(activity,
|
||||
getString(R.string.startscreen_migration_title),
|
||||
activity.getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||
getString(R.string.startscreen_migration_text),
|
||||
null,
|
||||
true);
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.ok);
|
||||
d.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface arg0) {
|
||||
boolean hasSavegames = !Savegames.getUsedSavegameSlots(getActivity()).isEmpty();
|
||||
startscreen_load.setEnabled(hasSavegames);
|
||||
}
|
||||
});
|
||||
CustomDialogFactory.show(d);
|
||||
if (!AndroidStorage.migrateToInternalStorage(activity.getApplicationContext())) {
|
||||
final CustomDialog errorDlg = CustomDialogFactory.createDialog(activity,
|
||||
final Dialog errorDlg = CustomDialogFactory.createDialog(activity,
|
||||
getString(R.string.startscreen_migration_title),
|
||||
activity.getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||
getString(R.string.startscreen_migration_failure),
|
||||
@@ -249,13 +259,13 @@ public class StartScreenActivity_MainMenu extends Fragment {
|
||||
super.onAttach(activity);
|
||||
listener = (OnNewGameRequestedListener) activity;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
listener = null;
|
||||
}
|
||||
|
||||
|
||||
private void setButtonState(final String playerName, final String displayInfo, int iconID, boolean isDead) {
|
||||
startscreen_continue.setEnabled(hasExistingGame && !isDead);
|
||||
startscreen_newgame.setEnabled(true);
|
||||
@@ -295,9 +305,9 @@ public class StartScreenActivity_MainMenu extends Fragment {
|
||||
// .create().show();
|
||||
//
|
||||
//
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(getActivity(),
|
||||
getString(R.string.startscreen_newgame),
|
||||
getResources().getDrawable(android.R.drawable.ic_delete),
|
||||
final Dialog d = CustomDialogFactory.createDialog(getActivity(),
|
||||
getString(R.string.startscreen_newgame),
|
||||
getResources().getDrawable(android.R.drawable.ic_delete),
|
||||
getResources().getString(R.string.startscreen_newgame_confirm),
|
||||
null,
|
||||
true);
|
||||
@@ -308,9 +318,9 @@ public class StartScreenActivity_MainMenu extends Fragment {
|
||||
}
|
||||
});
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.cancel);
|
||||
|
||||
|
||||
CustomDialogFactory.show(d);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static final String versionCheck = "lastversion";
|
||||
@@ -327,90 +337,64 @@ public class StartScreenActivity_MainMenu extends Fragment {
|
||||
e.putInt(versionCheck, AndorsTrailApplication.CURRENT_VERSION);
|
||||
e.commit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode) {
|
||||
case INTENTREQUEST_LOADGAME:
|
||||
boolean unsuccessful = resultCode != Activity.RESULT_OK;
|
||||
if(data == null) break;
|
||||
|
||||
final boolean wasImportOrExport = data.getBooleanExtra("import_export", false);
|
||||
if (wasImportOrExport) {
|
||||
String message = getImportExportMessage(!unsuccessful, data);
|
||||
Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
if (unsuccessful) break;
|
||||
final int slot = data.getIntExtra("slot", 1);
|
||||
continueGame(false, slot, null);
|
||||
break;
|
||||
case INTENTREQUEST_PREFERENCES:
|
||||
updatePreferences(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private String getImportExportMessage(boolean successful, Intent data) {
|
||||
String message = "";
|
||||
boolean isImportWorldmap = data.getBooleanExtra("import_worldmap", false);
|
||||
boolean isImportSaves = data.getBooleanExtra("import_savegames", false);
|
||||
boolean isExport = data.getBooleanExtra("export", false);
|
||||
|
||||
if(isImportWorldmap) {
|
||||
message = getString(successful ? R.string.loadsave_import_worldmap_successfull : R.string.loadsave_import_worldmap_unsuccessfull);
|
||||
} else if(isImportSaves) {
|
||||
message = getString(successful ? R.string.loadsave_import_save_successfull : R.string.loadsave_import_save_unsuccessfull);
|
||||
} else if(isExport) {
|
||||
message = getString(successful ? R.string.loadsave_export_successfull : R.string.loadsave_export_unsuccessfull);
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode) {
|
||||
case INTENTREQUEST_LOADGAME:
|
||||
if (resultCode != Activity.RESULT_OK) break;
|
||||
final int slot = data.getIntExtra("slot", 1);
|
||||
continueGame(false, slot, null);
|
||||
break;
|
||||
case INTENTREQUEST_PREFERENCES:
|
||||
updatePreferences(true);
|
||||
break;
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
private void updatePreferences(boolean alreadyStartedLoadingResources) {
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(getActivity());
|
||||
AndorsTrailPreferences preferences = app.getPreferences();
|
||||
preferences.read(getActivity());
|
||||
if (app.setLocale(getActivity())) {
|
||||
if (alreadyStartedLoadingResources) {
|
||||
// Changing the locale after having loaded the game requires resources to
|
||||
// be re-loaded. Therefore, we just exit here.
|
||||
Toast.makeText(getActivity(), R.string.change_locale_requires_restart, Toast.LENGTH_LONG).show();
|
||||
doFinish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ThemeHelper.changeTheme(preferences.selectedTheme)) {
|
||||
// Changing the theme requires a restart to re-create all activities.
|
||||
Toast.makeText(getActivity(), R.string.change_theme_requires_restart, Toast.LENGTH_LONG).show();
|
||||
doFinish();
|
||||
return;
|
||||
}
|
||||
app.getWorld().tileManager.updatePreferences(preferences);
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private void doFinish() {
|
||||
//For Lollipop and above
|
||||
((AndorsTrailApplication)getActivity().getApplication()).discardWorld();
|
||||
getActivity().finish();
|
||||
}
|
||||
|
||||
private void updatePreferences(boolean alreadyStartedLoadingResources) {
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(getActivity());
|
||||
AndorsTrailPreferences preferences = app.getPreferences();
|
||||
preferences.read(getActivity());
|
||||
if (app.setLocale(getActivity())) {
|
||||
if (alreadyStartedLoadingResources) {
|
||||
// Changing the locale after having loaded the game requires resources to
|
||||
// be re-loaded. Therefore, we just exit here.
|
||||
Toast.makeText(getActivity(), R.string.change_locale_requires_restart, Toast.LENGTH_LONG).show();
|
||||
doFinish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ThemeHelper.changeTheme(preferences.selectedTheme)) {
|
||||
// Changing the theme requires a restart to re-create all activities.
|
||||
Toast.makeText(getActivity(), R.string.change_theme_requires_restart, Toast.LENGTH_LONG).show();
|
||||
doFinish();
|
||||
return;
|
||||
}
|
||||
app.getWorld().tileManager.updatePreferences(preferences);
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private void doFinish() {
|
||||
//For Lollipop and above
|
||||
((AndorsTrailApplication) getActivity().getApplication()).discardWorld();
|
||||
getActivity().finish();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public interface OnNewGameRequestedListener {
|
||||
public void onNewGameRequested();
|
||||
}
|
||||
|
||||
|
||||
private OnNewGameRequestedListener listener = null;
|
||||
|
||||
|
||||
private void createNewGame() {
|
||||
if (listener != null) {
|
||||
listener.onNewGameRequested();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -51,10 +51,6 @@ public final class Constants {
|
||||
public static final String CHEAT_DETECTION_FOLDER = "dEAGyGE3YojqXjI3x4x7";
|
||||
public static final String PASSIVE_ACHIEVEMENT_CHECK_PHRASE = "passive_achievement_check";
|
||||
|
||||
public static final String SAVEGAME_FILE_MIME_TYPE = "application/octet-stream";
|
||||
public static final String WORLDMAP_FILE_MIME_TYPE = "image/png";
|
||||
public static final String NO_FILE_EXTENSION_MIME_TYPE = "application/no_file_extension_mime_type";
|
||||
|
||||
public static final Random rnd = new Random();
|
||||
public static int rollValue(final ConstRange r) { return rollValue(r.max, r.current); }
|
||||
public static int rollValue(final ConstRange r, int bias) { return rollValue((r.max + 1) * 100 -1, r.current * 100 + bias)/100; }
|
||||
|
||||
@@ -83,7 +83,7 @@ public final class SkillCollection {
|
||||
public static final int PER_SKILLPOINT_INCREASE_COINFINDER_CHANCE_PERCENT = 30;
|
||||
public static final int PER_SKILLPOINT_INCREASE_MAGICFINDER_CHANCE_PERCENT = 50;
|
||||
public static final int PER_SKILLPOINT_INCREASE_COINFINDER_QUANTITY_PERCENT = 50;
|
||||
public static final int PER_SKILLPOINT_INCREASE_MORE_EXP_PERCENT = 10;
|
||||
public static final int PER_SKILLPOINT_INCREASE_MORE_EXP_PERCENT = 5;
|
||||
public static final int PER_SKILLPOINT_INCREASE_CLEAVE_AP = 3;
|
||||
public static final int PER_SKILLPOINT_INCREASE_EATER_HEALTH = 1;
|
||||
public static final int PER_SKILLPOINT_INCREASE_FORTITUDE_HEALTH = 1;
|
||||
|
||||
@@ -343,7 +343,6 @@ public final class ResourceLoader {
|
||||
loader.prepareTileset(R.drawable.obj_12, "obj_12", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_13, "obj_13", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_14, "obj_14", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_15, "obj_15", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_2, "obj_2", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_3, "obj_3", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_4, "obj_4", sz8x8, sz1x1, mTileSize);
|
||||
|
||||
@@ -86,7 +86,7 @@ public final class Savegames {
|
||||
|
||||
private static void writeBackup(Context androidContext, byte[] savegame, String playerId) throws IOException {
|
||||
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
|
||||
ensureDirExists(cheatDetectionFolder);
|
||||
if (!cheatDetectionFolder.exists()) cheatDetectionFolder.mkdir();
|
||||
File backupFile = new File(cheatDetectionFolder, playerId + "X");
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(backupFile);
|
||||
fileOutputStream.write(savegame);
|
||||
@@ -127,33 +127,34 @@ public final class Savegames {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean triedToCheat(Context androidContext, FileHeader fh) throws IOException {
|
||||
long savedVersionToCheck = 0;
|
||||
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
|
||||
ensureDirExists(cheatDetectionFolder);
|
||||
File cheatDetectionFile = new File(cheatDetectionFolder, fh.playerId);
|
||||
if (cheatDetectionFile.exists()) {
|
||||
FileInputStream fileInputStream = new FileInputStream(cheatDetectionFile);
|
||||
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
|
||||
final CheatDetection cheatDetection = new CheatDetection(dataInputStream);
|
||||
savedVersionToCheck = cheatDetection.savedVersion;
|
||||
dataInputStream.close();
|
||||
fileInputStream.close();
|
||||
}
|
||||
private static boolean triedToCheat(Context androidContext, FileHeader fh) throws IOException {
|
||||
long savedVersionToCheck = 0;
|
||||
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
|
||||
if (!cheatDetectionFolder.exists()) cheatDetectionFolder.mkdir();
|
||||
File cheatDetectionFile = new File(cheatDetectionFolder, fh.playerId);
|
||||
if (cheatDetectionFile.exists()) {
|
||||
FileInputStream fileInputStream = new FileInputStream(cheatDetectionFile);
|
||||
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
|
||||
final CheatDetection cheatDetection = new CheatDetection(dataInputStream);
|
||||
savedVersionToCheck = cheatDetection.savedVersion;
|
||||
dataInputStream.close();
|
||||
fileInputStream.close();
|
||||
}
|
||||
|
||||
if (savedVersionToCheck == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (androidContext.getFileStreamPath(fh.playerId).exists()) {
|
||||
FileInputStream fileInputStream = androidContext.openFileInput(fh.playerId);
|
||||
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
|
||||
final CheatDetection cheatDetection = new CheatDetection(dataInputStream);
|
||||
if (cheatDetection.savedVersion == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED) {
|
||||
savedVersionToCheck = DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED;
|
||||
} else if (cheatDetection.savedVersion > savedVersionToCheck) {
|
||||
savedVersionToCheck = cheatDetection.savedVersion;
|
||||
}
|
||||
if (androidContext.getFileStreamPath(fh.playerId).exists()) {
|
||||
FileInputStream fileInputStream = androidContext.openFileInput(fh.playerId);
|
||||
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
|
||||
final CheatDetection cheatDetection = new CheatDetection(dataInputStream);
|
||||
if (cheatDetection.savedVersion == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED) {
|
||||
savedVersionToCheck = DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED;
|
||||
}
|
||||
else if (cheatDetection.savedVersion > savedVersionToCheck) {
|
||||
savedVersionToCheck = cheatDetection.savedVersion;
|
||||
}
|
||||
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
|
||||
L.log("Internal cheatcheck file savedVersion: " + cheatDetection.savedVersion);
|
||||
@@ -166,48 +167,31 @@ public final class Savegames {
|
||||
return (savedVersionToCheck == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED || fh.savedVersion < savedVersionToCheck);
|
||||
}
|
||||
|
||||
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(androidContext);
|
||||
return new FileOutputStream(getSlotFile(slot, androidContext));
|
||||
}
|
||||
}
|
||||
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(androidContext);
|
||||
return new FileOutputStream(getSlotFile(slot, androidContext));
|
||||
}
|
||||
}
|
||||
private static void ensureSavegameDirectoryExists(Context context) {
|
||||
File dir = AndroidStorage.getStorageDirectory(context, 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, androidContext));
|
||||
}
|
||||
}
|
||||
|
||||
private static void ensureSavegameDirectoryExists(Context context) {
|
||||
File dir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
ensureDirExists(dir);
|
||||
}
|
||||
public static File getSlotFile(int slot, Context context) {
|
||||
File root = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
return new File(root, Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + slot);
|
||||
}
|
||||
|
||||
public static boolean ensureDirExists(File dir) {
|
||||
if (!dir.exists()) {
|
||||
boolean worked = dir.mkdir();
|
||||
return worked;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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, androidContext));
|
||||
}
|
||||
}
|
||||
|
||||
public static File getSlotFile(int slot, Context context) {
|
||||
File root = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
return getSlotFile(slot, root);
|
||||
}
|
||||
|
||||
public static File getSlotFile(int slot, File directory) {
|
||||
return new File(directory, getSlotFileName(slot));
|
||||
}
|
||||
|
||||
public static String getSlotFileName(int slot) {
|
||||
return Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + slot;
|
||||
}
|
||||
|
||||
|
||||
public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException {
|
||||
@@ -223,11 +207,10 @@ public final class Savegames {
|
||||
dest.close();
|
||||
}
|
||||
|
||||
public static LoadSavegameResult loadWorld(Resources res, WorldContext world, ControllerContext controllers, InputStream inState, FileHeader fh) throws IOException {
|
||||
DataInputStream src = new DataInputStream(inState);
|
||||
final FileHeader header = new FileHeader(src, fh.skipIcon);
|
||||
if (header.fileversion > AndorsTrailApplication.CURRENT_VERSION)
|
||||
return LoadSavegameResult.savegameIsFromAFutureVersion;
|
||||
public static LoadSavegameResult loadWorld(Resources res, WorldContext world, ControllerContext controllers, InputStream inState, FileHeader fh) throws IOException {
|
||||
DataInputStream src = new DataInputStream(inState);
|
||||
final FileHeader header = new FileHeader(src, fh.skipIcon);
|
||||
if (header.fileversion > AndorsTrailApplication.CURRENT_VERSION) return LoadSavegameResult.savegameIsFromAFutureVersion;
|
||||
|
||||
world.maps.readFromParcel(src, world, controllers, header.fileversion);
|
||||
world.model = new ModelContainer(src, world, controllers, header.fileversion);
|
||||
@@ -266,15 +249,15 @@ public final class Savegames {
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeCheatCheck(Context androidContext, long savedVersion, String playerId) throws IOException {
|
||||
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
|
||||
ensureDirExists(cheatDetectionFolder);
|
||||
File cheatDetectionFile = new File(cheatDetectionFolder, playerId);
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(cheatDetectionFile);
|
||||
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
|
||||
CheatDetection.writeToParcel(dataOutputStream, savedVersion);
|
||||
dataOutputStream.close();
|
||||
fileOutputStream.close();
|
||||
private static void writeCheatCheck(Context androidContext, long savedVersion, String playerId) throws IOException {
|
||||
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
|
||||
if (!cheatDetectionFolder.exists()) cheatDetectionFolder.mkdir();
|
||||
File cheatDetectionFile = new File(cheatDetectionFolder, playerId);
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(cheatDetectionFile);
|
||||
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
|
||||
CheatDetection.writeToParcel(dataOutputStream, savedVersion);
|
||||
dataOutputStream.close();
|
||||
fileOutputStream.close();
|
||||
|
||||
fileOutputStream = androidContext.openFileOutput(playerId, Context.MODE_PRIVATE);
|
||||
dataOutputStream = new DataOutputStream(fileOutputStream);
|
||||
@@ -285,26 +268,26 @@ public final class Savegames {
|
||||
|
||||
private static final Pattern savegameFilenamePattern = Pattern.compile(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + "(\\d+)");
|
||||
|
||||
public static List<Integer> getUsedSavegameSlots(Context context) {
|
||||
try {
|
||||
final List<Integer> result = new ArrayList<Integer>();
|
||||
AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY).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 new ArrayList<Integer>();
|
||||
}
|
||||
}
|
||||
public static List<Integer> getUsedSavegameSlots(Context context) {
|
||||
try {
|
||||
final List<Integer> result = new ArrayList<Integer>();
|
||||
AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY).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;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class CheatDetection {
|
||||
public final int fileversion;
|
||||
@@ -324,16 +307,17 @@ public final class Savegames {
|
||||
}
|
||||
|
||||
|
||||
public static final class FileHeader {
|
||||
public final int fileversion;
|
||||
public final String playerName;
|
||||
public final String displayInfo;
|
||||
public final int iconID;
|
||||
public boolean skipIcon = false;
|
||||
public final boolean isDead;
|
||||
public final boolean hasUnlimitedSaves;
|
||||
public final String playerId;
|
||||
public final long savedVersion;
|
||||
|
||||
public static final class FileHeader {
|
||||
public final int fileversion;
|
||||
public final String playerName;
|
||||
public final String displayInfo;
|
||||
public final int iconID;
|
||||
public boolean skipIcon = false;
|
||||
public final boolean isDead;
|
||||
public final boolean hasUnlimitedSaves;
|
||||
public final String playerId;
|
||||
public final long savedVersion;
|
||||
|
||||
public String describe() {
|
||||
return (fileversion == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION ? "(D) " : "") + playerName + ", " + displayInfo;
|
||||
@@ -342,18 +326,17 @@ public final class Savegames {
|
||||
|
||||
// ====== PARCELABLE ===================================================================
|
||||
|
||||
public FileHeader(DataInputStream src, boolean skipIcon) 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 FileHeader(DataInputStream src, boolean skipIcon) 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;
|
||||
}
|
||||
|
||||
if (fileversion >= 43) {
|
||||
int id = src.readInt();
|
||||
|
||||
@@ -1,58 +1,42 @@
|
||||
package com.gpl.rpg.AndorsTrail.util;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.support.v4.provider.DocumentFile;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.controller.Constants;
|
||||
import com.gpl.rpg.AndorsTrail.util.BackgroundWorker.BackgroundWorkerCallback;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
public final class AndroidStorage {
|
||||
public static File getStorageDirectory(Context context, String name) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
return context.getExternalFilesDir(name);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
File root = Environment.getExternalStorageDirectory();
|
||||
return new File(root, name);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean shouldMigrateToInternalStorage(Context context) {
|
||||
boolean ret = false;
|
||||
File externalSaveGameDirectory = new File(Environment.getExternalStorageDirectory(),
|
||||
Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
File externalSaveGameDirectory = new File(Environment.getExternalStorageDirectory(), Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
File internalSaveGameDirectory = getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
|
||||
if (externalSaveGameDirectory.exists()
|
||||
&& externalSaveGameDirectory.isDirectory()
|
||||
&& externalSaveGameDirectory.listFiles().length > 0
|
||||
&& (!internalSaveGameDirectory.exists()
|
||||
|| internalSaveGameDirectory.isDirectory()
|
||||
&& internalSaveGameDirectory.listFiles().length < 2)) {
|
||||
&& externalSaveGameDirectory.isDirectory()
|
||||
&& externalSaveGameDirectory.listFiles().length > 0
|
||||
&& (
|
||||
!internalSaveGameDirectory.exists()
|
||||
|| internalSaveGameDirectory.isDirectory() && internalSaveGameDirectory.listFiles().length < 2)
|
||||
) {
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
@@ -61,11 +45,11 @@ public final class AndroidStorage {
|
||||
public static boolean migrateToInternalStorage(Context context) {
|
||||
try {
|
||||
copy(new File(Environment.getExternalStorageDirectory(), Constants.CHEAT_DETECTION_FOLDER),
|
||||
getStorageDirectory(context, Constants.CHEAT_DETECTION_FOLDER));
|
||||
getStorageDirectory(context, Constants.CHEAT_DETECTION_FOLDER));
|
||||
copy(new File(Environment.getExternalStorageDirectory(), Constants.FILENAME_SAVEGAME_DIRECTORY),
|
||||
getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY));
|
||||
getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY));
|
||||
} catch (IOException e) {
|
||||
L.log("Error migrating data: " + e);
|
||||
L.log("Error migrating data: " + e.toString());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -92,381 +76,35 @@ public final class AndroidStorage {
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyFile(File source, File target) throws IOException {
|
||||
try (InputStream in = new FileInputStream(source); OutputStream out = new FileOutputStream(target)) {
|
||||
copyStream(in, out);
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyStream(InputStream in, OutputStream out) throws IOException {
|
||||
byte[] buf = new byte[1024];
|
||||
int length;
|
||||
while ((length = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, length);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
public static void createZipDocumentFileFromFilesAsync(File[] files,
|
||||
Context context,
|
||||
DocumentFile targetDirectory,
|
||||
String fileName,
|
||||
String loadingMessage,
|
||||
Consumer<Boolean> callback) {
|
||||
|
||||
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
|
||||
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
|
||||
progressDialog.setOnCancelListener(dialog -> worker.cancel());
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Handler handler = Handler.createAsync(Looper.getMainLooper());
|
||||
|
||||
|
||||
worker.setTask(workerCallback -> {
|
||||
try {
|
||||
workerCallback.onInitialize();
|
||||
|
||||
//region create zip file
|
||||
File zip = File.createTempFile("temp_worldmap", ".zip");
|
||||
try (OutputStream out = new FileOutputStream(zip)) {
|
||||
ZipOutputStream zipOut = new ZipOutputStream(out);
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File file = files[i];
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
workerCallback.onProgress((float) i / files.length);
|
||||
zipOut.putNextEntry(new ZipEntry(file.getName()));
|
||||
copyStream(fis, zipOut);
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
}
|
||||
zipOut.close();
|
||||
}
|
||||
//endregion
|
||||
|
||||
DocumentFile worldmapZip = DocumentFile.fromFile(zip);
|
||||
DocumentFile worldmapTarget = targetDirectory.createFile("application/zip", fileName);
|
||||
if (worldmapTarget != null && worldmapTarget.exists()) {
|
||||
AndroidStorage.copyDocumentFile(worldmapZip, resolver, worldmapTarget);
|
||||
workerCallback.onComplete(true);
|
||||
} else {
|
||||
throw new FileNotFoundException("Could not create File");
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
if (worker.isCancelled()) {
|
||||
workerCallback.onFailure(new CancellationException("Cancelled"));
|
||||
} else {
|
||||
workerCallback.onFailure(e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
workerCallback.onFailure(e);
|
||||
private static void copyFile(File source, File target) throws IOException {
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
try {
|
||||
in = new FileInputStream(source);
|
||||
out = new FileOutputStream(target);
|
||||
byte[] buf = new byte[1024];
|
||||
int length;
|
||||
while ((length = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, length);
|
||||
}
|
||||
});
|
||||
|
||||
worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback));
|
||||
worker.run();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void unzipToDirectory(File zipFile,
|
||||
File targetDirectory,
|
||||
boolean overwriteNotSkip) throws IOException {
|
||||
|
||||
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
|
||||
unzipStreamToDirectory(targetDirectory, overwriteNotSkip, zis);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
public static void unzipDocumentFileToDirectoryAsync(DocumentFile zipFile,
|
||||
Context context,
|
||||
File targetDirectory,
|
||||
boolean overwriteNotSkip,
|
||||
String loadingMessage,
|
||||
Consumer<Boolean> callback) {
|
||||
|
||||
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
|
||||
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
|
||||
progressDialog.setOnCancelListener(dialog -> worker.cancel());
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Handler handler = Handler.createAsync(Looper.getMainLooper());
|
||||
|
||||
worker.setTask(workerCallback -> {
|
||||
try {
|
||||
workerCallback.onInitialize();
|
||||
workerCallback.onProgress(-1);//set dummy progress since we don't know the
|
||||
// progress of the unzip
|
||||
unzipDocumentFileToDirectory(zipFile, resolver, targetDirectory, overwriteNotSkip);
|
||||
workerCallback.onComplete(true);
|
||||
} catch (IOException e) {
|
||||
workerCallback.onFailure(e);
|
||||
} finally {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
});
|
||||
|
||||
worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback));
|
||||
worker.run();
|
||||
|
||||
}
|
||||
|
||||
public static void unzipDocumentFileToDirectory(DocumentFile zipFile,
|
||||
ContentResolver resolver,
|
||||
File targetDirectory,
|
||||
boolean overwriteNotSkip) throws IOException {
|
||||
try (ZipInputStream zis = new ZipInputStream(resolver.openInputStream(zipFile.getUri()))) {
|
||||
unzipStreamToDirectory(targetDirectory, overwriteNotSkip, zis);
|
||||
}
|
||||
}
|
||||
|
||||
private static void unzipStreamToDirectory(File targetDirectory,
|
||||
boolean overwriteNotSkip,
|
||||
ZipInputStream zis) throws IOException {
|
||||
ZipEntry entry;
|
||||
while ((entry = zis.getNextEntry()) != null) {
|
||||
File file = new File(targetDirectory, entry.getName());
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
file.mkdirs();
|
||||
} else {
|
||||
file.getParentFile().mkdirs();
|
||||
if (file.exists() && !overwriteNotSkip) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
copyStream(zis, fos);
|
||||
}
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile,
|
||||
ContentResolver resolver,
|
||||
DocumentFile targetFolder) throws IOException {
|
||||
copyDocumentFileToNewOrExistingFile(sourceFile,
|
||||
resolver,
|
||||
targetFolder,
|
||||
Constants.NO_FILE_EXTENSION_MIME_TYPE);
|
||||
}
|
||||
|
||||
|
||||
public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile,
|
||||
ContentResolver resolver,
|
||||
DocumentFile targetFolder,
|
||||
String mimeType) throws IOException {
|
||||
String fileName = sourceFile.getName();
|
||||
DocumentFile file = targetFolder.findFile(fileName);
|
||||
if (file == null) {
|
||||
file = targetFolder.createFile(mimeType, fileName);
|
||||
}
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
AndroidStorage.copyDocumentFile(sourceFile, resolver, file);
|
||||
}
|
||||
|
||||
public static void copyDocumentFile(DocumentFile sourceFile,
|
||||
ContentResolver resolver,
|
||||
DocumentFile targetFile) throws IOException {
|
||||
try (OutputStream outputStream = resolver.openOutputStream(targetFile.getUri());
|
||||
InputStream inputStream = resolver.openInputStream(sourceFile.getUri())) {
|
||||
copyStream(inputStream, outputStream);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getUrlForFile(Context context, File worldmap) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
String applicationId = context.getPackageName();
|
||||
// Uri uri = FileProvider.getUriForFile(context, "com.gpl.rpg.AndorsTrail.fileprovider", worldmap);
|
||||
Uri uri = FileProvider.getUriForFile(context, applicationId + ".fileprovider", worldmap);
|
||||
return uri.toString();
|
||||
} else {
|
||||
return "file://" + worldmap.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public static Intent getNewOpenDirectoryIntent() {
|
||||
return new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public static Intent getNewSelectMultipleSavegameFilesIntent() {
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
|
||||
intent.setType(Constants.SAVEGAME_FILE_MIME_TYPE);
|
||||
return intent;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public static Intent getNewSelectZipIntent() {
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("application/zip");
|
||||
return intent;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
public static void copyDocumentFilesFromToAsync(DocumentFile[] sources,
|
||||
Context context,
|
||||
DocumentFile[] targets,
|
||||
String loadingMessage,
|
||||
Consumer<Boolean> callback) {
|
||||
if (sources.length != targets.length) {
|
||||
throw new IllegalArgumentException("Both arrays, target & source have to have the same size");
|
||||
}
|
||||
|
||||
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
|
||||
|
||||
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
|
||||
progressDialog.setOnCancelListener(dialog -> worker.cancel());
|
||||
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Handler handler = Handler.createAsync(Looper.getMainLooper());
|
||||
|
||||
worker.setTask(workerCallback -> {
|
||||
try {
|
||||
workerCallback.onInitialize();
|
||||
for (int i = 0; i < sources.length; i++) {
|
||||
if (worker.isCancelled()) {
|
||||
workerCallback.onFailure(new CancellationException("Cancelled"));
|
||||
return;
|
||||
}
|
||||
DocumentFile source = sources[i];
|
||||
DocumentFile target = targets[i];
|
||||
|
||||
if (source == null || target == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
copyDocumentFile(source, resolver, target);
|
||||
float progress = i / (float) sources.length;
|
||||
workerCallback.onProgress(progress);
|
||||
}
|
||||
workerCallback.onComplete(true);
|
||||
} catch (NullPointerException e) {
|
||||
if (worker.isCancelled()) {
|
||||
workerCallback.onFailure(new CancellationException("Cancelled"));
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
workerCallback.onFailure(e);
|
||||
}
|
||||
});
|
||||
worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback));
|
||||
worker.run();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
public static void copyDocumentFilesToDirAsync(DocumentFile[] files,
|
||||
Context context,
|
||||
DocumentFile targetDirectory,
|
||||
String loadingMessage,
|
||||
Consumer<Boolean> callback) {
|
||||
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
|
||||
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
|
||||
progressDialog.setOnCancelListener(dialog -> worker.cancel());
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Handler handler = Handler.createAsync(Looper.getMainLooper());
|
||||
|
||||
worker.setTask(workerCallback -> {
|
||||
try {
|
||||
workerCallback.onInitialize();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
if (worker.isCancelled()) {
|
||||
workerCallback.onFailure(new CancellationException("Cancelled"));
|
||||
return;
|
||||
}
|
||||
DocumentFile file = files[i];
|
||||
if (file == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
copyDocumentFileToNewOrExistingFile(file, resolver, targetDirectory);
|
||||
float progress = i / (float) files.length;
|
||||
workerCallback.onProgress(progress);
|
||||
}
|
||||
workerCallback.onComplete(true);
|
||||
} catch (NullPointerException e) {
|
||||
if (worker.isCancelled()) {
|
||||
workerCallback.onFailure(new CancellationException("Cancelled"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
workerCallback.onFailure(e);
|
||||
}
|
||||
});
|
||||
worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback));
|
||||
worker.run();
|
||||
}
|
||||
|
||||
private static BackgroundWorkerCallback<Boolean> getDefaultBackgroundWorkerCallback(Handler handler,
|
||||
CustomDialogFactory.CustomDialog progressDialog,
|
||||
Consumer<Boolean> callback) {
|
||||
return new BackgroundWorkerCallback<Boolean>() {
|
||||
private int progress = -1;
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
handler.post(() -> {
|
||||
CustomDialogFactory.show(progressDialog);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(float progress) {
|
||||
handler.post(() -> {
|
||||
int intProgress = (int) (progress * 100);
|
||||
if (this.progress == intProgress) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.progress = intProgress;
|
||||
|
||||
if (progress == -1) {
|
||||
CustomDialogFactory.setDesc(progressDialog, null);
|
||||
return;
|
||||
}
|
||||
|
||||
CustomDialogFactory.setDesc(progressDialog, intProgress + "%");
|
||||
});
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
this.onComplete(false);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
@Override
|
||||
public void onComplete(Boolean result) {
|
||||
handler.post(() -> {
|
||||
progressDialog.dismiss();
|
||||
callback.accept(result);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static CustomDialogFactory.CustomDialog getLoadingDialog(Context context) {
|
||||
return getLoadingDialog(context, null);
|
||||
}
|
||||
|
||||
private static CustomDialogFactory.CustomDialog getLoadingDialog(Context context, String message) {
|
||||
if (message == null) {
|
||||
message = context.getResources().getString(R.string.dialog_loading_message);
|
||||
}
|
||||
|
||||
CustomDialogFactory.CustomDialog dialog = CustomDialogFactory.createDialog(context,
|
||||
message,
|
||||
context.getResources()
|
||||
.getDrawable(R.drawable.loading_anim),
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false);
|
||||
CustomDialogFactory.addCancelButton(dialog, android.R.string.no);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.util;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public final class BackgroundWorker<T> {
|
||||
boolean cancelled = false;
|
||||
worker<T> task;
|
||||
BackgroundWorkerCallback<T> callback;
|
||||
|
||||
public void setTask(worker<T> task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public void setCallback(BackgroundWorkerCallback<T> callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
interface worker<T> {
|
||||
void doWork(BackgroundWorkerCallback<T> callback);
|
||||
}
|
||||
|
||||
interface BackgroundWorkerCallback<T> {
|
||||
void onInitialize();
|
||||
|
||||
default void onProgress(float progress) {
|
||||
}
|
||||
|
||||
void onFailure(Exception e);
|
||||
|
||||
void onComplete(T result);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
Executors.newSingleThreadExecutor().execute(() -> {
|
||||
task.doWork(callback);
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.gpl.rpg.AndorsTrail.view;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface.OnDismissListener;
|
||||
import android.content.DialogInterface.OnCancelListener;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@@ -22,33 +22,25 @@ import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
|
||||
|
||||
public class CustomDialogFactory {
|
||||
|
||||
public static class CustomDialog extends android.app.Dialog {
|
||||
|
||||
public static class CustomDialog extends Dialog {
|
||||
public CustomDialog(Context context) {
|
||||
super(context);
|
||||
}
|
||||
boolean verticalButtons = false;
|
||||
|
||||
}
|
||||
|
||||
public static CustomDialog createDialog(final Context context, String title, Drawable icon,
|
||||
String desc, View content, boolean hasButtons, boolean canDismiss) {
|
||||
return createDialog(context, title, icon, desc, content, hasButtons, canDismiss, false);
|
||||
}
|
||||
|
||||
public static CustomDialog createDialog(final Context context, String title, Drawable icon,
|
||||
String desc, View content, boolean hasButtons) {
|
||||
|
||||
public static CustomDialog createDialog(final Context context, String title, Drawable icon, String desc, View content, boolean hasButtons) {
|
||||
return createDialog(context, title, icon, desc, content, hasButtons, true);
|
||||
}
|
||||
|
||||
public static CustomDialog createDialog(final Context context, String title, Drawable icon,
|
||||
String desc, View content, boolean hasButtons,
|
||||
final boolean canDismiss, final boolean verticalButtons) {
|
||||
|
||||
public static CustomDialog createDialog(final Context context, String title, Drawable icon, String desc, View content, boolean hasButtons, final boolean canDismiss) {
|
||||
final CustomDialog dialog = new CustomDialog(new ContextThemeWrapper(context, ThemeHelper.getDialogTheme())) {
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
Rect r = new Rect();
|
||||
this.getWindow().getDecorView().findViewById(R.id.dialog_hitrect).getHitRect(r);
|
||||
|
||||
|
||||
if (r.contains((int)event.getX(), (int)event.getY())) {
|
||||
return super.onTouchEvent(event);
|
||||
} else {
|
||||
@@ -59,7 +51,7 @@ public class CustomDialogFactory {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
@@ -71,8 +63,7 @@ public class CustomDialogFactory {
|
||||
}
|
||||
}
|
||||
};
|
||||
dialog.verticalButtons = verticalButtons;
|
||||
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(R.layout.custom_dialog_title_icon);
|
||||
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
|
||||
@@ -81,37 +72,23 @@ public class CustomDialogFactory {
|
||||
} else {
|
||||
dialog.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
}
|
||||
|
||||
|
||||
setTitle(dialog, title, icon);
|
||||
|
||||
|
||||
setDesc(dialog, desc);
|
||||
|
||||
|
||||
setContent(dialog, content);
|
||||
|
||||
ViewGroup buttonsHolder = getButtonContainer(dialog);
|
||||
ViewGroup unusedButtonsHolder = getUnusedButtonContainer(dialog);
|
||||
|
||||
unusedButtonsHolder.setVisibility(View.GONE);
|
||||
|
||||
ViewGroup buttonsHolder = (ViewGroup) dialog.findViewById(R.id.dialog_button_container);
|
||||
if (hasButtons) {
|
||||
buttonsHolder.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
buttonsHolder.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static CustomDialog createErrorDialog(final Context context, String title, String description) {
|
||||
final CustomDialog d = createDialog(context,
|
||||
title,
|
||||
context.getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||
description,
|
||||
null,
|
||||
true);
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.ok);
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
public static CustomDialog setTitle(final CustomDialog dialog, String title, Drawable icon) {
|
||||
TextView titleView = (TextView) dialog.findViewById(R.id.dialog_title);
|
||||
if (title != null || icon != null) {
|
||||
@@ -123,7 +100,7 @@ public class CustomDialogFactory {
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
public static CustomDialog setDesc(final CustomDialog dialog, String desc) {
|
||||
TextView descView = (TextView) dialog.findViewById(R.id.dialog_description);
|
||||
ViewGroup descHolder = (ViewGroup) dialog.findViewById(R.id.dialog_description_container);
|
||||
@@ -136,7 +113,7 @@ public class CustomDialogFactory {
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
public static CustomDialog setContent(final CustomDialog dialog, View content) {
|
||||
ViewGroup contentHolder = (ViewGroup) dialog.findViewById(R.id.dialog_content_container);
|
||||
if (content != null) {
|
||||
@@ -147,101 +124,54 @@ public class CustomDialogFactory {
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static CustomDialog addButton(final CustomDialog dialog, String text, final OnClickListener listener) {
|
||||
return addButton(dialog, -1, text, listener);
|
||||
}
|
||||
public static CustomDialog addButton(final CustomDialog dialog, int textId, final OnClickListener listener) {
|
||||
return addButton(dialog, textId, null, listener);
|
||||
}
|
||||
public static CustomDialog addButton(final CustomDialog dialog, int textId, String text, final OnClickListener listener) {
|
||||
Button template = getButtonTemplate(dialog);
|
||||
|
||||
public static Dialog addButton(final Dialog dialog, int textId, final OnClickListener listener) {
|
||||
|
||||
Button template = (Button) dialog.findViewById(R.id.dialog_template_button);
|
||||
LayoutParams params = template.getLayoutParams();
|
||||
ViewGroup buttonsHolder = getButtonContainer(dialog);
|
||||
|
||||
ViewGroup buttonsHolder = (ViewGroup) dialog.findViewById(R.id.dialog_button_container);
|
||||
|
||||
Button b = new Button(dialog.getContext());
|
||||
b.setLayoutParams(params);
|
||||
//Old android versions need this "reminder"
|
||||
b.setBackgroundDrawable(ThemeHelper.getThemeDrawable(dialog.getContext(), R.attr.ui_theme_textbutton_drawable));
|
||||
b.setTextColor(ThemeHelper.getThemeColor(dialog.getContext(), R.attr.ui_theme_dialogue_light_color));
|
||||
|
||||
if(textId != -1) {
|
||||
b.setText(textId);
|
||||
} else {
|
||||
b.setText(text);
|
||||
}
|
||||
|
||||
|
||||
b.setText(textId);
|
||||
b.setOnClickListener(new OnClickListener() {
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
listener.onClick(v);
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
buttonsHolder.addView(b, params);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static CustomDialog addDismissButton(final CustomDialog dialog, int textId) {
|
||||
|
||||
public static Dialog addDismissButton(final Dialog dialog, int textId) {
|
||||
return CustomDialogFactory.addButton(dialog, textId, new OnClickListener() {
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
public static CustomDialog addCancelButton(final CustomDialog dialog, int textId) {
|
||||
return CustomDialogFactory.addButton(dialog, textId, new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static CustomDialog setDismissListener(CustomDialog dialog, OnDismissListener listener) {
|
||||
|
||||
public static Dialog setDismissListener(Dialog dialog, OnDismissListener listener) {
|
||||
dialog.setOnDismissListener(listener);
|
||||
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static CustomDialog setCancelListener(CustomDialog dialog, OnCancelListener listener) {
|
||||
dialog.setOnCancelListener(listener);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static void show(CustomDialog dialog) {
|
||||
|
||||
|
||||
public static void show(Dialog dialog) {
|
||||
|
||||
dialog.findViewById(R.id.dialog_template_button).setVisibility(View.GONE);
|
||||
dialog.findViewById(R.id.dialog_template_button_vertical).setVisibility(View.GONE);
|
||||
dialog.show();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static ViewGroup getUnusedButtonContainer(CustomDialog dialog) {
|
||||
if (dialog.verticalButtons)
|
||||
return (ViewGroup) dialog.findViewById(R.id.dialog_button_container);
|
||||
else
|
||||
return (ViewGroup) dialog.findViewById(R.id.dialog_button_container_vertical);
|
||||
}
|
||||
|
||||
private static ViewGroup getButtonContainer(CustomDialog dialog) {
|
||||
if (dialog.verticalButtons)
|
||||
return (ViewGroup) dialog.findViewById(R.id.dialog_button_container_vertical);
|
||||
else
|
||||
return (ViewGroup) dialog.findViewById(R.id.dialog_button_container);
|
||||
}
|
||||
|
||||
private static Button getButtonTemplate(CustomDialog dialog) {
|
||||
if (dialog.verticalButtons)
|
||||
return (Button) dialog.findViewById(R.id.dialog_template_button_vertical);
|
||||
else
|
||||
return (Button) dialog.findViewById(R.id.dialog_template_button);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,15 +9,13 @@ import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
|
||||
|
||||
/**
|
||||
* Simply instantiate this class, implement abstract methods in an anonymous type, and tada, your Button is a Spinner!
|
||||
*/
|
||||
public abstract class SpinnerEmulator {
|
||||
|
||||
private Button spinnerButton;
|
||||
private CustomDialog spinnerDialog = null;
|
||||
private Dialog spinnerDialog = null;
|
||||
private ListView choicesList;
|
||||
private Context context;
|
||||
|
||||
|
||||
7
AndorsTrail/local.properties
Normal file
@@ -0,0 +1,7 @@
|
||||
## This file must *NOT* be checked into Version Control Systems,
|
||||
# as it contains information specific to your local configuration.
|
||||
#
|
||||
# Location of the SDK. This is only used by Gradle.
|
||||
#
|
||||
#Sun Sep 25 12:50:59 CEST 2022
|
||||
sdk.dir=C\:\\Users\\chris\\AppData\\Local\\Android\\Sdk
|
||||
@@ -1,112 +1,23 @@
|
||||
I put both (release notes + forum announcement) into this source, so it will be easier to maintain them parallel:
|
||||
|
||||
|
||||
APK 68 (0.8.4) Mostly harmless
|
||||
|
||||
Release notes
|
||||
=============
|
||||
* Export/Import: The worldmap, which consists of many small png files, is handled now as a zip file.
|
||||
* Translation updates and many minor bug fixes and map enhancements
|
||||
|
||||
|
||||
Forum announcement //2023-01-29
|
||||
==================
|
||||
Hello fellow adventurers,
|
||||
|
||||
Here is the actual release v0.8.4 with bugfixes, translations and little enhancements:
|
||||
|
||||
[list]The export/import is enhanced: The worldmap, which consists of many small png files, is handled now as a zip file. This is more convenient and much quicker.[/list]
|
||||
|
||||
[list]Fixes of several little bugs and typos[/list]
|
||||
[list]Especially the Pangitain break should be fixed now[/list]
|
||||
[list]Many map fixes and changes, most of them in the new area towards Sullengard and the haunted forest[/list]
|
||||
|
||||
[list]And as always we actualized the translations[/list]
|
||||
|
||||
Here is is the link on our server: [url]https://andorstrail.com/static/AndorsTrail_v0.8.4.apk[/url]
|
||||
Google Play, F-Droid and Itch will follow soon.
|
||||
|
||||
Have fun!
|
||||
|
||||
|
||||
|
||||
|
||||
APK 67 (0.8.3) //Haunted Forest 2022-11-04
|
||||
|
||||
Release notes (Google/Itch)
|
||||
=============
|
||||
Content
|
||||
* 38 new maps
|
||||
* A new quest "The Dead are Walking"
|
||||
|
||||
Engine
|
||||
* Export / Import function for savegames (Android 11+ devices only)
|
||||
* Beta versions come now as a different APK
|
||||
|
||||
|
||||
|
||||
Forum announcement
|
||||
==================
|
||||
Hello fellow adventurers,
|
||||
|
||||
we have another new release for you 8-)
|
||||
It would have been nice if we had been some days faster. Then it would have come out in time for Halloween.
|
||||
But we won't delay the release for an extra year because of that...
|
||||
|
||||
[list]We have 38 new maps and 1 new quest "The Dead are Walking" created by Antison - thanks for all the work 8-)
|
||||
You start at the church in Vilegard. But beware - similar to Sullengard, this release is no walk in the park![/list]
|
||||
|
||||
[list]In addition, the game now has the long-awaited export / import function, so that savegames can now be conveniently copied to another device.
|
||||
This feature was brought to us by OMGeeky, which we're taking as an opportunity to welcome him as the newest member of the development team!
|
||||
|
||||
There are now 3 more choices in the load menu:
|
||||
[list]Export: Writes all savegames and the world map to any directory.[/list]
|
||||
[list]Import: Loads individually selected saved games. If the slot is already occupied, you can choose between overwriting, canceling or saving in a new slot.[/list]
|
||||
[list]Import world map: Loads missing parts of the world maps, e.g. if saves were copied from another device.[/list]
|
||||
(This export/import is only available for Android 11+, older devices can be copied as usual.)
|
||||
[/list]
|
||||
|
||||
[list]This Beta version is released with a different APK name, so you won't have to deinstall the product version any more. You can install and play both APK's independently.[/list]
|
||||
[list]And as always we fixed some minor bugs and actualized the translations.[/list]
|
||||
|
||||
|
||||
Here is is the link: [url]https://andorstrail.com/static/AndorsTrail_v0.8.3_beta.apk[/url]
|
||||
|
||||
Have fun trying!
|
||||
If you encounter bugs or strange things, please post them. This will help us to fix it before publishing the release.
|
||||
|
||||
|
||||
APK 66 (0.8.2) //Sullengard Bugfix
|
||||
|
||||
Release notes
|
||||
=============
|
||||
* Fix of a lost traveler in certain conditions
|
||||
* support of older mobiles again
|
||||
|
||||
|
||||
Forum announcement //2022-10-09
|
||||
==================
|
||||
Hello fellow adventurers,
|
||||
|
||||
we have a new release for you 8-)
|
||||
we fixed a bug in the last Andor's Trail release to ensure the quest "Recovering stolen property" can be completed.
|
||||
Also some more XP and better loot in Sullengard area.
|
||||
|
||||
[list]Some of you had encountered a serious bug so that the quest "Recovering stolen property" could not be completed.
|
||||
(If you miss a certain traveler, you should talk to Sullengard's innkeeper in this new release)[/list]
|
||||
Here is the link to the productive version: [url]https://andorstrail.com/static/AndorsTrail_v0.8.2.apk[/url]
|
||||
|
||||
[list]Then we increased XP for quests a bit and ensured one diamond ring.[/list]
|
||||
Google Play and Itch will follow soon, and hopefully this version can also be provided by F-Droid again.
|
||||
|
||||
[list]And we fixed some maps, added a long missed little map near Fallhaven, and actualized the translations.[/list]
|
||||
|
||||
[list]Also we tried to support older mobiles again.[/list]
|
||||
|
||||
[list]And last but not least: hopefully F-Droid supports our sources again.[/list]
|
||||
|
||||
There is no new content, but this list of fixes is enough reason to publish a new release.
|
||||
Here is is the link: [url]https://andorstrail.com/static/AndorsTrail_v0.8.2.apk[/url]
|
||||
|
||||
Google Play and Itch will follow soon, and hopefully F-Droid too.
|
||||
|
||||
Cheers!
|
||||
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 119 KiB |
@@ -71,29 +71,6 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/dialog_button_container_vertical"
|
||||
style="@style/AndorsTrail_Style_StdFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.8"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="5dp"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingRight="5dp"
|
||||
android:paddingBottom="5dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/dialog_template_button_vertical"
|
||||
style="@style/AndorsTrail_Style_TextButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -51,45 +51,19 @@
|
||||
</ScrollView>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/loadsave_save_to_new_slot_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
style="@style/AndorsTrail_Style_StdFrame"
|
||||
>
|
||||
<Button
|
||||
android:id="@+id/loadsave_save_to_new_slot"
|
||||
android:id="@+id/loadsave_save_to_new_slot_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/loadsave_save_to_new_slot"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/loadsave_export_import_save_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
style="@style/AndorsTrail_Style_StdFrame"
|
||||
>
|
||||
<Button
|
||||
android:id="@+id/loadsave_export_save"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/loadsave_export"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/loadsave_import_save"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/loadsave_import_save"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/loadsave_import_worldmap"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/loadsave_import_worldmap"
|
||||
/>
|
||||
</LinearLayout>
|
||||
android:orientation="vertical"
|
||||
style="@style/AndorsTrail_Style_StdFrame"
|
||||
>
|
||||
<Button
|
||||
android:id="@+id/loadsave_save_to_new_slot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/loadsave_save_to_new_slot"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
[{"id":"death_plague","iconID":"obj_0:61","name":"Death Plague","category":"blood","roundEffect":{"increaseCurrentHP":{"min":-2,"max":-2}},"abilityEffect":{"increaseBlockChance":-10}},{"id":"sleepwalking","iconID":"obj_0:62","name":"Sleepwalking","category":"physical","roundEffect":{"increaseCurrentAP":{"min":-3,"max":-3}}}]
|
||||
@@ -1 +1 @@
|
||||
[{"id":"panic","iconID":"obj_0:56","name":"Panic","category":"mental","roundEffect":{"visualEffectID":"blueSwirl","increaseCurrentHP":{"min":-1,"max":1}},"abilityEffect":{"increaseAttackChance":10,"increaseMaxAP":4,"increaseCriticalSkill":10,"increaseBlockChance":10}},{"id":"satiety","iconID":"obj_0:57","name":"Satiety","category":"physical","isPositive":1,"roundEffect":{"visualEffectID":"blueSwirl","increaseCurrentHP":{"min":0,"max":2}},"abilityEffect":{"increaseMaxHP":2}},{"id":"frozen1","iconID":"obj_0:58","name":"Minor freeze","category":"physical","roundEffect":{"visualEffectID":"blueSwirl","increaseCurrentHP":{"min":-1,"max":-1}},"abilityEffect":{"increaseMoveCost":1,"increaseUseItemCost":1,"increaseBlockChance":20,"increaseDamageResistance":1}},{"id":"frozen2","iconID":"obj_0:59","name":"Icy wounds","category":"physical","isStacking":1,"roundEffect":{"visualEffectID":"blueSwirl","increaseCurrentHP":{"min":-1,"max":-1}},"abilityEffect":{"increaseMoveCost":1,"increaseAttackCost":0,"increaseBlockChance":-5}},{"id":"relax","iconID":"obj_0:60","name":"Requiescence","category":"mental","roundEffect":{"visualEffectID":"blueSwirl","increaseCurrentHP":{"min":2,"max":2}},"abilityEffect":{"increaseAttackChance":-50,"increaseAttackDamage":{"min":-5,"max":-5},"increaseMaxAP":-4,"increaseUseItemCost":-1,"increaseReequipCost":-1,"increaseAttackCost":2,"increaseCriticalSkill":-20,"increaseBlockChance":-80,"increaseDamageResistance":-2}},{"id":"kazarite_misery","iconID":"obj_0:18","name":"Kazaul possession","category":"spiritual","roundEffect":{"visualEffectID":"redSplash","increaseCurrentHP":{"min":-3,"max":-2}},"abilityEffect":{"increaseAttackChance":10,"increaseBlockChance":10,"increaseDamageResistance":1}}]
|
||||
[{"id":"panic","iconID":"obj_0:56","name":"Panic","category":"mental","roundEffect":{"visualEffectID":"blueSwirl","increaseCurrentHP":{"min":-1,"max":1}},"abilityEffect":{"increaseAttackChance":10,"increaseMaxAP":4,"increaseCriticalSkill":10,"increaseBlockChance":10}},{"id":"satiety","iconID":"obj_0:57","name":"Satiety","category":"physical","isPositive":1,"roundEffect":{"visualEffectID":"blueSwirl","increaseCurrentHP":{"min":0,"max":2}},"abilityEffect":{"increaseMaxHP":2}},{"id":"frozen1","iconID":"obj_0:58","name":"Minor freeze","category":"physical","roundEffect":{"visualEffectID":"blueSwirl","increaseCurrentHP":{"min":-1,"max":-1}},"abilityEffect":{"increaseMoveCost":1,"increaseUseItemCost":1,"increaseBlockChance":20,"increaseDamageResistance":1}},{"id":"frozen2","iconID":"obj_0:59","name":"Icy wounds","category":"physical","isStacking":1,"roundEffect":{"visualEffectID":"blueSwirl","increaseCurrentHP":{"min":-1,"max":-1}},"abilityEffect":{"increaseMoveCost":1,"increaseAttackCost":0,"increaseBlockChance":-5}},{"id":"relax","iconID":"obj_0:60","name":"Requiescence","category":"mental","isPositive":1,"roundEffect":{"visualEffectID":"blueSwirl","increaseCurrentHP":{"min":2,"max":2},"increaseCurrentAP":{"min":0,"max":0}},"abilityEffect":{"increaseAttackChance":-50,"increaseAttackDamage":{"min":-5,"max":-5},"increaseMaxAP":-4,"increaseUseItemCost":-1,"increaseReequipCost":-1,"increaseAttackCost":2,"increaseCriticalSkill":-20,"increaseBlockChance":-80,"increaseDamageResistance":-2}},{"id":"kazarite_misery","iconID":"obj_0:18","name":"Kazaul possession","category":"spiritual","roundEffect":{"visualEffectID":"redSplash","increaseCurrentHP":{"min":-3,"max":-2}},"abilityEffect":{"increaseAttackChance":10,"increaseBlockChance":10,"increaseDamageResistance":1}}]
|
||||
@@ -1 +1 @@
|
||||
[
|
||||
[
|
||||
@@ -1 +1 @@
|
||||
[
|
||||
[
|
||||