Compare commits
3 Commits
import_exp
...
compressed
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19d9ecb721 | ||
|
|
66a0e34ef9 | ||
|
|
13c58fcdbc |
2
AndorsTrail/.idea/workspace.xml
generated
@@ -10,7 +10,7 @@
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="ExecutionTargetManager" SELECTED_TARGET="device_and_snapshot_combo_box_target[C:\Users\chris\.android\avd\Nexus_5_API_30.avd]" />
|
||||
<component name="ExecutionTargetManager" SELECTED_TARGET="device_and_snapshot_combo_box_target[AQ8PSW4DBUZPMZOR]" />
|
||||
<component name="ExternalProjectsData">
|
||||
<projectState path="$PROJECT_DIR$">
|
||||
<ProjectState />
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.gpl.rpg.AndorsTrail"
|
||||
android:versionCode="66"
|
||||
android:versionName="0.8.2"
|
||||
android:versionCode="65"
|
||||
android:versionName="0.8.1"
|
||||
android:installLocation="auto"
|
||||
>
|
||||
<uses-sdk
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
|
||||
<application
|
||||
android:name=".AndorsTrailApplication"
|
||||
android:name="com.gpl.rpg.AndorsTrail.AndorsTrailApplication"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@drawable/icon"
|
||||
android:description="@string/app_description"
|
||||
@@ -36,33 +36,34 @@
|
||||
android:preserveLegacyExternalStorage="true"
|
||||
>
|
||||
<activity
|
||||
android:name=".activity.StartScreenActivity"
|
||||
android:clearTaskOnLaunch="true">
|
||||
android:name="com.gpl.rpg.AndorsTrail.activity.StartScreenActivity"
|
||||
android:clearTaskOnLaunch="true"
|
||||
>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.MainActivity"
|
||||
android:name="com.gpl.rpg.AndorsTrail.activity.MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AndorsTrailTheme_Blue.NoBackground"
|
||||
/>
|
||||
<activity android:name=".activity.HeroinfoActivity" />
|
||||
<activity android:name=".activity.MonsterInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name=".activity.ItemInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name=".activity.LevelUpActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name=".activity.MonsterEncounterActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name=".activity.ConversationActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name=".activity.ShopActivity" />
|
||||
<activity android:name=".activity.AboutActivity" />
|
||||
<activity android:name=".activity.LoadingActivity" />
|
||||
<activity android:name=".activity.Preferences" />
|
||||
<activity android:name=".activity.LoadSaveActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name=".activity.ActorConditionInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name=".activity.BulkSelectionInterface" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name=".activity.SkillInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name=".activity.DisplayWorldMapActivity" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.HeroinfoActivity" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.MonsterInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.ItemInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.LevelUpActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.MonsterEncounterActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.ConversationActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.ShopActivity" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.AboutActivity" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.LoadingActivity" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.Preferences" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.LoadSaveActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.ActorConditionInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.BulkSelectionInterface" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.SkillInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
|
||||
<activity android:name="com.gpl.rpg.AndorsTrail.activity.DisplayWorldMapActivity" />
|
||||
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
|
||||
@@ -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.2";
|
||||
public static final String CURRENT_VERSION_DISPLAY = "0.8.1";
|
||||
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 : 66;
|
||||
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 65;
|
||||
|
||||
private final AndorsTrailPreferences preferences = new AndorsTrailPreferences();
|
||||
private WorldContext world = new WorldContext();
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.gpl.rpg.AndorsTrail;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
public final class AndorsTrailPreferences {
|
||||
@@ -62,8 +61,6 @@ public final class AndorsTrailPreferences {
|
||||
public boolean showQuickslotsWhenToolboxIsVisible = false;
|
||||
public String language = "default";
|
||||
|
||||
public Uri exportImportFolderPath;
|
||||
|
||||
public int selectedTheme = 0;
|
||||
|
||||
public void read(final Context androidContext) {
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
package com.gpl.rpg.AndorsTrail.activity;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.ClipData;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v4.provider.DocumentFile;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
@@ -32,653 +22,241 @@ import android.widget.Toast;
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences;
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.controller.Constants;
|
||||
import com.gpl.rpg.AndorsTrail.model.ModelContainer;
|
||||
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
|
||||
import com.gpl.rpg.AndorsTrail.savegames.Savegames;
|
||||
import com.gpl.rpg.AndorsTrail.savegames.Savegames.FileHeader;
|
||||
import com.gpl.rpg.AndorsTrail.util.AndroidStorage;
|
||||
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
|
||||
|
||||
public final class LoadSaveActivity extends AndorsTrailBaseActivity implements OnClickListener {
|
||||
private boolean isLoading = true;
|
||||
//region special slot numbers
|
||||
private static final int SLOT_NUMBER_CREATE_NEW_SLOT = -1;
|
||||
public static final int SLOT_NUMBER_EXPORT_SAVEGAMES = -2;
|
||||
public static final int SLOT_NUMBER_IMPORT_SAVEGAMES = -3;
|
||||
public static final int SLOT_NUMBER_IMPORT_WORLDMAP = -4;
|
||||
private static final int SLOT_NUMBER_FIRST_SLOT = 1;
|
||||
//endregion
|
||||
private ModelContainer model;
|
||||
private TileManager tileManager;
|
||||
private AndorsTrailPreferences preferences;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(ThemeHelper.getDialogTheme());
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
final AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
|
||||
app.setWindowParameters(this);
|
||||
this.model = app.getWorld().model;
|
||||
this.preferences = app.getPreferences();
|
||||
this.tileManager = app.getWorld().tileManager;
|
||||
|
||||
String loadsave = getIntent().getData().getLastPathSegment();
|
||||
isLoading = (loadsave.equalsIgnoreCase("load"));
|
||||
|
||||
setContentView(R.layout.loadsave);
|
||||
|
||||
TextView tv = (TextView) findViewById(R.id.loadsave_title);
|
||||
if (isLoading) {
|
||||
tv.setCompoundDrawablesWithIntrinsicBounds(android.R.drawable.ic_menu_search, 0, 0, 0);
|
||||
tv.setText(R.string.loadsave_title_load);
|
||||
} else {
|
||||
tv.setCompoundDrawablesWithIntrinsicBounds(android.R.drawable.ic_menu_save, 0, 0, 0);
|
||||
tv.setText(R.string.loadsave_title_save);
|
||||
}
|
||||
|
||||
ViewGroup slotList = (ViewGroup) findViewById(R.id.loadsave_slot_list);
|
||||
Button slotTemplateButton = (Button) findViewById(R.id.loadsave_slot_n);
|
||||
LayoutParams params = slotTemplateButton.getLayoutParams();
|
||||
slotList.removeView(slotTemplateButton);
|
||||
|
||||
ViewGroup newSlotContainer = (ViewGroup) findViewById(R.id.loadsave_save_to_new_slot_container);
|
||||
Button createNewSlot = (Button) findViewById(R.id.loadsave_save_to_new_slot);
|
||||
|
||||
Button exportSaves = (Button) findViewById(R.id.loadsave_export_save);
|
||||
Button importSaves = (Button) findViewById(R.id.loadsave_import_save);
|
||||
Button importWorldmap = (Button) findViewById(R.id.loadsave_import_worldmap);
|
||||
|
||||
exportSaves.setTag(SLOT_NUMBER_EXPORT_SAVEGAMES);
|
||||
importSaves.setTag(SLOT_NUMBER_IMPORT_SAVEGAMES);
|
||||
importWorldmap.setTag(SLOT_NUMBER_IMPORT_WORLDMAP);
|
||||
|
||||
ViewGroup exportContainer = (ViewGroup) findViewById(R.id.loadsave_export_save_container);
|
||||
ViewGroup importContainer = (ViewGroup) findViewById(R.id.loadsave_import_save_container);
|
||||
ViewGroup importWorldmapContainer = (ViewGroup) findViewById(R.id.loadsave_import_worldmap_container);
|
||||
|
||||
|
||||
addSavegameSlotButtons(slotList, params, Savegames.getUsedSavegameSlots(this));
|
||||
|
||||
checkAndRequestPermissions();
|
||||
|
||||
if (!isLoading) {
|
||||
createNewSlot.setTag(SLOT_NUMBER_CREATE_NEW_SLOT);
|
||||
createNewSlot.setOnClickListener(this);
|
||||
newSlotContainer.setVisibility(View.VISIBLE);
|
||||
exportContainer.setVisibility(View.GONE);
|
||||
importContainer.setVisibility(View.GONE);
|
||||
importWorldmapContainer.setVisibility(View.GONE);
|
||||
} else {
|
||||
newSlotContainer.setVisibility(View.GONE);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
exportSaves.setOnClickListener(this);
|
||||
importSaves.setOnClickListener(this);
|
||||
importWorldmap.setOnClickListener(this);
|
||||
exportContainer.setVisibility(View.VISIBLE);
|
||||
importContainer.setVisibility(View.VISIBLE);
|
||||
importWorldmapContainer.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final int READ_EXTERNAL_STORAGE_REQUEST = 1;
|
||||
private static final int WRITE_EXTERNAL_STORAGE_REQUEST = 2;
|
||||
|
||||
@TargetApi(23)
|
||||
private void checkAndRequestPermissions() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
||||
if (getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
this.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE_REQUEST);
|
||||
}
|
||||
if (getApplicationContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
this.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_REQUEST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
|
||||
Toast.makeText(this, R.string.storage_permissions_mandatory, Toast.LENGTH_LONG).show();
|
||||
((AndorsTrailApplication) getApplication()).discardWorld();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private void addSavegameSlotButtons(ViewGroup parent, LayoutParams params, List<Integer> usedSavegameSlots) {
|
||||
int unused = 1;
|
||||
for (int slot : usedSavegameSlots) {
|
||||
final FileHeader header = Savegames.quickload(this, slot);
|
||||
if (header == null) continue;
|
||||
|
||||
while (unused < slot) {
|
||||
Button b = new Button(this);
|
||||
b.setLayoutParams(params);
|
||||
b.setTag(unused);
|
||||
b.setOnClickListener(this);
|
||||
b.setText(getString(R.string.loadsave_empty_slot, unused));
|
||||
tileManager.setImageViewTileForPlayer(getResources(), b, header.iconID);
|
||||
parent.addView(b, params);
|
||||
unused++;
|
||||
}
|
||||
unused++;
|
||||
|
||||
Button b = new Button(this);
|
||||
b.setLayoutParams(params);
|
||||
b.setTag(slot);
|
||||
b.setOnClickListener(this);
|
||||
b.setText(slot + ". " + header.describe());
|
||||
tileManager.setImageViewTileForPlayer(getResources(), b, header.iconID);
|
||||
parent.addView(b, params);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void completeLoadSaveActivity(int slot) {
|
||||
Intent i = new Intent();
|
||||
if (slot == SLOT_NUMBER_CREATE_NEW_SLOT) {
|
||||
List<Integer> usedSlots = Savegames.getUsedSavegameSlots(this);
|
||||
if (usedSlots.isEmpty())
|
||||
slot = SLOT_NUMBER_FIRST_SLOT;
|
||||
else slot = Collections.max(usedSlots) + 1;
|
||||
} else if (slot == SLOT_NUMBER_EXPORT_SAVEGAMES
|
||||
|| slot == SLOT_NUMBER_IMPORT_SAVEGAMES
|
||||
|| slot == SLOT_NUMBER_IMPORT_WORLDMAP) {
|
||||
i.putExtra("import_export", true);
|
||||
} else if (slot < SLOT_NUMBER_FIRST_SLOT)
|
||||
slot = SLOT_NUMBER_FIRST_SLOT;
|
||||
|
||||
i.putExtra("slot", slot);
|
||||
setResult(Activity.RESULT_OK, i);
|
||||
LoadSaveActivity.this.finish();
|
||||
}
|
||||
|
||||
private String getConfirmOverwriteQuestion(int slot) {
|
||||
if (isLoading)
|
||||
return null;
|
||||
|
||||
return getConfirmOverwriteQuestionIgnoringLoading(slot);
|
||||
}
|
||||
|
||||
private String getConfirmOverwriteQuestionIgnoringLoading(int slot) {
|
||||
if (slot == SLOT_NUMBER_CREATE_NEW_SLOT)
|
||||
return null;//creating a new savegame
|
||||
|
||||
if (!Savegames.getSlotFile(slot, this).exists())
|
||||
return null;//nothing in slot to overwrite
|
||||
|
||||
if (preferences.displayOverwriteSavegame == AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_ALWAYS) {
|
||||
return getString(R.string.loadsave_save_overwrite_confirmation_all);
|
||||
}
|
||||
if (preferences.displayOverwriteSavegame == AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_NEVER) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String currentPlayerName = model.player.getName();
|
||||
final FileHeader header = Savegames.quickload(this, slot);
|
||||
if (header == null) return null;
|
||||
|
||||
final String savedPlayerName = header.playerName;
|
||||
if (currentPlayerName.equals(savedPlayerName)) return null; //if the names match
|
||||
|
||||
return getString(R.string.loadsave_save_overwrite_confirmation, savedPlayerName, currentPlayerName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
final int slot = (Integer) view.getTag();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
switch (slot) {
|
||||
case SLOT_NUMBER_IMPORT_WORLDMAP:
|
||||
clickImportWorldmap();
|
||||
return;
|
||||
case SLOT_NUMBER_IMPORT_SAVEGAMES:
|
||||
clickImportSaveGames();
|
||||
return;
|
||||
case SLOT_NUMBER_EXPORT_SAVEGAMES:
|
||||
clickExportSaveGames();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!isLoading
|
||||
&& slot != SLOT_NUMBER_CREATE_NEW_SLOT
|
||||
&& AndorsTrailApplication.CURRENT_VERSION == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) {
|
||||
if (!isOverwriteTargetInIncompatibleVersion(slot)) {
|
||||
saveOrOverwriteSavegame(slot);
|
||||
}
|
||||
} else if (isLoading) {
|
||||
loadSaveGame(slot);
|
||||
} else {
|
||||
saveOrOverwriteSavegame(slot);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveOrOverwriteSavegame(int slot) {
|
||||
final String message = getConfirmOverwriteQuestion(slot);
|
||||
if (message != null) {
|
||||
showConfirmoverwriteQuestion(slot, message);
|
||||
} else {
|
||||
completeLoadSaveActivity(slot);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOverwriteTargetInIncompatibleVersion(int slot) {
|
||||
final FileHeader header = Savegames.quickload(this, slot);
|
||||
if (header != null && header.fileversion != AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) {
|
||||
final Dialog d = CustomDialogFactory.createErrorDialog(this, "Overwriting not allowed", "You are currently using a development version of Andor's trail. Overwriting a regular savegame is not allowed in development mode.");
|
||||
CustomDialogFactory.show(d);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//region Imports/Exports
|
||||
|
||||
private void exportSaveGames(Intent data) {
|
||||
Uri uri = data.getData();
|
||||
|
||||
Context context = getApplicationContext();
|
||||
ContentResolver resolver = AndorsTrailApplication.getApplicationFromActivity(this).getContentResolver();
|
||||
|
||||
File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
DocumentFile source = DocumentFile.fromFile(storageDir);
|
||||
DocumentFile target = DocumentFile.fromTreeUri(context, uri);
|
||||
if (target == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
DocumentFile[] files = source.listFiles();
|
||||
|
||||
boolean hasExistingFiles = false;
|
||||
for (DocumentFile file :
|
||||
files) {
|
||||
String fileName = file.getName();
|
||||
if (fileName == null)
|
||||
continue;
|
||||
|
||||
DocumentFile existingFile = target.findFile(fileName);
|
||||
if (existingFile != null) {
|
||||
hasExistingFiles = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasExistingFiles) {
|
||||
showConfirmOverwriteByExportQuestion(resolver, target, files);
|
||||
} else {
|
||||
exportSaveGamesFolderContentToFolder(resolver, target, files);
|
||||
}
|
||||
}
|
||||
|
||||
private void exportSaveGamesFolderContentToFolder(ContentResolver resolver, DocumentFile target, DocumentFile[] files) {
|
||||
for (DocumentFile file : files) {
|
||||
String fileName = file.getName();
|
||||
DocumentFile existingFile = target.findFile(fileName);
|
||||
boolean hasExistingFile = existingFile != null && existingFile.exists();
|
||||
|
||||
if (file.isFile()) {
|
||||
try {
|
||||
if (hasExistingFile)
|
||||
existingFile.delete();
|
||||
|
||||
|
||||
AndroidStorage.copyDocumentFileToNewOrExistingFile(file, resolver, target);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (file.isDirectory()) {
|
||||
DocumentFile targetWorlmap = existingFile;
|
||||
//if the folder exists already, put the files in the existing folder. (should not happen because of check earlier)
|
||||
if (!hasExistingFile)
|
||||
//create a new folder for the worldmap-files
|
||||
targetWorlmap = target.createDirectory(Constants.FILENAME_WORLDMAP_DIRECTORY);
|
||||
|
||||
if (targetWorlmap == null)//Unable to create worldmap folder for some reason
|
||||
continue;
|
||||
|
||||
DocumentFile[] worldmapFiles = file.listFiles();
|
||||
for (DocumentFile f : worldmapFiles) {
|
||||
try {
|
||||
AndroidStorage.copyDocumentFileToNewOrExistingFile(f, resolver, targetWorlmap);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
completeLoadSaveActivity(SLOT_NUMBER_EXPORT_SAVEGAMES);
|
||||
}
|
||||
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
|
||||
private void importSaveGames(Intent data) {
|
||||
Uri uri = data.getData();
|
||||
ClipData uris = data.getClipData();
|
||||
|
||||
if (uri == null && uris == null) {
|
||||
//no file was selected
|
||||
return;
|
||||
}
|
||||
|
||||
Context context = getApplicationContext();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
|
||||
File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
DocumentFile appSavegameFolder = DocumentFile.fromFile(storageDir);
|
||||
|
||||
List<Uri> uriList = new ArrayList<>();
|
||||
if (uri != null) {
|
||||
uriList.add(uri);
|
||||
} else {
|
||||
for (int i = 0; i < uris.getItemCount(); i++)
|
||||
uriList.add(uris.getItemAt(i).getUri());
|
||||
}
|
||||
importSaveGamesFromUris(context, resolver, appSavegameFolder, uriList);
|
||||
}
|
||||
|
||||
private void importSaveGamesFromUris(Context context, ContentResolver resolver, DocumentFile appSavegameFolder, List<Uri> uriList) {
|
||||
int count = uriList.size();
|
||||
|
||||
ArrayList<DocumentFile> alreadyExistingFiles = new ArrayList<>();
|
||||
ArrayList<DocumentFile> newFiles = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
Uri item = uriList.get(i);
|
||||
DocumentFile itemFile = DocumentFile.fromSingleUri(context, item);
|
||||
boolean fileAlreadyExists = getExistsSavegameInOwnFiles(itemFile, appSavegameFolder);
|
||||
if (fileAlreadyExists)
|
||||
alreadyExistingFiles.add(itemFile);
|
||||
else
|
||||
newFiles.add(itemFile);
|
||||
}
|
||||
|
||||
if (alreadyExistingFiles.size() > 0) {
|
||||
showConfirmOverwriteByImportQuestion(resolver, appSavegameFolder, alreadyExistingFiles, newFiles);
|
||||
} else {
|
||||
importSaveGames(resolver, appSavegameFolder, newFiles);
|
||||
}
|
||||
}
|
||||
|
||||
private void importSaveGames(ContentResolver resolver, DocumentFile appSavegameFolder, List<DocumentFile> saveFiles) {
|
||||
for (DocumentFile file : saveFiles) {
|
||||
int slot = getSlotFromSavegameFileName(file.getName());
|
||||
importSaveGameFile(resolver, appSavegameFolder, file, slot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void completeSavegameImportAndCheckIfDone(List<Integer> importsNeedingConfirmation, int slot) {
|
||||
importsNeedingConfirmation.remove((Object) slot);
|
||||
if (importsNeedingConfirmation.isEmpty()) {
|
||||
completeLoadSaveActivity(SLOT_NUMBER_IMPORT_SAVEGAMES);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean getExistsSavegameInOwnFiles(DocumentFile savegameFile, DocumentFile appSavegameFolder) {
|
||||
if (savegameFile == null)
|
||||
return false;
|
||||
|
||||
DocumentFile foundFile = appSavegameFolder.findFile(Objects.requireNonNull(savegameFile.getName()));
|
||||
return foundFile != null && foundFile.exists();
|
||||
}
|
||||
|
||||
private int getSlotFromSavegameFileName(String fileName) {
|
||||
if (fileName == null || !fileName.startsWith(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX)) {
|
||||
//TODO: Maybe output a message that the file didn't have the right name?
|
||||
return -1;
|
||||
}
|
||||
String slotStr = fileName.substring(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX.length());
|
||||
|
||||
int slot;
|
||||
try {
|
||||
slot = Integer.parseInt(slotStr);
|
||||
return slot;
|
||||
} catch (NumberFormatException e) {
|
||||
//TODO: Maybe output a message that the file didn't have the right name?
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void importSaveGameFile(ContentResolver resolver, DocumentFile appSavegameFolder, DocumentFile itemFile, int slot) {
|
||||
String targetName = Savegames.getSlotFileName(slot);
|
||||
DocumentFile targetFile = getOrCreateDocumentFile(appSavegameFolder, targetName);
|
||||
|
||||
if (targetFile == null || !targetName.equals(targetFile.getName())) {
|
||||
showErrorImportingSaveGameUnknown();//TODO: maybe replace with a more specific error message
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
AndroidStorage.copyDocumentFile(itemFile, resolver, targetFile);
|
||||
} catch (IOException e) {
|
||||
showErrorImportingSaveGameUnknown();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private DocumentFile getOrCreateDocumentFile(DocumentFile folder, String targetName) {
|
||||
DocumentFile targetFile = folder.findFile(targetName);//try finding the file
|
||||
if (targetFile == null)//no file found, creating new one
|
||||
targetFile = folder.createFile(Constants.NO_FILE_EXTENSION_MIME_TYPE, targetName);
|
||||
return targetFile;
|
||||
}
|
||||
|
||||
private void importWorldmap(Intent data) {
|
||||
Uri uri = data.getData();
|
||||
|
||||
Context context = getApplicationContext();
|
||||
ContentResolver resolver = AndorsTrailApplication.getApplicationFromActivity(this).getContentResolver();
|
||||
|
||||
File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
DocumentFile storageFolder = DocumentFile.fromFile(storageDir);
|
||||
DocumentFile ownWorldmapFolder = storageFolder.findFile(Constants.FILENAME_WORLDMAP_DIRECTORY);
|
||||
if (ownWorldmapFolder == null) {
|
||||
ownWorldmapFolder = storageFolder.createDirectory(Constants.FILENAME_WORLDMAP_DIRECTORY);
|
||||
}
|
||||
|
||||
DocumentFile chosenFolder = DocumentFile.fromTreeUri(context, uri);
|
||||
if (chosenFolder == null || !chosenFolder.isDirectory()) {
|
||||
showErrorImportingWorldmapWrongDirectory();
|
||||
return;
|
||||
}
|
||||
if (!Constants.FILENAME_WORLDMAP_DIRECTORY.equals(chosenFolder.getName())) {
|
||||
//user did not select the worldmap folder directly
|
||||
DocumentFile file = chosenFolder.findFile(Constants.FILENAME_WORLDMAP_DIRECTORY);
|
||||
if (file == null || !file.isDirectory() || !Constants.FILENAME_WORLDMAP_DIRECTORY.equals(file.getName())) {
|
||||
//could not find a worldmap folder in the users selection
|
||||
showErrorImportingWorldmapWrongDirectory();
|
||||
return;
|
||||
}
|
||||
|
||||
chosenFolder = file;
|
||||
}
|
||||
|
||||
DocumentFile[] files = chosenFolder.listFiles();
|
||||
for (DocumentFile file : files) {
|
||||
if (file.isFile()) {
|
||||
try {
|
||||
AndroidStorage.copyDocumentFileToNewOrExistingFile(file, resolver, ownWorldmapFolder);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
completeLoadSaveActivity(SLOT_NUMBER_IMPORT_WORLDMAP);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
private void clickExportSaveGames() {
|
||||
startActivityForResult(AndroidStorage.getNewOpenDirectoryIntent(), -SLOT_NUMBER_EXPORT_SAVEGAMES);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
private void clickImportSaveGames() {
|
||||
startActivityForResult(AndroidStorage.getNewSelectMultipleSavegameFilesIntent(), -SLOT_NUMBER_IMPORT_SAVEGAMES);
|
||||
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
private void clickImportWorldmap() {
|
||||
startActivityForResult(AndroidStorage.getNewOpenDirectoryIntent(), -SLOT_NUMBER_IMPORT_WORLDMAP);
|
||||
|
||||
}
|
||||
|
||||
private void showConfirmOverwriteByExportQuestion(ContentResolver resolver, DocumentFile targetFolder, DocumentFile[] files) {
|
||||
final Dialog d = CustomDialogFactory.createDialog(this,
|
||||
getString(R.string.loadsave_export_overwrite_confirmation_title),
|
||||
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||
getString(R.string.loadsave_export_overwrite_confirmation),
|
||||
null,
|
||||
true);
|
||||
|
||||
CustomDialogFactory.addButton(d, android.R.string.yes, v -> exportSaveGamesFolderContentToFolder(resolver, targetFolder, files));
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.no);
|
||||
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
private void showConfirmOverwriteByImportQuestion(ContentResolver resolver,
|
||||
DocumentFile appSavegameFolder,
|
||||
List<DocumentFile> alreadyExistingFiles,
|
||||
List<DocumentFile> newFiles) {
|
||||
final String title = getString(R.string.loadsave_import_overwrite_confirmation_title);
|
||||
String message = getString(R.string.loadsave_import_overwrite_confirmation);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('\n');
|
||||
int amount = alreadyExistingFiles.size();
|
||||
|
||||
Context context = AndorsTrailApplication.getApplicationFromActivity(this).getApplicationContext();
|
||||
|
||||
for (int i = 0; i < amount && i < 3; i++) {
|
||||
DocumentFile alreadyExistingFile = alreadyExistingFiles.get(i);
|
||||
String alreadyExistingFileName = alreadyExistingFile.getName();
|
||||
FileHeader fileHeader = Savegames.quickload(context, getSlotFromSavegameFileName(alreadyExistingFileName));
|
||||
sb.append('\n');
|
||||
String fileHeaderDesription = "";
|
||||
if (fileHeader != null)
|
||||
fileHeaderDesription = fileHeader.describe();
|
||||
|
||||
sb.append(getString(R.string.loadsave_import_overwrite_confirmation_file_pattern, alreadyExistingFileName, fileHeaderDesription));
|
||||
// sb.append(alreadyExistingFile.getName());
|
||||
}
|
||||
if (amount > 3) {
|
||||
sb.append("\n...");
|
||||
}
|
||||
message = message + sb;
|
||||
final Dialog d = CustomDialogFactory.createDialog(this,
|
||||
title,
|
||||
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||
message,
|
||||
null,
|
||||
true);
|
||||
|
||||
CustomDialogFactory.addButton(d, android.R.string.yes, v -> newFiles.addAll(alreadyExistingFiles));
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.no);
|
||||
CustomDialogFactory.setDismissListener(d, dialog -> {
|
||||
importSaveGames(resolver, appSavegameFolder, newFiles);
|
||||
completeLoadSaveActivity(SLOT_NUMBER_IMPORT_SAVEGAMES);
|
||||
});
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if (resultCode != Activity.RESULT_OK)
|
||||
return;
|
||||
|
||||
// Uri uri = data.getData();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
switch (-requestCode) {
|
||||
case SLOT_NUMBER_EXPORT_SAVEGAMES:
|
||||
exportSaveGames(data);
|
||||
return;
|
||||
case SLOT_NUMBER_IMPORT_SAVEGAMES:
|
||||
importSaveGames(data);
|
||||
return;
|
||||
case SLOT_NUMBER_IMPORT_WORLDMAP:
|
||||
importWorldmap(data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
private void loadSaveGame(int slot) {
|
||||
if (!Savegames.getSlotFile(slot, this).exists()) {
|
||||
showErrorLoadingEmptySlot();
|
||||
} else {
|
||||
final FileHeader header = Savegames.quickload(this, slot);
|
||||
if (header != null && !header.hasUnlimitedSaves) {
|
||||
showSlotGetsDeletedOnLoadWarning(slot);
|
||||
} else {
|
||||
completeLoadSaveActivity(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//region show Dialogs
|
||||
|
||||
private void showErrorImportingWorldmapWrongDirectory() {
|
||||
final Dialog d = CustomDialogFactory.createErrorDialog(this,
|
||||
getString(R.string.loadsave_import_worldmap_unsuccessfull),
|
||||
getString(R.string.loadsave_import_worldmap_unsuccessfull_wrong_directory));
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
private void showErrorImportingSaveGameUnknown() {
|
||||
final Dialog d = CustomDialogFactory.createErrorDialog(this,
|
||||
getString(R.string.loadsave_import_save_unsuccessfull),
|
||||
getString(R.string.loadsave_import_save_unsuccessfull_unknown));
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
private void showErrorLoadingEmptySlot() {
|
||||
final Dialog d = CustomDialogFactory.createErrorDialog(this,
|
||||
getString(R.string.startscreen_error_loading_game),
|
||||
getString(R.string.startscreen_error_loading_empty_slot));
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
private void showSlotGetsDeletedOnLoadWarning(final int slot) {
|
||||
final Dialog d = CustomDialogFactory.createDialog(this,
|
||||
getString(R.string.startscreen_attention_slot_gets_delete_on_load),
|
||||
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||
getString(R.string.startscreen_attention_message_slot_gets_delete_on_load),
|
||||
null,
|
||||
true);
|
||||
CustomDialogFactory.addButton(d, android.R.string.ok, v -> completeLoadSaveActivity(slot));
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
private void showConfirmoverwriteQuestion(final int slot, String message) {
|
||||
final String title =
|
||||
getString(R.string.loadsave_save_overwrite_confirmation_title) + ' '
|
||||
+ getString(R.string.loadsave_save_overwrite_confirmation_slot, slot);
|
||||
final Dialog d = CustomDialogFactory.createDialog(this,
|
||||
title,
|
||||
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||
message,
|
||||
null,
|
||||
true);
|
||||
|
||||
CustomDialogFactory.addButton(d, android.R.string.yes, v -> completeLoadSaveActivity(slot));
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.no);
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
private boolean isLoading = true;
|
||||
private static final int SLOT_NUMBER_CREATE_NEW_SLOT = -1;
|
||||
private static final int SLOT_NUMBER_FIRST_SLOT = 1;
|
||||
private ModelContainer model;
|
||||
private TileManager tileManager;
|
||||
private AndorsTrailPreferences preferences;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(ThemeHelper.getDialogTheme());
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
final AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
|
||||
app.setWindowParameters(this);
|
||||
this.model = app.getWorld().model;
|
||||
this.preferences = app.getPreferences();
|
||||
this.tileManager = app.getWorld().tileManager;
|
||||
|
||||
String loadsave = getIntent().getData().getLastPathSegment();
|
||||
isLoading = (loadsave.equalsIgnoreCase("load"));
|
||||
|
||||
setContentView(R.layout.loadsave);
|
||||
|
||||
TextView tv = (TextView) findViewById(R.id.loadsave_title);
|
||||
if (isLoading) {
|
||||
tv.setCompoundDrawablesWithIntrinsicBounds(android.R.drawable.ic_menu_search, 0, 0, 0);
|
||||
tv.setText(R.string.loadsave_title_load);
|
||||
} else {
|
||||
tv.setCompoundDrawablesWithIntrinsicBounds(android.R.drawable.ic_menu_save, 0, 0, 0);
|
||||
tv.setText(R.string.loadsave_title_save);
|
||||
}
|
||||
|
||||
ViewGroup slotList = (ViewGroup) findViewById(R.id.loadsave_slot_list);
|
||||
Button slotTemplateButton = (Button) findViewById(R.id.loadsave_slot_n);
|
||||
LayoutParams params = slotTemplateButton.getLayoutParams();
|
||||
slotList.removeView(slotTemplateButton);
|
||||
|
||||
ViewGroup newSlotContainer = (ViewGroup) findViewById(R.id.loadsave_save_to_new_slot_container);
|
||||
Button createNewSlot = (Button) findViewById(R.id.loadsave_save_to_new_slot);
|
||||
|
||||
addSavegameSlotButtons(slotList, params, Savegames.getUsedSavegameSlots(this));
|
||||
|
||||
checkAndRequestPermissions();
|
||||
|
||||
if (!isLoading) {
|
||||
createNewSlot.setTag(SLOT_NUMBER_CREATE_NEW_SLOT);
|
||||
createNewSlot.setOnClickListener(this);
|
||||
newSlotContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
newSlotContainer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private static final int READ_EXTERNAL_STORAGE_REQUEST=1;
|
||||
private static final int WRITE_EXTERNAL_STORAGE_REQUEST=2;
|
||||
|
||||
@TargetApi(23)
|
||||
private void checkAndRequestPermissions() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
||||
if (getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
this.requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE_REQUEST);
|
||||
}
|
||||
if (getApplicationContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
this.requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_REQUEST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
|
||||
Toast.makeText(this, R.string.storage_permissions_mandatory, Toast.LENGTH_LONG).show();
|
||||
((AndorsTrailApplication)getApplication()).discardWorld();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private void addSavegameSlotButtons(ViewGroup parent, LayoutParams params, List<Integer> usedSavegameSlots) {
|
||||
int unused = 1;
|
||||
for (int slot : usedSavegameSlots) {
|
||||
final FileHeader header = Savegames.quickload(this, slot);
|
||||
if (header == null) continue;
|
||||
|
||||
while (unused < slot){
|
||||
Button b = new Button(this);
|
||||
b.setLayoutParams(params);
|
||||
b.setTag(unused);
|
||||
b.setOnClickListener(this);
|
||||
b.setText(getString(R.string.loadsave_empty_slot, unused));
|
||||
tileManager.setImageViewTileForPlayer(getResources(), b, header.iconID);
|
||||
parent.addView(b, params);
|
||||
unused++;
|
||||
}
|
||||
unused++;
|
||||
|
||||
Button b = new Button(this);
|
||||
b.setLayoutParams(params);
|
||||
b.setTag(slot);
|
||||
b.setOnClickListener(this);
|
||||
b.setText(slot + ". " + header.describe());
|
||||
tileManager.setImageViewTileForPlayer(getResources(), b, header.iconID);
|
||||
parent.addView(b, params);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadsave(int slot) {
|
||||
if (slot == SLOT_NUMBER_CREATE_NEW_SLOT) {
|
||||
List<Integer> usedSlots = Savegames.getUsedSavegameSlots(this);
|
||||
if (usedSlots.isEmpty()) slot = SLOT_NUMBER_FIRST_SLOT;
|
||||
else slot = Collections.max(usedSlots) + 1;
|
||||
}
|
||||
if (slot < SLOT_NUMBER_FIRST_SLOT) slot = SLOT_NUMBER_FIRST_SLOT;
|
||||
|
||||
Intent i = new Intent();
|
||||
i.putExtra("slot", slot);
|
||||
setResult(Activity.RESULT_OK, i);
|
||||
LoadSaveActivity.this.finish();
|
||||
}
|
||||
|
||||
private String getConfirmOverwriteQuestion(int slot) {
|
||||
if (isLoading) return null;
|
||||
if (slot == SLOT_NUMBER_CREATE_NEW_SLOT) return null; // if we're creating a new slot
|
||||
if (!Savegames.getSlotFile(slot, this).exists()) return null;
|
||||
|
||||
if (preferences.displayOverwriteSavegame == AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_ALWAYS) {
|
||||
return getString(R.string.loadsave_save_overwrite_confirmation_all);
|
||||
}
|
||||
if (preferences.displayOverwriteSavegame == AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_NEVER) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String currentPlayerName = model.player.getName();
|
||||
final FileHeader header = Savegames.quickload(this, slot);
|
||||
if (header == null) return null;
|
||||
|
||||
final String savedPlayerName = header.playerName;
|
||||
if (currentPlayerName.equals(savedPlayerName)) return null; // if the names match
|
||||
|
||||
return getString(R.string.loadsave_save_overwrite_confirmation, savedPlayerName, currentPlayerName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
final int slot = (Integer) view.getTag();
|
||||
|
||||
if (!isLoading && slot != SLOT_NUMBER_CREATE_NEW_SLOT && AndorsTrailApplication.CURRENT_VERSION == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) {
|
||||
final FileHeader header = Savegames.quickload(this, slot);
|
||||
if (header != null && header.fileversion != AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) {
|
||||
final Dialog d = CustomDialogFactory.createDialog(this,
|
||||
"Overwriting not allowed",
|
||||
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||
"You are currently using a development version of Andor's trail. Overwriting a regular savegame is not allowed in development mode.",
|
||||
null,
|
||||
true);
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.ok);
|
||||
CustomDialogFactory.show(d);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isLoading) {
|
||||
if(!Savegames.getSlotFile(slot, this).exists()) {
|
||||
showErrorLoadingEmptySlot();
|
||||
} else {
|
||||
final FileHeader header = Savegames.quickload(this, slot);
|
||||
if (header != null && !header.hasUnlimitedSaves) {
|
||||
showSlotGetsDeletedOnLoadWarning(slot);
|
||||
} else {
|
||||
loadsave(slot);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final String message = getConfirmOverwriteQuestion(slot);
|
||||
if (message != null) {
|
||||
showConfirmoverwriteQuestion(slot, message);
|
||||
} else {
|
||||
loadsave(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showErrorLoadingEmptySlot() {
|
||||
final Dialog d = CustomDialogFactory.createDialog(this,
|
||||
getString(R.string.startscreen_error_loading_game),
|
||||
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||
getString(R.string.startscreen_error_loading_empty_slot),
|
||||
null,
|
||||
true);
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.ok);
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
private void showSlotGetsDeletedOnLoadWarning(final int slot) {
|
||||
final Dialog d = CustomDialogFactory.createDialog(this,
|
||||
getString(R.string.startscreen_attention_slot_gets_delete_on_load),
|
||||
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||
getString(R.string.startscreen_attention_message_slot_gets_delete_on_load),
|
||||
null,
|
||||
true);
|
||||
CustomDialogFactory.addButton(d, android.R.string.ok, new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
loadsave(slot);
|
||||
}
|
||||
});
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
private void showConfirmoverwriteQuestion(final int slot, String message) {
|
||||
final String title =
|
||||
getString(R.string.loadsave_save_overwrite_confirmation_title) + ' '
|
||||
+ getString(R.string.loadsave_save_overwrite_confirmation_slot, slot);
|
||||
final Dialog d = CustomDialogFactory.createDialog(this,
|
||||
title,
|
||||
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||
message,
|
||||
null,
|
||||
true);
|
||||
|
||||
CustomDialogFactory.addButton(d, android.R.string.yes, new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
loadsave(slot);
|
||||
}
|
||||
});
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.no);
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
package com.gpl.rpg.AndorsTrail.activity;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
@@ -39,7 +32,5 @@ public final class Preferences extends PreferenceActivity {
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
|
||||
app.setLocale(this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -28,10 +28,8 @@ import com.gpl.rpg.AndorsTrail.Dialogs;
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.WorldSetup;
|
||||
import com.gpl.rpg.AndorsTrail.activity.AboutActivity;
|
||||
import com.gpl.rpg.AndorsTrail.activity.LoadSaveActivity;
|
||||
import com.gpl.rpg.AndorsTrail.activity.LoadingActivity;
|
||||
import com.gpl.rpg.AndorsTrail.activity.Preferences;
|
||||
import com.gpl.rpg.AndorsTrail.activity.StartScreenActivity;
|
||||
import com.gpl.rpg.AndorsTrail.controller.Constants;
|
||||
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
|
||||
import com.gpl.rpg.AndorsTrail.savegames.Savegames;
|
||||
@@ -43,253 +41,253 @@ import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
|
||||
|
||||
public class StartScreenActivity_MainMenu extends Fragment {
|
||||
|
||||
private static final int INTENTREQUEST_PREFERENCES = 7;
|
||||
public static final int INTENTREQUEST_LOADGAME = 9;
|
||||
public static final int INTENTREQUEST_EXPORT_SAVE = 11;
|
||||
public static final int INTENTREQUEST_IMPORT_SAVE = 13;
|
||||
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 Button startscreen_import;
|
||||
private Button startscreen_export;
|
||||
private ViewGroup save_preview_holder;
|
||||
private ImageView save_preview_hero_icon;
|
||||
private TextView save_preview_hero_desc;
|
||||
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);
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
updatePreferences(false);
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
if (container != null) {
|
||||
container.removeAllViews();
|
||||
}
|
||||
|
||||
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() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
continueGame(false, Savegames.SLOT_QUICKSAVE, null);
|
||||
}
|
||||
});
|
||||
|
||||
if (container != null) {
|
||||
container.removeAllViews();
|
||||
}
|
||||
startscreen_newgame = (Button) root.findViewById(R.id.startscreen_newgame);
|
||||
startscreen_newgame.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
if (hasExistingGame) {
|
||||
comfirmNewGame();
|
||||
} else {
|
||||
createNewGame();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
View root = inflater.inflate(R.layout.startscreen_mainmenu, container, false);
|
||||
Button b = (Button) root.findViewById(R.id.startscreen_about);
|
||||
b.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
startActivity(new Intent(getActivity(), AboutActivity.class));
|
||||
}
|
||||
});
|
||||
|
||||
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);
|
||||
b = (Button) root.findViewById(R.id.startscreen_preferences);
|
||||
b.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
Intent intent = new Intent(getActivity(), Preferences.class);
|
||||
StartScreenActivity_MainMenu.this.startActivityForResult(intent, INTENTREQUEST_PREFERENCES);
|
||||
}
|
||||
});
|
||||
|
||||
startscreen_load = (Button) root.findViewById(R.id.startscreen_load);
|
||||
startscreen_load.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
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 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),
|
||||
null,
|
||||
true);
|
||||
CustomDialogFactory.addButton(d, android.R.string.ok, new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Dialogs.showLoad(StartScreenActivity_MainMenu.this);
|
||||
}
|
||||
});
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.cancel);
|
||||
CustomDialogFactory.show(d);
|
||||
|
||||
startscreen_continue = (Button) root.findViewById(R.id.startscreen_continue);
|
||||
startscreen_continue.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
continueGame(false, Savegames.SLOT_QUICKSAVE, null);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Dialogs.showLoad(StartScreenActivity_MainMenu.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
startscreen_newgame = (Button) root.findViewById(R.id.startscreen_newgame);
|
||||
startscreen_newgame.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
if (hasExistingGame) {
|
||||
comfirmNewGame();
|
||||
} else {
|
||||
createNewGame();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (AndorsTrailApplication.DEVELOPMENT_FORCE_STARTNEWGAME) {
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES) {
|
||||
continueGame(true, 0, "Debug player");
|
||||
} else {
|
||||
continueGame(true, 0, "Player");
|
||||
}
|
||||
} else if (AndorsTrailApplication.DEVELOPMENT_FORCE_CONTINUEGAME) {
|
||||
continueGame(false, Savegames.SLOT_QUICKSAVE, null);
|
||||
}
|
||||
|
||||
Button b = (Button) root.findViewById(R.id.startscreen_about);
|
||||
b.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
startActivity(new Intent(getActivity(), AboutActivity.class));
|
||||
}
|
||||
});
|
||||
// if it is a new version we first fire a welcome screen in onResume
|
||||
// and afterwards check the permissions
|
||||
if (!isNewVersion()) {
|
||||
checkAndRequestPermissions(getActivity());
|
||||
migrateDataOnDemand(getActivity());
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
String playerName;
|
||||
String displayInfo = null;
|
||||
int iconID = TileManager.CHAR_HERO;
|
||||
boolean isDead = false;
|
||||
|
||||
b = (Button) root.findViewById(R.id.startscreen_preferences);
|
||||
b.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
Intent intent = new Intent(getActivity(), Preferences.class);
|
||||
StartScreenActivity_MainMenu.this.startActivityForResult(intent, INTENTREQUEST_PREFERENCES);
|
||||
}
|
||||
});
|
||||
FileHeader header = Savegames.quickload(getActivity(), Savegames.SLOT_QUICKSAVE);
|
||||
if (header != null && header.playerName != null) {
|
||||
playerName = header.playerName;
|
||||
displayInfo = header.displayInfo;
|
||||
iconID = header.iconID;
|
||||
isDead = header.isDead;
|
||||
} else {
|
||||
// Before fileversion 14 (v0.6.7), quicksave was stored in Shared preferences
|
||||
SharedPreferences p = getActivity().getSharedPreferences("quicksave", Activity.MODE_PRIVATE);
|
||||
playerName = p.getString("playername", null);
|
||||
if (playerName != null) {
|
||||
displayInfo = "level " + p.getInt("level", -1);
|
||||
}
|
||||
}
|
||||
hasExistingGame = (playerName != null);
|
||||
setButtonState(playerName, displayInfo, iconID, isDead);
|
||||
|
||||
startscreen_load = (Button) root.findViewById(R.id.startscreen_load);
|
||||
startscreen_load.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
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 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),
|
||||
null,
|
||||
true);
|
||||
CustomDialogFactory.addButton(d, android.R.string.ok, new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Dialogs.showLoad(StartScreenActivity_MainMenu.this);
|
||||
}
|
||||
});
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.cancel);
|
||||
CustomDialogFactory.show(d);
|
||||
if (isNewVersion()) {
|
||||
Dialogs.showNewVersion(getActivity(), new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface arg0) {
|
||||
setCurrentVersionForVersionCheck();
|
||||
checkAndRequestPermissions(getActivity());
|
||||
migrateDataOnDemand(getActivity());
|
||||
boolean hasSavegames = !Savegames.getUsedSavegameSlots(getActivity()).isEmpty();
|
||||
startscreen_load.setEnabled(hasSavegames);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
Dialogs.showLoad(StartScreenActivity_MainMenu.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
boolean hasSavegames = !Savegames.getUsedSavegameSlots(getActivity()).isEmpty();
|
||||
startscreen_load.setEnabled(hasSavegames);
|
||||
}
|
||||
|
||||
if (AndorsTrailApplication.DEVELOPMENT_FORCE_STARTNEWGAME) {
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES) {
|
||||
continueGame(true, 0, "Debug player");
|
||||
} else {
|
||||
continueGame(true, 0, "Player");
|
||||
}
|
||||
} else if (AndorsTrailApplication.DEVELOPMENT_FORCE_CONTINUEGAME) {
|
||||
continueGame(false, Savegames.SLOT_QUICKSAVE, null);
|
||||
}
|
||||
@TargetApi(29)
|
||||
public void migrateDataOnDemand(final Activity activity) {
|
||||
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 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 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),
|
||||
null,
|
||||
true);
|
||||
CustomDialogFactory.addDismissButton(errorDlg, android.R.string.ok);
|
||||
d.cancel();
|
||||
CustomDialogFactory.show(errorDlg);
|
||||
}
|
||||
} else {
|
||||
L.log("INFO: No external files or destination folder ist not empty. No data migration.");
|
||||
}
|
||||
} else {
|
||||
L.log("INFO: No read permission on external folder. No data migration.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if it is a new version we first fire a welcome screen in onResume
|
||||
// and afterwards check the permissions
|
||||
if (!isNewVersion()) {
|
||||
checkAndRequestPermissions(getActivity());
|
||||
migrateDataOnDemand(getActivity());
|
||||
}
|
||||
private static final int READ_EXTERNAL_STORAGE_REQUEST=1;
|
||||
private static final int WRITE_EXTERNAL_STORAGE_REQUEST=2;
|
||||
|
||||
return root;
|
||||
}
|
||||
@TargetApi(23)
|
||||
public static void checkAndRequestPermissions(final Activity activity) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
||||
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
activity.requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE_REQUEST);
|
||||
}
|
||||
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
activity.requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_REQUEST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
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);
|
||||
if (hasExistingGame) {
|
||||
TileManager tm = AndorsTrailApplication.getApplicationFromActivity(getActivity()).getWorld().tileManager;
|
||||
tm.setImageViewTileForPlayer(getResources(), save_preview_hero_icon, iconID);
|
||||
save_preview_hero_desc.setText((isDead ? getString(R.string.rip_startscreen) : "") + playerName + ", " + displayInfo);
|
||||
save_preview_holder.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
save_preview_holder.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
String playerName;
|
||||
String displayInfo = null;
|
||||
int iconID = TileManager.CHAR_HERO;
|
||||
boolean isDead = false;
|
||||
private void continueGame(boolean createNewCharacter, int loadFromSlot, String name) {
|
||||
final WorldSetup setup = AndorsTrailApplication.getApplicationFromActivity(getActivity()).getWorldSetup();
|
||||
setup.createNewCharacter = createNewCharacter;
|
||||
setup.loadFromSlot = loadFromSlot;
|
||||
setup.newHeroName = name;
|
||||
startActivity(new Intent(getActivity(), LoadingActivity.class));
|
||||
}
|
||||
|
||||
FileHeader header = Savegames.quickload(getActivity(), Savegames.SLOT_QUICKSAVE);
|
||||
if (header != null && header.playerName != null) {
|
||||
playerName = header.playerName;
|
||||
displayInfo = header.displayInfo;
|
||||
iconID = header.iconID;
|
||||
isDead = header.isDead;
|
||||
} else {
|
||||
// Before fileversion 14 (v0.6.7), quicksave was stored in Shared preferences
|
||||
SharedPreferences p = getActivity().getSharedPreferences("quicksave", Activity.MODE_PRIVATE);
|
||||
playerName = p.getString("playername", null);
|
||||
if (playerName != null) {
|
||||
displayInfo = "level " + p.getInt("level", -1);
|
||||
}
|
||||
}
|
||||
hasExistingGame = (playerName != null);
|
||||
setButtonState(playerName, displayInfo, iconID, isDead);
|
||||
|
||||
if (isNewVersion()) {
|
||||
Dialogs.showNewVersion(getActivity(), new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface arg0) {
|
||||
setCurrentVersionForVersionCheck();
|
||||
checkAndRequestPermissions(getActivity());
|
||||
migrateDataOnDemand(getActivity());
|
||||
startscreen_load.setEnabled(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
startscreen_load.setEnabled(true);
|
||||
}
|
||||
|
||||
@TargetApi(29)
|
||||
public void migrateDataOnDemand(final Activity activity) {
|
||||
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 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) {
|
||||
startscreen_load.setEnabled(true);
|
||||
}
|
||||
});
|
||||
CustomDialogFactory.show(d);
|
||||
if (!AndroidStorage.migrateToInternalStorage(activity.getApplicationContext())) {
|
||||
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),
|
||||
null,
|
||||
true);
|
||||
CustomDialogFactory.addDismissButton(errorDlg, android.R.string.ok);
|
||||
d.cancel();
|
||||
CustomDialogFactory.show(errorDlg);
|
||||
}
|
||||
} else {
|
||||
L.log("INFO: No external files or destination folder ist not empty. No data migration.");
|
||||
}
|
||||
} else {
|
||||
L.log("INFO: No read permission on external folder. No data migration.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final int READ_EXTERNAL_STORAGE_REQUEST = 1;
|
||||
private static final int WRITE_EXTERNAL_STORAGE_REQUEST = 2;
|
||||
|
||||
@TargetApi(23)
|
||||
public static void checkAndRequestPermissions(final Activity activity) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
||||
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
activity.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE_REQUEST);
|
||||
}
|
||||
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_REQUEST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
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);
|
||||
if (hasExistingGame) {
|
||||
TileManager tm = AndorsTrailApplication.getApplicationFromActivity(getActivity()).getWorld().tileManager;
|
||||
tm.setImageViewTileForPlayer(getResources(), save_preview_hero_icon, iconID);
|
||||
save_preview_hero_desc.setText((isDead ? getString(R.string.rip_startscreen) : "") + playerName + ", " + displayInfo);
|
||||
save_preview_holder.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
save_preview_holder.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void continueGame(boolean createNewCharacter, int loadFromSlot, String name) {
|
||||
final WorldSetup setup = AndorsTrailApplication.getApplicationFromActivity(getActivity()).getWorldSetup();
|
||||
setup.createNewCharacter = createNewCharacter;
|
||||
setup.loadFromSlot = loadFromSlot;
|
||||
setup.newHeroName = name;
|
||||
startActivity(new Intent(getActivity(), LoadingActivity.class));
|
||||
}
|
||||
|
||||
private void comfirmNewGame() {
|
||||
private void comfirmNewGame() {
|
||||
// new AlertDialog.Builder(new ContextThemeWrapper(getActivity(), R.style.AndorsTrailStyle_Dialog))
|
||||
// .setTitle(R.string.startscreen_newgame)
|
||||
// .setMessage(R.string.startscreen_newgame_confirm)
|
||||
@@ -307,108 +305,96 @@ public class StartScreenActivity_MainMenu extends Fragment {
|
||||
// .create().show();
|
||||
//
|
||||
//
|
||||
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);
|
||||
CustomDialogFactory.addButton(d, android.R.string.ok, new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
createNewGame();
|
||||
}
|
||||
});
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.cancel);
|
||||
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);
|
||||
CustomDialogFactory.addButton(d, android.R.string.ok, new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
createNewGame();
|
||||
}
|
||||
});
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.cancel);
|
||||
|
||||
CustomDialogFactory.show(d);
|
||||
|
||||
}
|
||||
|
||||
CustomDialogFactory.show(d);
|
||||
private static final String versionCheck = "lastversion";
|
||||
private boolean isNewVersion() {
|
||||
SharedPreferences s = getActivity().getSharedPreferences(Constants.PREFERENCE_MODEL_LASTRUNVERSION, Activity.MODE_PRIVATE);
|
||||
int lastversion = s.getInt(versionCheck, 0);
|
||||
if (lastversion >= AndorsTrailApplication.CURRENT_VERSION) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
private void setCurrentVersionForVersionCheck() {
|
||||
SharedPreferences s = getActivity().getSharedPreferences(Constants.PREFERENCE_MODEL_LASTRUNVERSION, Activity.MODE_PRIVATE);
|
||||
Editor e = s.edit();
|
||||
e.putInt(versionCheck, AndorsTrailApplication.CURRENT_VERSION);
|
||||
e.commit();
|
||||
}
|
||||
|
||||
|
||||
private static final String versionCheck = "lastversion";
|
||||
|
||||
private boolean isNewVersion() {
|
||||
SharedPreferences s = getActivity().getSharedPreferences(Constants.PREFERENCE_MODEL_LASTRUNVERSION, Activity.MODE_PRIVATE);
|
||||
int lastversion = s.getInt(versionCheck, 0);
|
||||
if (lastversion >= AndorsTrailApplication.CURRENT_VERSION) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setCurrentVersionForVersionCheck() {
|
||||
SharedPreferences s = getActivity().getSharedPreferences(Constants.PREFERENCE_MODEL_LASTRUNVERSION, Activity.MODE_PRIVATE);
|
||||
Editor e = s.edit();
|
||||
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:
|
||||
if (resultCode != Activity.RESULT_OK) break;
|
||||
final boolean wasImportOrExport = data.getBooleanExtra("import_export", false);
|
||||
final int slot = data.getIntExtra("slot", 1);
|
||||
if (wasImportOrExport) {
|
||||
if(slot == LoadSaveActivity.SLOT_NUMBER_EXPORT_SAVEGAMES)
|
||||
Toast.makeText(getActivity(),R.string.loadsave_export_save_successfull, Toast.LENGTH_LONG).show();
|
||||
else if(slot == LoadSaveActivity.SLOT_NUMBER_IMPORT_SAVEGAMES)
|
||||
Toast.makeText(getActivity(),R.string.loadsave_import_save_successfull, Toast.LENGTH_LONG).show();
|
||||
else if(slot == LoadSaveActivity.SLOT_NUMBER_IMPORT_WORLDMAP)
|
||||
Toast.makeText(getActivity(),R.string.loadsave_import_worldmap_successfull, Toast.LENGTH_LONG).show();
|
||||
|
||||
break;
|
||||
}
|
||||
continueGame(false, slot, null);
|
||||
break;
|
||||
case INTENTREQUEST_PREFERENCES:
|
||||
updatePreferences(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
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; }
|
||||
|
||||
@@ -274,168 +274,83 @@ public final class ResourceLoader {
|
||||
loader.prepareTileset(R.drawable.ui_icon_immunity, "ui_icon_immunity", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_dynamic_placeholders, "map_dynamic_placeholders", new Size(10, 2), sz1x1, mTileSize);
|
||||
|
||||
loader.prepareTileset(R.drawable.actorconditions_1, "actorconditions_1", new Size(14, 8), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.actorconditions_2, "actorconditions_2", sz3x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.actorconditions_japozero, "actorconditions_japozero", new Size(16, 4), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.actorconditions_omi1, "actorconditions_omi1", sz2x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.actorconditions_omi2, "actorconditions_omi2", sz5x1, sz1x1, mTileSize);
|
||||
/*INSERT_ACTORCONDITIONS_TILESETS_HERE*/
|
||||
|
||||
loader.prepareTileset(R.drawable.items_armours, "items_armours", new Size(14, 3), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_weapons, "items_weapons", new Size(14, 6), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_jewelry, "items_jewelry", new Size(14, 1), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_consumables, "items_consumables", new Size(14, 5), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_books, "items_books", new Size(11, 1), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_misc, "items_misc", new Size(14, 4), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_misc_2, "items_misc_2", sz20x12, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_misc_3, "items_misc_3", sz20x12, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_misc_4, "items_misc_4", new Size(20, 4), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_misc_5, "items_misc_5", new Size(9, 5), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_misc_6, "items_misc_6", new Size(9, 4), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_reterski_1, "items_reterski_1", new Size(3, 10), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_tometik1, "items_tometik1", new Size(6, 10), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_tometik2, "items_tometik2", new Size(10, 10), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_tometik3, "items_tometik3", new Size(8, 6), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_necklaces_1, "items_necklaces_1", new Size(10, 3), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_weapons_2, "items_weapons_2", new Size(7, 1), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_weapons_3, "items_weapons_3", new Size(13, 5), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_armours_2, "items_armours_2", sz7x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_armours_3, "items_armours_3", new Size(10, 4), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_rings_1, "items_rings_1", new Size(10, 3), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_japozero, "items_japozero", new Size(16, 37), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_rijackson_1, "items_rijackson_1", new Size(5, 4), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_g03_package_omi1, "items_g03_package_omi1", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_consumables_omi1, "items_consumables_omi1", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_feygard1, "items_feygard1", new Size(6, 2), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.items_omi2, "items_omi2", new Size(6, 5), sz1x1, mTileSize);
|
||||
/*INSERT_ITEMS_TILESETS_HERE*/
|
||||
|
||||
loader.prepareTileset(R.drawable.monsters_armor1, "monsters_armor1", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_cyclops, "monsters_cyclops", sz1x1, sz2x3, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_demon1, "monsters_demon1", sz1x1, sz2x2, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_demon2, "monsters_demon2", sz1x1, sz2x2, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_dogs, "monsters_dogs", sz7x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_eye1, "monsters_eye1", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_eye2, "monsters_eye2", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_eye3, "monsters_eye3", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_eye4, "monsters_eye4", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_ghost1, "monsters_ghost1", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_hydra1, "monsters_hydra1", sz1x1, sz2x2, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_insects, "monsters_insects", sz6x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_karvis1, "monsters_karvis1", sz2x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_karvis2, "monsters_karvis2", new Size(9, 1), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_ld1, "monsters_ld1", new Size(20, 12), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_ld2, "monsters_ld2", new Size(20, 12), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_liches, "monsters_liches", new Size(4, 1), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_mage, "monsters_mage", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_mage2, "monsters_mage2", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_man1, "monsters_man1", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_men, "monsters_men", new Size(9, 1), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_men2, "monsters_men2", new Size(10, 1), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_misc, "monsters_misc", new Size(13, 1), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_rats, "monsters_rats", new Size(5, 1), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_redshrike1, "monsters_redshrike1", sz7x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_rltiles1, "monsters_rltiles1", new Size(20, 8), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_rltiles2, "monsters_rltiles2", new Size(20, 9), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_rltiles3, "monsters_rltiles3", new Size(10, 3), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_rltiles4, "monsters_rltiles4", new Size(12, 4), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_rogue1, "monsters_rogue1", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_skeleton1, "monsters_skeleton1", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_skeleton2, "monsters_skeleton2", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_snakes, "monsters_snakes", sz6x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_tometik1, "monsters_tometik1", new Size(10, 9), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_tometik2, "monsters_tometik2", new Size(8, 10), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_tometik3, "monsters_tometik3", new Size(6, 13), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_tometik4, "monsters_tometik4", new Size(6, 13), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_tometik5, "monsters_tometik5", new Size(6, 16), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_tometik6, "monsters_tometik6", new Size(7, 6), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_tometik7, "monsters_tometik7", new Size(8, 11), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_tometik8, "monsters_tometik8", new Size(7, 9), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_tometik9, "monsters_tometik9", new Size(8, 8), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_tometik10, "monsters_tometik10", new Size(6, 13), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_wraiths, "monsters_wraiths", sz3x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_zombie1, "monsters_zombie1", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_zombie2, "monsters_zombie2", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_guynmart, "monsters_guynmart", new Size(8, 2), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_maksiu1, "monsters_maksiu1", new Size(4, 4), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_omi1, "monsters_omi1", sz2x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_omi1_b, "monsters_omi1_b", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_unknown, "monsters_unknown", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_arulirs, "monsters_arulirs", new Size(8, 2), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_fatboy73, "monsters_fatboy73", new Size(20, 12), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_giantbasilisk, "monsters_giantbasilisk", sz1x1, sz2x2, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_gisons, "monsters_gisons", new Size(8, 2), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_bosses_2x2, "monsters_bosses_2x2", sz1x1, sz2x2, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_omi2, "monsters_omi2", sz8x3, sz1x1, mTileSize);
|
||||
/*INSERT_NPCS_TILESETS_HERE*/
|
||||
|
||||
loader.prepareTileset(R.drawable.map_bed_1, "map_bed_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_border_1, "map_border_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_bridge_1, "map_bridge_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_bridge_2, "map_bridge_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_broken_1, "map_broken_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_cavewall_1, "map_cavewall_1", new Size(18, 6), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_cavewall_2, "map_cavewall_2", new Size(18, 6), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_cavewall_3, "map_cavewall_3", new Size(18, 6), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_cavewall_4, "map_cavewall_4", new Size(18, 6), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_chair_table_1, "map_chair_table_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_chair_table_2, "map_chair_table_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_crate_1, "map_crate_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_cupboard_1, "map_cupboard_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_curtain_1, "map_curtain_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_entrance_1, "map_entrance_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_entrance_2, "map_entrance_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_fence_1, "map_fence_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_fence_2, "map_fence_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_fence_3, "map_fence_3", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_fence_4, "map_fence_4", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_ground_1, "map_ground_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_ground_2, "map_ground_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_ground_3, "map_ground_3", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_ground_4, "map_ground_4", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_ground_5, "map_ground_5", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_ground_6, "map_ground_6", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_ground_7, "map_ground_7", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_ground_8, "map_ground_8", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_house_1, "map_house_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_house_2, "map_house_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_indoor_1, "map_indoor_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_indoor_2, "map_indoor_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_kitchen_1, "map_kitchen_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_outdoor_1, "map_outdoor_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_pillar_1, "map_pillar_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_pillar_2, "map_pillar_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_plant_1, "map_plant_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_plant_2, "map_plant_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_rock_1, "map_rock_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_rock_2, "map_rock_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_roof_1, "map_roof_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_roof_2, "map_roof_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_roof_3, "map_roof_3", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_shop_1, "map_shop_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_sign_ladder_1, "map_sign_ladder_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_table_1, "map_table_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_table_2, "map_table_2", new Size(14, 8), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_trail_1, "map_trail_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_transition_1, "map_transition_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_transition_2, "map_transition_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_transition_3, "map_transition_3", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_transition_4, "map_transition_4", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_transition_5, "map_transition_5", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_tree_1, "map_tree_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_tree_2, "map_tree_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_wall_1, "map_wall_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_wall_2, "map_wall_2", new Size(15, 8), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_wall_3, "map_wall_3", new Size(15, 8), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_wall_4, "map_wall_4", new Size(15, 8), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_window_1, "map_window_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_window_2, "map_window_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_guynmart, "map_guynmart", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_cavewall_5, "map_cavewall_5", new Size(6, 6), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_rock_3, "map_rock_3", new Size(6, 5), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_sign_ladder_omi2, "map_sign_ladder_omi2", new Size(8, 4), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_transition_6, "map_transition_6", new Size(18, 8), sz1x1, mTileSize);
|
||||
/*INSERT_MAP_TILESETS_HERE*/
|
||||
|
||||
loader.prepareTileset(R.drawable.map_0, "map_0", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_1, "map_1", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_10, "map_10", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_11, "map_11", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_12, "map_12", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_13, "map_13", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_14, "map_14", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_15, "map_15", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_16, "map_16", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_17, "map_17", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_18, "map_18", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_19, "map_19", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_2, "map_2", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_20, "map_20", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_21, "map_21", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_22, "map_22", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_23, "map_23", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_24, "map_24", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_25, "map_25", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_26, "map_26", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_27, "map_27", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_28, "map_28", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_29, "map_29", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_3, "map_3", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_30, "map_30", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_31, "map_31", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_32, "map_32", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_33, "map_33", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_34, "map_34", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_35, "map_35", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_36, "map_36", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_37, "map_37", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_38, "map_38", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_39, "map_39", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_4, "map_4", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_40, "map_40", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_41, "map_41", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_42, "map_42", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_43, "map_43", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_44, "map_44", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_45, "map_45", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_46, "map_46", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_47, "map_47", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_48, "map_48", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_49, "map_49", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_5, "map_5", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_50, "map_50", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_51, "map_51", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_52, "map_52", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_53, "map_53", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_54, "map_54", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_6, "map_6", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_7, "map_7", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_8, "map_8", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_9, "map_9", sz8x8, sz1x1, mTileSize);
|
||||
|
||||
loader.prepareTileset(R.drawable.obj_0, "obj_0", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_1, "obj_1", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_10, "obj_10", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_11, "obj_11", sz8x8, sz1x1, mTileSize);
|
||||
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_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);
|
||||
loader.prepareTileset(R.drawable.obj_5, "obj_5", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_6, "obj_6", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_7, "obj_7", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_8, "obj_8", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_9, "obj_9", sz8x8, sz1x1, mTileSize);
|
||||
|
||||
loader.prepareTileset(R.drawable.effect_blood4, "effect_blood4", new Size(7, 2), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.effect_heal2, "effect_heal2", new Size(8, 2), sz1x1, mTileSize);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.gpl.rpg.AndorsTrail.savegames;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Console;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
@@ -34,358 +33,345 @@ import com.gpl.rpg.AndorsTrail.util.AndroidStorage;
|
||||
import com.gpl.rpg.AndorsTrail.util.L;
|
||||
|
||||
public final class Savegames {
|
||||
public static final int SLOT_QUICKSAVE = 0;
|
||||
public static final long DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED = -1;
|
||||
public static final int SLOT_QUICKSAVE = 0;
|
||||
public static final long DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED = -1;
|
||||
|
||||
private static long lastBackup = 0;
|
||||
private static long lastBackup = 0;
|
||||
|
||||
|
||||
public static enum LoadSavegameResult {
|
||||
success, unknownError, savegameIsFromAFutureVersion, cheatingDetected
|
||||
}
|
||||
|
||||
public static boolean saveWorld(WorldContext world, Context androidContext, int slot) {
|
||||
try {
|
||||
final String displayInfo = androidContext.getString(R.string.savegame_currenthero_displayinfo, world.model.player.getLevel(), world.model.player.getTotalExperience(), world.model.player.getGold());
|
||||
if (slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
|
||||
world.model.player.savedVersion++;
|
||||
}
|
||||
String id = world.model.player.id;
|
||||
long savedVersion = world.model.player.savedVersion;
|
||||
public static enum LoadSavegameResult {
|
||||
success
|
||||
, unknownError
|
||||
, savegameIsFromAFutureVersion
|
||||
, cheatingDetected
|
||||
}
|
||||
|
||||
// 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();
|
||||
public static boolean saveWorld(WorldContext world, Context androidContext, int slot) {
|
||||
try {
|
||||
final String displayInfo = androidContext.getString(R.string.savegame_currenthero_displayinfo, world.model.player.getLevel(), world.model.player.getTotalExperience(), world.model.player.getGold());
|
||||
if (slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
|
||||
world.model.player.savedVersion++;
|
||||
}
|
||||
String id = world.model.player.id;
|
||||
long savedVersion = world.model.player.savedVersion;
|
||||
|
||||
FileOutputStream fos = getOutputFile(androidContext, slot);
|
||||
fos.write(savegame);
|
||||
fos.close();
|
||||
// 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();
|
||||
|
||||
if (!world.model.statistics.hasUnlimitedSaves()) {
|
||||
if (slot != SLOT_QUICKSAVE) {
|
||||
androidContext.deleteFile(Constants.FILENAME_SAVEGAME_QUICKSAVE);
|
||||
writeCheatCheck(androidContext, savedVersion, id);
|
||||
} else if (SystemClock.uptimeMillis() > lastBackup + 120000) {
|
||||
writeBackup(androidContext, savegame, id);
|
||||
lastBackup = SystemClock.uptimeMillis();
|
||||
}
|
||||
}
|
||||
FileOutputStream fos = getOutputFile(androidContext, slot);
|
||||
fos.write(savegame);
|
||||
fos.close();
|
||||
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
L.log("Error saving world: " + e.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!world.model.statistics.hasUnlimitedSaves()) {
|
||||
if (slot != SLOT_QUICKSAVE) {
|
||||
androidContext.deleteFile(Constants.FILENAME_SAVEGAME_QUICKSAVE);
|
||||
writeCheatCheck(androidContext, savedVersion, id);
|
||||
} else if (SystemClock.uptimeMillis() > lastBackup + 120000) {
|
||||
writeBackup(androidContext, savegame, id);
|
||||
lastBackup = SystemClock.uptimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeBackup(Context androidContext, byte[] savegame, String playerId) throws IOException {
|
||||
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
|
||||
ensureDirExists(cheatDetectionFolder);
|
||||
File backupFile = new File(cheatDetectionFolder, playerId + "X");
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(backupFile);
|
||||
fileOutputStream.write(savegame);
|
||||
fileOutputStream.close();
|
||||
}
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
L.log("Error saving world: " + e.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static LoadSavegameResult loadWorld(WorldContext world, ControllerContext controllers, Context androidContext, int slot) {
|
||||
try {
|
||||
FileHeader fh = quickload(androidContext, slot);
|
||||
if (fh == null) {
|
||||
return LoadSavegameResult.unknownError;
|
||||
}
|
||||
if (!fh.hasUnlimitedSaves && slot != SLOT_QUICKSAVE && triedToCheat(androidContext, fh)) {
|
||||
return LoadSavegameResult.cheatingDetected;
|
||||
}
|
||||
private static void writeBackup(Context androidContext, byte[] savegame, String playerId) throws IOException {
|
||||
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
|
||||
if (!cheatDetectionFolder.exists()) cheatDetectionFolder.mkdir();
|
||||
File backupFile = new File(cheatDetectionFolder, playerId + "X");
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(backupFile);
|
||||
fileOutputStream.write(savegame);
|
||||
fileOutputStream.close();
|
||||
}
|
||||
|
||||
FileInputStream fos = getInputFile(androidContext, slot);
|
||||
LoadSavegameResult result = loadWorld(androidContext.getResources(), world, controllers, fos, fh);
|
||||
fos.close();
|
||||
if (result == LoadSavegameResult.success && slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
|
||||
public static LoadSavegameResult loadWorld(WorldContext world, ControllerContext controllers, Context androidContext, int slot) {
|
||||
try {
|
||||
FileHeader fh = quickload(androidContext, slot);
|
||||
if(fh == null) {
|
||||
return LoadSavegameResult.unknownError;
|
||||
}
|
||||
if (!fh.hasUnlimitedSaves && slot != SLOT_QUICKSAVE && triedToCheat(androidContext, fh)) {
|
||||
return LoadSavegameResult.cheatingDetected;
|
||||
}
|
||||
|
||||
FileInputStream fos = getInputFile(androidContext, slot);
|
||||
LoadSavegameResult result = loadWorld(androidContext.getResources(), world, controllers, fos, fh);
|
||||
fos.close();
|
||||
if (result == LoadSavegameResult.success && slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
|
||||
// save to the quicksave slot before deleting the file
|
||||
if (!saveWorld(world, androidContext, SLOT_QUICKSAVE)) {
|
||||
return LoadSavegameResult.unknownError;
|
||||
}
|
||||
getSlotFile(slot, androidContext).delete();
|
||||
writeCheatCheck(androidContext, DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED, fh.playerId);
|
||||
}
|
||||
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 LoadSavegameResult.unknownError;
|
||||
}
|
||||
}
|
||||
return LoadSavegameResult.unknownError;
|
||||
}
|
||||
getSlotFile(slot, androidContext).delete();
|
||||
writeCheatCheck(androidContext, DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED, fh.playerId);
|
||||
}
|
||||
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 LoadSavegameResult.unknownError;
|
||||
}
|
||||
}
|
||||
|
||||
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 (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);
|
||||
}
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
|
||||
L.log("Internal cheatcheck file savedVersion: " + cheatDetection.savedVersion);
|
||||
}
|
||||
|
||||
dataInputStream.close();
|
||||
fileInputStream.close();
|
||||
}
|
||||
dataInputStream.close();
|
||||
fileInputStream.close();
|
||||
}
|
||||
|
||||
return (savedVersionToCheck == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED || fh.savedVersion < savedVersionToCheck);
|
||||
}
|
||||
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 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 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 void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException {
|
||||
DataOutputStream dest = new DataOutputStream(outStream);
|
||||
FileHeader.writeToParcel(dest, world.model.player.getName(),
|
||||
displayInfo, world.model.player.iconID,
|
||||
world.model.statistics.isDead(),
|
||||
world.model.statistics.hasUnlimitedSaves(),
|
||||
world.model.player.id,
|
||||
world.model.player.savedVersion);
|
||||
world.maps.writeToParcel(dest, world);
|
||||
world.model.writeToParcel(dest);
|
||||
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 void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException {
|
||||
DataOutputStream dest = new DataOutputStream(outStream);
|
||||
FileHeader.writeToParcel(dest, world.model.player.getName(),
|
||||
displayInfo, world.model.player.iconID,
|
||||
world.model.statistics.isDead(),
|
||||
world.model.statistics.hasUnlimitedSaves(),
|
||||
world.model.player.id,
|
||||
world.model.player.savedVersion);
|
||||
world.maps.writeToParcel(dest, world);
|
||||
world.model.writeToParcel(dest);
|
||||
dest.close();
|
||||
}
|
||||
|
||||
world.maps.readFromParcel(src, world, controllers, header.fileversion);
|
||||
world.model = new ModelContainer(src, world, controllers, header.fileversion);
|
||||
src.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;
|
||||
|
||||
if (header.fileversion < 45) {
|
||||
LegacySavegamesContentAdaptations.adaptToNewContentForVersion45(world, controllers, res);
|
||||
}
|
||||
world.maps.readFromParcel(src, world, controllers, header.fileversion);
|
||||
world.model = new ModelContainer(src, world, controllers, header.fileversion);
|
||||
src.close();
|
||||
|
||||
if (header.fileversion < 45) {
|
||||
LegacySavegamesContentAdaptations.adaptToNewContentForVersion45(world, controllers, res);
|
||||
}
|
||||
|
||||
onWorldLoaded(res, world, controllers);
|
||||
|
||||
onWorldLoaded(res, world, controllers);
|
||||
return LoadSavegameResult.success;
|
||||
}
|
||||
|
||||
return LoadSavegameResult.success;
|
||||
}
|
||||
private static void onWorldLoaded(Resources res, WorldContext world, ControllerContext controllers) {
|
||||
controllers.actorStatsController.recalculatePlayerStats(world.model.player);
|
||||
controllers.mapController.resetMapsNotRecentlyVisited();
|
||||
controllers.movementController.prepareMapAsCurrentMap(world.model.currentMaps.map, res, false);
|
||||
controllers.gameRoundController.resetRoundTimers();
|
||||
}
|
||||
|
||||
private static void onWorldLoaded(Resources res, WorldContext world, ControllerContext controllers) {
|
||||
controllers.actorStatsController.recalculatePlayerStats(world.model.player);
|
||||
controllers.mapController.resetMapsNotRecentlyVisited();
|
||||
controllers.movementController.prepareMapAsCurrentMap(world.model.currentMaps.map, res, false);
|
||||
controllers.gameRoundController.resetRoundTimers();
|
||||
}
|
||||
public static FileHeader quickload(Context androidContext, int slot) {
|
||||
try {
|
||||
if (slot != SLOT_QUICKSAVE) {
|
||||
File f = getSlotFile(slot, androidContext);
|
||||
if (!f.exists()) return null;
|
||||
}
|
||||
FileInputStream fos = getInputFile(androidContext, slot);
|
||||
DataInputStream src = new DataInputStream(fos);
|
||||
final FileHeader header = new FileHeader(src, false);
|
||||
src.close();
|
||||
fos.close();
|
||||
return header;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static FileHeader quickload(Context androidContext, int slot) {
|
||||
try {
|
||||
if (slot != SLOT_QUICKSAVE) {
|
||||
File f = getSlotFile(slot, androidContext);
|
||||
if (!f.exists()) return null;
|
||||
}
|
||||
FileInputStream fos = getInputFile(androidContext, slot);
|
||||
DataInputStream src = new DataInputStream(fos);
|
||||
final FileHeader header = new FileHeader(src, false);
|
||||
src.close();
|
||||
fos.close();
|
||||
return header;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
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();
|
||||
|
||||
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();
|
||||
fileOutputStream = androidContext.openFileOutput(playerId, Context.MODE_PRIVATE);
|
||||
dataOutputStream = new DataOutputStream(fileOutputStream);
|
||||
CheatDetection.writeToParcel(dataOutputStream, savedVersion);
|
||||
dataOutputStream.close();
|
||||
fileOutputStream.close();
|
||||
}
|
||||
|
||||
fileOutputStream = androidContext.openFileOutput(playerId, Context.MODE_PRIVATE);
|
||||
dataOutputStream = new DataOutputStream(fileOutputStream);
|
||||
CheatDetection.writeToParcel(dataOutputStream, savedVersion);
|
||||
dataOutputStream.close();
|
||||
fileOutputStream.close();
|
||||
}
|
||||
private static final Pattern savegameFilenamePattern = Pattern.compile(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + "(\\d+)");
|
||||
|
||||
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 null;
|
||||
}
|
||||
}
|
||||
|
||||
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>();
|
||||
}
|
||||
}
|
||||
private static final class CheatDetection {
|
||||
public final int fileversion;
|
||||
public final long savedVersion;
|
||||
|
||||
private static final class CheatDetection {
|
||||
public final int fileversion;
|
||||
public final long savedVersion;
|
||||
// ====== PARCELABLE ===================================================================
|
||||
|
||||
// ====== PARCELABLE ===================================================================
|
||||
public CheatDetection(DataInputStream src) throws IOException {
|
||||
this.fileversion = src.readInt();
|
||||
this.savedVersion = src.readLong();
|
||||
}
|
||||
|
||||
public CheatDetection(DataInputStream src) throws IOException {
|
||||
this.fileversion = src.readInt();
|
||||
this.savedVersion = src.readLong();
|
||||
}
|
||||
|
||||
public static void writeToParcel(DataOutputStream dest, long savedVersion) throws IOException {
|
||||
dest.writeInt(AndorsTrailApplication.CURRENT_VERSION);
|
||||
dest.writeLong(savedVersion);
|
||||
}
|
||||
}
|
||||
public static void writeToParcel(DataOutputStream dest, long savedVersion) throws IOException {
|
||||
dest.writeInt(AndorsTrailApplication.CURRENT_VERSION);
|
||||
dest.writeLong(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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// ====== PARCELABLE ===================================================================
|
||||
// ====== 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();
|
||||
if (skipIcon || id > TileManager.LAST_HERO) {
|
||||
this.iconID = TileManager.CHAR_HERO_0;
|
||||
this.skipIcon = true;
|
||||
} else {
|
||||
this.iconID = id;
|
||||
}
|
||||
} else {
|
||||
this.iconID = TileManager.CHAR_HERO_0;
|
||||
}
|
||||
if (fileversion >= 43) {
|
||||
int id = src.readInt();
|
||||
if (skipIcon || id > TileManager.LAST_HERO) {
|
||||
this.iconID = TileManager.CHAR_HERO_0;
|
||||
this.skipIcon = true;
|
||||
} else {
|
||||
this.iconID = id;
|
||||
}
|
||||
} else {
|
||||
this.iconID = TileManager.CHAR_HERO_0;
|
||||
}
|
||||
|
||||
if (fileversion >= 49) {
|
||||
this.isDead = src.readBoolean();
|
||||
this.hasUnlimitedSaves = src.readBoolean();
|
||||
this.playerId = src.readUTF();
|
||||
this.savedVersion = src.readLong();
|
||||
} else {
|
||||
this.isDead = false;
|
||||
this.hasUnlimitedSaves = true;
|
||||
this.playerId = "";
|
||||
this.savedVersion = 0;
|
||||
}
|
||||
}
|
||||
if (fileversion >= 49) {
|
||||
this.isDead = src.readBoolean();
|
||||
this.hasUnlimitedSaves = src.readBoolean();
|
||||
this.playerId = src.readUTF();
|
||||
this.savedVersion = src.readLong();
|
||||
} else {
|
||||
this.isDead = false;
|
||||
this.hasUnlimitedSaves = true;
|
||||
this.playerId = "";
|
||||
this.savedVersion = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeToParcel(DataOutputStream dest, String playerName, String displayInfo, int iconID, boolean isDead, boolean hasUnlimitedSaves, String playerId, long savedVersion) throws IOException {
|
||||
dest.writeInt(AndorsTrailApplication.CURRENT_VERSION);
|
||||
dest.writeUTF(playerName);
|
||||
dest.writeUTF(displayInfo);
|
||||
dest.writeInt(iconID);
|
||||
dest.writeBoolean(isDead);
|
||||
dest.writeBoolean(hasUnlimitedSaves);
|
||||
dest.writeUTF(playerId);
|
||||
dest.writeLong(savedVersion);
|
||||
}
|
||||
}
|
||||
public static void writeToParcel(DataOutputStream dest, String playerName, String displayInfo, int iconID, boolean isDead, boolean hasUnlimitedSaves, String playerId, long savedVersion) throws IOException {
|
||||
dest.writeInt(AndorsTrailApplication.CURRENT_VERSION);
|
||||
dest.writeUTF(playerName);
|
||||
dest.writeUTF(displayInfo);
|
||||
dest.writeInt(iconID);
|
||||
dest.writeBoolean(isDead);
|
||||
dest.writeBoolean(hasUnlimitedSaves);
|
||||
dest.writeUTF(playerId);
|
||||
dest.writeLong(savedVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
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.NonNull;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.support.v4.provider.DocumentFile;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.controller.Constants;
|
||||
|
||||
@@ -23,14 +17,14 @@ import java.io.OutputStream;
|
||||
|
||||
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);
|
||||
@@ -42,7 +36,7 @@ public final class AndroidStorage {
|
||||
&& (
|
||||
!internalSaveGameDirectory.exists()
|
||||
|| internalSaveGameDirectory.isDirectory() && internalSaveGameDirectory.listFiles().length < 2)
|
||||
) {
|
||||
) {
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
@@ -82,90 +76,33 @@ 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);
|
||||
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);
|
||||
}
|
||||
} finally {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the MIME-Type for a file.<p/>
|
||||
* Fallback value is '* / *' (without spaces) <p/>
|
||||
* Mostly copied together from: <a href="https://stackoverflow.com/q/8589645/17292289">StackOverflow</a>
|
||||
*/
|
||||
@NonNull
|
||||
public static String getMimeType(ContentResolver resolver, Uri uri) {
|
||||
String type = null;
|
||||
if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
|
||||
type = resolver.getType(uri);
|
||||
return type;
|
||||
}
|
||||
|
||||
final String extension = MimeTypeMap.getFileExtensionFromUrl(uri.getPath());
|
||||
if (extension != null) {
|
||||
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
|
||||
}
|
||||
if (type == null) {
|
||||
type = "*/*"; // fallback type.
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
public static String getUrlForFile(Context context, File worldmap) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
Uri uri = FileProvider.getUriForFile(context, "com.gpl.rpg.AndorsTrail_beta2.fileprovider", worldmap);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
Uri uri = FileProvider.getUriForFile(context, "com.gpl.rpg.AndorsTrail.fileprovider", worldmap);
|
||||
return uri.toString();
|
||||
} else {
|
||||
return "file://" + worldmap.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public static Intent getNewOpenDirectoryIntent() {
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
return intent;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,167 +22,156 @@ import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
|
||||
|
||||
public class CustomDialogFactory {
|
||||
|
||||
public static class CustomDialog extends Dialog {
|
||||
public CustomDialog(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 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 {
|
||||
if (canDismiss) {
|
||||
this.dismiss();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
TextView title = (TextView) this.getWindow().getDecorView().findViewById(R.id.dialog_title);
|
||||
if (title != null && title.getCompoundDrawables() != null && title.getCompoundDrawables()[0] != null) {
|
||||
if (title.getCompoundDrawables()[0] instanceof AnimationDrawable) {
|
||||
((AnimationDrawable) title.getCompoundDrawables()[0]).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(R.layout.custom_dialog_title_icon);
|
||||
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
|
||||
if (((AndorsTrailApplication) context.getApplicationContext()).getPreferences().fullscreen) {
|
||||
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
} else {
|
||||
dialog.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
}
|
||||
|
||||
setTitle(dialog, title, icon);
|
||||
|
||||
setDesc(dialog, desc);
|
||||
|
||||
setContent(dialog, content);
|
||||
|
||||
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) {
|
||||
titleView.setText(title);
|
||||
titleView.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
|
||||
titleView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
titleView.setVisibility(View.GONE);
|
||||
}
|
||||
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);
|
||||
if (desc != null) {
|
||||
descView.setText(desc);
|
||||
descHolder.setVisibility(View.VISIBLE);
|
||||
descView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
descHolder.setVisibility(View.GONE);
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static CustomDialog setContent(final CustomDialog dialog, View content) {
|
||||
ViewGroup contentHolder = (ViewGroup) dialog.findViewById(R.id.dialog_content_container);
|
||||
if (content != null) {
|
||||
contentHolder.addView(content);
|
||||
contentHolder.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
contentHolder.setVisibility(View.GONE);
|
||||
}
|
||||
return 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 = (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));
|
||||
|
||||
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 Dialog addDismissButton(final Dialog dialog, int textId) {
|
||||
return CustomDialogFactory.addButton(dialog, textId, new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Dialog setDismissListener(Dialog dialog, OnDismissListener listener) {
|
||||
dialog.setOnDismissListener(listener);
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static void show(Dialog dialog) {
|
||||
|
||||
dialog.findViewById(R.id.dialog_template_button).setVisibility(View.GONE);
|
||||
dialog.show();
|
||||
|
||||
}
|
||||
|
||||
public static class CustomDialog extends Dialog {
|
||||
public CustomDialog(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 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 {
|
||||
if (canDismiss) {
|
||||
this.dismiss();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
TextView title = (TextView) this.getWindow().getDecorView().findViewById(R.id.dialog_title);
|
||||
if (title != null && title.getCompoundDrawables() != null && title.getCompoundDrawables()[0] != null) {
|
||||
if (title.getCompoundDrawables()[0] instanceof AnimationDrawable) {
|
||||
((AnimationDrawable)title.getCompoundDrawables()[0]).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(R.layout.custom_dialog_title_icon);
|
||||
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
|
||||
if (((AndorsTrailApplication)context.getApplicationContext()).getPreferences().fullscreen) {
|
||||
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
} else {
|
||||
dialog.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
}
|
||||
|
||||
setTitle(dialog, title, icon);
|
||||
|
||||
setDesc(dialog, desc);
|
||||
|
||||
setContent(dialog, content);
|
||||
|
||||
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 setTitle(final CustomDialog dialog, String title, Drawable icon) {
|
||||
TextView titleView = (TextView) dialog.findViewById(R.id.dialog_title);
|
||||
if (title != null || icon != null) {
|
||||
titleView.setText(title);
|
||||
titleView.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
|
||||
titleView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
titleView.setVisibility(View.GONE);
|
||||
}
|
||||
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);
|
||||
if (desc != null) {
|
||||
descView.setText(desc);
|
||||
descHolder.setVisibility(View.VISIBLE);
|
||||
descView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
descHolder.setVisibility(View.GONE);
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static CustomDialog setContent(final CustomDialog dialog, View content) {
|
||||
ViewGroup contentHolder = (ViewGroup) dialog.findViewById(R.id.dialog_content_container);
|
||||
if (content != null) {
|
||||
contentHolder.addView(content);
|
||||
contentHolder.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
contentHolder.setVisibility(View.GONE);
|
||||
}
|
||||
return 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 = (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));
|
||||
|
||||
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 Dialog addDismissButton(final Dialog dialog, int textId) {
|
||||
return CustomDialogFactory.addButton(dialog, textId, new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Dialog setDismissListener(Dialog dialog, OnDismissListener listener) {
|
||||
dialog.setOnDismissListener(listener);
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static void show(Dialog dialog) {
|
||||
|
||||
dialog.findViewById(R.id.dialog_template_button).setVisibility(View.GONE);
|
||||
dialog.show();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,51 +4,29 @@ APK 65 (0.8.1) //Engine modernization + Sullengard
|
||||
|
||||
Release notes
|
||||
=============
|
||||
Hello fellow adventurers,
|
||||
* Reorginization of the engine! It can be compiled by actual AS versions, as well as go to F-Droid at last.
|
||||
This is worth a new release number 0.8!
|
||||
* The content files stay in their usual directories, so Weblate and ATCS projects needn't be changed.
|
||||
|
||||
it took a while - much longer than we planned - but it was worth the wait:
|
||||
* New quest: "Hunting the hunter"
|
||||
* New quest: "Getting home on time"
|
||||
You find these quests on your way to Sullengard.
|
||||
|
||||
[list]We have a big update with 71 new maps and 6 new quests for you![/list]
|
||||
|
||||
[list]3 Additions from Guro-meditation-No42:
|
||||
[list]Kill count summed up for monsters with same name (a minor irritation)[/list]
|
||||
[list]Show kills of monsters in monster stat view (often requested)[/list]
|
||||
[list]Controller support (not yet tested)[/list]
|
||||
[/list]
|
||||
[list]Also we modernized the engine (Many thanks to OMGeeky), so that you can now use the current Android Studio version to create the APK.
|
||||
This will be easier for new developers, and it should enable F-Droid to publish Andor's Trail again![/list]
|
||||
* New quest: "Pond safety"
|
||||
* New quest: "Recovering stolen property"
|
||||
Look for these in Sullengard.
|
||||
|
||||
Enough reason to start a new release number: v0.8
|
||||
* New quest: "Beer Bootlegging"
|
||||
Starts at the Foaming flask.
|
||||
|
||||
* New quest: "Another ruthless Crackshot"
|
||||
Sound like thieves affairs, so ask at the Guild.
|
||||
|
||||
There is a big new area and a new city called Sullengard to the southeast - follow the Duleian road, you can't miss it. But beware, the beasts are really dangerous!! Don't venture there too early or you'll find yourself waking up in a bed more often than you want...
|
||||
* Two more achievements
|
||||
* 72 new maps
|
||||
|
||||
On your way to Sullengard you may find two quests
|
||||
[list]"Hunting the hunter" [/list]
|
||||
[list]"Getting home on time"[/list]
|
||||
|
||||
Look for these two quests in Sullengard:
|
||||
[list]"Pond safety"[/list]
|
||||
[list]"Recovering stolen property"[/list]
|
||||
|
||||
The following two quests are found elsewhere:
|
||||
[list]"Beer Bootlegging" starts at the Foaming flask[/list]
|
||||
[list]"Another ruthless Crackshot" not only sounds like thieves affairs, so ask at the Guild.[/list]
|
||||
|
||||
I won't tell more about the quests, I trust you to find out yourself - it's more fun after all.
|
||||
|
||||
|
||||
Translations are actualized, many languages are at 93% now. That would have been 100%, if we hadn't added the new quests.
|
||||
This is great - Thanks to all the translators!
|
||||
|
||||
Maybe you will notice that a few already translated texts are now in English again. This has technical reasons which I couldn't avoid - sorry for the inconvenience.
|
||||
|
||||
|
||||
Here is the link to the productive version: [url]https://andorstrail.com/static/AndorsTrail_v0.8.1.apk[/url]
|
||||
|
||||
Google Play and Itch will follow soon, and hopefully this version can also be provided by F-Droid again.
|
||||
|
||||
Thx for your patience - have fun with the new release!
|
||||
* Various small changes and bug fixes
|
||||
* Translations actualized
|
||||
|
||||
|
||||
Forum beta announcement //2022-08-27
|
||||
|
||||
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 1017 B |
|
Before Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 28 KiB |
BIN
AndorsTrail/res/drawable/map_0.png
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
AndorsTrail/res/drawable/map_1.png
Normal file
|
After Width: | Height: | Size: 145 KiB |
BIN
AndorsTrail/res/drawable/map_10.png
Normal file
|
After Width: | Height: | Size: 101 KiB |
BIN
AndorsTrail/res/drawable/map_11.png
Normal file
|
After Width: | Height: | Size: 120 KiB |
BIN
AndorsTrail/res/drawable/map_12.png
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
AndorsTrail/res/drawable/map_13.png
Normal file
|
After Width: | Height: | Size: 143 KiB |
BIN
AndorsTrail/res/drawable/map_14.png
Normal file
|
After Width: | Height: | Size: 153 KiB |
BIN
AndorsTrail/res/drawable/map_15.png
Normal file
|
After Width: | Height: | Size: 112 KiB |