Compare commits
3 Commits
v0.8.7_com
...
as3_migrat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62858836c1 | ||
|
|
cbb9254432 | ||
|
|
dc4f8e8590 |
87
.gitignore
vendored
@@ -1 +1,86 @@
|
||||
/AndorsTrail/.idea/workspace.xml
|
||||
### Android ###
|
||||
# Built application files
|
||||
*.apk
|
||||
*.ap_
|
||||
|
||||
# Files for the ART/Dalvik VM
|
||||
*.dex
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
|
||||
# Generated files
|
||||
bin/
|
||||
gen/
|
||||
out/
|
||||
|
||||
# Gradle files
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Proguard folder generated by Eclipse
|
||||
proguard/
|
||||
|
||||
# Log Files
|
||||
*.log
|
||||
|
||||
# Android Studio Navigation editor temp files
|
||||
.navigation/
|
||||
|
||||
# Android Studio captures folder
|
||||
captures/
|
||||
|
||||
# Built application files
|
||||
/*/build/
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
### Gradle ###
|
||||
.gradle
|
||||
/build/
|
||||
|
||||
# Ignore Gradle GUI config
|
||||
gradle-app.setting
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.jar
|
||||
|
||||
# Cache of project
|
||||
.gradletasknamecache
|
||||
|
||||
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
|
||||
# gradle/wrapper/gradle-wrapper.properties
|
||||
|
||||
# Signing files
|
||||
.signing/*.keystore
|
||||
!.signing/debug.keystore
|
||||
|
||||
# User-specific configurations
|
||||
.idea/libraries/
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/.name
|
||||
.idea/compiler.xml
|
||||
.idea/copyright/profiles_settings.xml
|
||||
.idea/encodings.xml
|
||||
.idea/misc.xml
|
||||
.idea/modules.xml
|
||||
.idea/scopes/scope_settings.xml
|
||||
.idea/caches/build_file_checksums.ser
|
||||
.idea/caches/gradle_models.ser
|
||||
.idea/vcs.xml
|
||||
.idea/assetWizardSettings.xml
|
||||
*.iml
|
||||
|
||||
# OS-specific files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
14
.idea/assetWizardSettings.xml
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="WizardSettings">
|
||||
<option name="children">
|
||||
<map>
|
||||
<entry key="imageWizard">
|
||||
<value>
|
||||
<PersistentState />
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
29
.idea/codeStyles/Project.xml
generated
Normal file
@@ -0,0 +1,29 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<Objective-C-extensions>
|
||||
<file>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||
</file>
|
||||
<class>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||
</class>
|
||||
<extensions>
|
||||
<pair source="cpp" header="h" fileNamingConvention="NONE" />
|
||||
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||
</extensions>
|
||||
</Objective-C-extensions>
|
||||
</code_scheme>
|
||||
</component>
|
||||
15
.idea/gradle.xml
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<compositeConfiguration>
|
||||
<compositeBuild compositeDefinitionSource="SCRIPT" />
|
||||
</compositeConfiguration>
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
12
.idea/runConfigurations.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
BIN
.signing/debug.keystore
Normal file
14
.travis.yml
@@ -1,14 +0,0 @@
|
||||
dist: bionic
|
||||
sudo: required
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/pbuilder-bases
|
||||
matrix:
|
||||
include:
|
||||
- env: TARGET_OS=stretch
|
||||
before_install:
|
||||
- "$TRAVIS_BUILD_DIR/travis/$TRAVIS_OS_NAME.$TARGET_OS.before_install"
|
||||
install:
|
||||
- "$TRAVIS_BUILD_DIR/travis/$TRAVIS_OS_NAME.$TARGET_OS.install"
|
||||
script:
|
||||
- "$TRAVIS_BUILD_DIR/travis/$TRAVIS_OS_NAME.$TARGET_OS.script"
|
||||
55
AndorsTrail/.gitignore
vendored
@@ -1,55 +0,0 @@
|
||||
# Android ignores
|
||||
app/src/main/res
|
||||
app/src/main/assets
|
||||
gen/
|
||||
bin/
|
||||
target/
|
||||
local.properties
|
||||
app/build/intermediates/
|
||||
build/
|
||||
debug/
|
||||
release/
|
||||
.gradle/
|
||||
|
||||
#IntelliJ
|
||||
.idea/
|
||||
out/production/
|
||||
out/test/
|
||||
*.iws
|
||||
*.ipr
|
||||
|
||||
# Other
|
||||
.metadata
|
||||
.svn/
|
||||
|
||||
|
||||
#copied from https://github.com/github/gitignore/blob/main/Gradle.gitignore
|
||||
.gradle
|
||||
**/build/
|
||||
!src/**/build/
|
||||
|
||||
# Ignore Gradle GUI config
|
||||
gradle-app.setting
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.jar
|
||||
|
||||
# Avoid ignore Gradle wrappper properties
|
||||
!gradle-wrapper.properties
|
||||
|
||||
# Cache of project
|
||||
.gradletasknamecache
|
||||
|
||||
# Eclipse Gradle plugin generated files
|
||||
# Eclipse Core
|
||||
.project
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
#copied from https://github.com/github/gitignore/blob/main/Gradle.gitignore
|
||||
|
||||
|
||||
/AndorsTrail/.gradle
|
||||
/AndorsTrail/gradle/wrapper
|
||||
/AndorsTrail/app/build/
|
||||
/AndorsTrail/app/debug/
|
||||
/AndorsTrail/app/release/
|
||||
@@ -1,52 +0,0 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 31
|
||||
buildToolsVersion "30.0.3"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.gpl.rpg.AndorsTrail"
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 31
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
manifestPlaceholders icon_name: 'icon', fileproviderPath: 'AndorsTrail'
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||
}
|
||||
debug {
|
||||
manifestPlaceholders icon_name: 'icon_beta', fileproviderPath: 'AndorsTrail.beta2'
|
||||
applicationIdSuffix 'beta2'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.android.support:support-v4:28.0.0'
|
||||
}
|
||||
|
||||
task copyRes(type: Copy) {
|
||||
description "Copies the res folder to the modules res folder (& renames .tmx to .xml)"
|
||||
from "${rootDir}/res"
|
||||
into "${projectDir}/src/main/res"
|
||||
rename "(.*)\\.tmx", "\$1.xml"
|
||||
}
|
||||
|
||||
task copyTranslation(type: Copy) {
|
||||
description("Copies the translation files to the modules translations folder")
|
||||
from "${rootDir}/assets/translation"
|
||||
into "${projectDir}/src/main/assets/translation"
|
||||
}
|
||||
|
||||
task cleanup(type: Delete) {
|
||||
description("Deletes the assets/translation and the res folder from the modules folder")
|
||||
delete "${projectDir}/src/main/res", "${projectDir}/src/main/assets/translation"
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
preBuild.dependsOn project.tasks.copyRes
|
||||
preBuild.dependsOn project.tasks.copyTranslation
|
||||
clean.dependsOn project.tasks.cleanup
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.gpl.rpg.AndorsTrail"
|
||||
android:versionCode="72"
|
||||
android:versionName="0.8.6.1"
|
||||
android:installLocation="auto"
|
||||
>
|
||||
|
||||
<supports-screens
|
||||
android:smallScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:largeScreens="true"
|
||||
android:xlargeScreens="true"
|
||||
android:anyDensity="true"
|
||||
/>
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
|
||||
<application
|
||||
android:name="com.gpl.rpg.AndorsTrail.AndorsTrailApplication"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@drawable/${icon_name}"
|
||||
android:description="@string/app_description"
|
||||
android:allowBackup="true"
|
||||
android:theme="@style/AndorsTrailTheme_Blue"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:hasFragileUserData="true"
|
||||
android:preserveLegacyExternalStorage="true"
|
||||
>
|
||||
<activity
|
||||
android:name="com.gpl.rpg.AndorsTrail.activity.StartScreenActivity"
|
||||
android:exported="true"
|
||||
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="com.gpl.rpg.AndorsTrail.activity.MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AndorsTrailTheme_Blue.NoBackground"
|
||||
/>
|
||||
<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"
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/fileprovider" />
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.activity;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
|
||||
public abstract class AndorsTrailBaseActivity extends Activity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
|
||||
app.setLocale(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
|
||||
app.setLocale(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.activity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
|
||||
public abstract class AndorsTrailBaseFragmentActivity extends FragmentActivity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
|
||||
app.setLocale(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
|
||||
app.setLocale(this);
|
||||
}
|
||||
}
|
||||
@@ -1,341 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.activity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.controller.Constants;
|
||||
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.MapObject;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
|
||||
import com.gpl.rpg.AndorsTrail.view.MainView;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
public final class DebugInterface {
|
||||
private final ControllerContext controllerContext;
|
||||
private final MainActivity mainActivity;
|
||||
private final Resources res;
|
||||
private final WorldContext world;
|
||||
|
||||
private DebugButton[] buttons;
|
||||
private List<DebugButton> tpButtons = new ArrayList<DebugButton>();
|
||||
private List<DebugButton> tpButtons2 = new ArrayList<DebugButton>();
|
||||
|
||||
public DebugInterface(ControllerContext controllers, WorldContext world, MainActivity mainActivity) {
|
||||
this.controllerContext = controllers;
|
||||
this.world = world;
|
||||
this.res = mainActivity.getResources();
|
||||
this.mainActivity = mainActivity;
|
||||
}
|
||||
|
||||
public void addDebugButtons() {
|
||||
if (!AndorsTrailApplication.DEVELOPMENT_DEBUGBUTTONS) return;
|
||||
|
||||
List<DebugButton> buttonList = new ArrayList<DebugButton>();
|
||||
buttonList.addAll(Arrays.asList(new DebugButton[] {
|
||||
new DebugButton("dbg", new OnClickListener() {
|
||||
boolean hidden = false;
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
hidden = !hidden;
|
||||
for (int i = 1; i < buttons.length; i++) {
|
||||
buttons[i].b.setVisibility(hidden ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
for (DebugButton b : tpButtons) {
|
||||
b.b.setVisibility(View.GONE);
|
||||
}
|
||||
for (DebugButton b : tpButtons2) {
|
||||
b.b.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
})
|
||||
,new DebugButton("teleport", new OnClickListener() {
|
||||
public void onClick(View arg0) {
|
||||
for (int i = 0; i < buttons.length; i++) {
|
||||
buttons[i].b.setVisibility(View.GONE);
|
||||
}
|
||||
for (DebugButton tpButton : tpButtons) {
|
||||
tpButton.b.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
})
|
||||
,new DebugButton("dmg", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
world.model.player.damagePotential.set(500, 500);
|
||||
world.model.player.attackChance = 500;
|
||||
world.model.player.attackCost = 1;
|
||||
showToast(mainActivity, "DEBUG: damagePotential=500, chance=500%, cost=1", Toast.LENGTH_SHORT);
|
||||
}
|
||||
})
|
||||
/*,new DebugButton("dmg=1", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
world.model.player.damagePotential.set(1, 1);
|
||||
showToast(mainActivity, "DEBUG: damagePotential=1", Toast.LENGTH_SHORT);
|
||||
}
|
||||
})*/
|
||||
,new DebugButton("itm", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
for (ItemType item : world.itemTypes.UNITTEST_getAllItemTypes().values()) {
|
||||
world.model.player.inventory.addItem(item, 10);
|
||||
}
|
||||
world.model.player.inventory.gold += 50000;
|
||||
showToast(mainActivity, "DEBUG: added items", Toast.LENGTH_SHORT);
|
||||
}
|
||||
})
|
||||
,new DebugButton("xp", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.actorStatsController.addExperience(10000);
|
||||
showToast(mainActivity, "DEBUG: given 10000 exp", Toast.LENGTH_SHORT);
|
||||
}
|
||||
})
|
||||
,new DebugButton("rst", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
for(PredefinedMap map : world.maps.getAllMaps()) {
|
||||
map.resetTemporaryData();
|
||||
}
|
||||
showToast(mainActivity, "DEBUG: maps respawned", Toast.LENGTH_SHORT);
|
||||
}
|
||||
})
|
||||
,new DebugButton("hp", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
world.model.player.baseTraits.maxHP = 500;
|
||||
world.model.player.health.max = world.model.player.baseTraits.maxHP;
|
||||
controllerContext.actorStatsController.setActorMaxHealth(world.model.player);
|
||||
world.model.player.conditions.clear();
|
||||
showToast(mainActivity, "DEBUG: hp set to max", Toast.LENGTH_SHORT);
|
||||
}
|
||||
})
|
||||
,new DebugButton("skl", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
world.model.player.availableSkillIncreases += 10;
|
||||
showToast(mainActivity, "DEBUG: 10 skill points", Toast.LENGTH_SHORT);
|
||||
}
|
||||
})
|
||||
,new DebugButton("spd", new OnClickListener() {
|
||||
boolean fast = Constants.MINIMUM_INPUT_INTERVAL == Constants.MINIMUM_INPUT_INTERVAL_FAST;
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
fast = !fast;
|
||||
if (fast) {
|
||||
Constants.MINIMUM_INPUT_INTERVAL = Constants.MINIMUM_INPUT_INTERVAL_FAST;
|
||||
} else {
|
||||
Constants.MINIMUM_INPUT_INTERVAL = Constants.MINIMUM_INPUT_INTERVAL_STD;
|
||||
}
|
||||
MainView.SCROLL_DURATION = Constants.MINIMUM_INPUT_INTERVAL;
|
||||
AndorsTrailApplication.getApplicationFromActivity(mainActivity).getControllerContext().movementController.resetMovementHandler();
|
||||
}
|
||||
})
|
||||
,new DebugButton("map", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
showToast(mainActivity, "DEBUG: map=" + world.model.currentMaps.map.name , Toast.LENGTH_SHORT);
|
||||
}
|
||||
})
|
||||
}));
|
||||
|
||||
tpButtons.addAll(Arrays.asList(new DebugButton[] {
|
||||
new DebugButton("teleport", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
for (DebugButton tpButton : tpButtons2) {
|
||||
tpButton.b.setVisibility(View.VISIBLE);
|
||||
}
|
||||
for (DebugButton tpButton : tpButtons) {
|
||||
tpButton.b.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
})
|
||||
,new DebugButton("cg", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "crossglen", "hall", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("vg", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "vilegard_s", "tavern", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("cr", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "houseatcrossroads4", "down", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("lf", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "loneford9", "south", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("fh", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "fallhaven_ne", "clothes", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("prm", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "blackwater_mountain29", "south", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("bwm", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "blackwater_mountain43", "south", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("rmg", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "remgard0", "east", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("chr", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "waytolostmine2", "minerhouse4", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("ldr", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "lodarhouse0", "lodarhouse", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("sf", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "wild20", "south2", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("gm", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "guynmart_wood_1", "farmhouse", 0, 0);
|
||||
}
|
||||
})
|
||||
}));
|
||||
buttonList.addAll(tpButtons);
|
||||
|
||||
tpButtons2.addAll(Arrays.asList(new DebugButton[] {
|
||||
new DebugButton("teleport", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
for (int i = 0; i < buttons.length; i++) {
|
||||
buttons[i].b.setVisibility(View.VISIBLE);
|
||||
}
|
||||
for (DebugButton tpButton : tpButtons) {
|
||||
tpButton.b.setVisibility(View.GONE);
|
||||
}
|
||||
for (DebugButton tpButton : tpButtons2) {
|
||||
tpButton.b.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
})
|
||||
,new DebugButton("brv", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "brimhaven4", "south2", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("aru", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "mountainlake5", "north", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("ws", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "woodsettlement0", "east", 0, 0);
|
||||
}
|
||||
})
|
||||
,new DebugButton("sul", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "sullengard2", "south", 0, 0);
|
||||
}
|
||||
})
|
||||
}));
|
||||
buttonList.addAll(tpButtons2);
|
||||
|
||||
buttons = buttonList.toArray(new DebugButton[buttonList.size()]);
|
||||
addDebugButtons(buttons);
|
||||
|
||||
for (DebugButton b : tpButtons) {
|
||||
b.b.setVisibility(View.GONE);
|
||||
}
|
||||
for (DebugButton b : tpButtons2) {
|
||||
b.b.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void showToast(Context context, String msg, int duration) {
|
||||
Toast.makeText(context, msg, duration).show();
|
||||
}
|
||||
|
||||
private static class DebugButton {
|
||||
public final String text;
|
||||
public final OnClickListener listener;
|
||||
public Button b = null;
|
||||
public DebugButton(String text, OnClickListener listener) {
|
||||
this.text = text;
|
||||
this.listener = listener;
|
||||
}
|
||||
public void makeButton(Context c, int id) {
|
||||
b = new Button(c);
|
||||
b.setText(text);
|
||||
b.setTextSize(10);//res.getDimension(R.dimen.actionbar_text));
|
||||
b.setId(id);
|
||||
b.setOnClickListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
private void addDebugButton(DebugButton button, int id, RelativeLayout layout) {
|
||||
if (!AndorsTrailApplication.DEVELOPMENT_DEBUGBUTTONS) return;
|
||||
|
||||
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, res.getDimensionPixelSize(R.dimen.smalltext_buttonheight));
|
||||
if (id == 1)
|
||||
lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
|
||||
else
|
||||
lp.addRule(RelativeLayout.RIGHT_OF, id - 1);
|
||||
lp.addRule(RelativeLayout.ABOVE, R.id.main_statusview);
|
||||
button.makeButton(mainActivity, id);
|
||||
button.b.setLayoutParams(lp);
|
||||
layout.addView(button.b);
|
||||
}
|
||||
|
||||
private void addDebugButtons(DebugButton[] buttons) {
|
||||
if (!AndorsTrailApplication.DEVELOPMENT_DEBUGBUTTONS) return;
|
||||
|
||||
if (buttons == null || buttons.length <= 0) return;
|
||||
RelativeLayout layout = (RelativeLayout) mainActivity.findViewById(R.id.main_container);
|
||||
|
||||
int id = 1;
|
||||
for (DebugButton b : buttons) {
|
||||
addDebugButton(b, id, layout);
|
||||
++id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,876 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.activity;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
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;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
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;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
|
||||
|
||||
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 exportImportContainer = (ViewGroup) findViewById(R.id.loadsave_export_import_save_container);
|
||||
|
||||
|
||||
addSavegameSlotButtons(slotList, params, Savegames.getUsedSavegameSlots(this));
|
||||
|
||||
checkAndRequestPermissions();
|
||||
|
||||
if (!isLoading) {
|
||||
createNewSlot.setTag(SLOT_NUMBER_CREATE_NEW_SLOT);
|
||||
createNewSlot.setOnClickListener(this);
|
||||
newSlotContainer.setVisibility(View.VISIBLE);
|
||||
exportImportContainer.setVisibility(View.GONE);
|
||||
} else {
|
||||
newSlotContainer.setVisibility(View.GONE);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
exportSaves.setOnClickListener(this);
|
||||
importSaves.setOnClickListener(this);
|
||||
importWorldmap.setOnClickListener(this);
|
||||
exportImportContainer.setVisibility(View.VISIBLE);
|
||||
|
||||
boolean hasSavegames = !Savegames.getUsedSavegameSlots(this).isEmpty();
|
||||
exportSaves.setEnabled(hasSavegames);
|
||||
} else {
|
||||
exportImportContainer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final int READ_EXTERNAL_STORAGE_REQUEST = 1;
|
||||
private static final int WRITE_EXTERNAL_STORAGE_REQUEST = 2;
|
||||
|
||||
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 cancelLoadSaveActivity(int slot) {
|
||||
completeLoadSaveActivity(slot, false);
|
||||
}
|
||||
|
||||
private void completeLoadSaveActivity(int slot) {
|
||||
completeLoadSaveActivity(slot, true);
|
||||
}
|
||||
|
||||
private void completeLoadSaveActivity(int slot, boolean success) {
|
||||
Intent i = new Intent();
|
||||
if (slot == SLOT_NUMBER_CREATE_NEW_SLOT) {
|
||||
slot = getFirstFreeSlot();
|
||||
} else if (slot == SLOT_NUMBER_EXPORT_SAVEGAMES
|
||||
|| slot == SLOT_NUMBER_IMPORT_SAVEGAMES
|
||||
|| slot == SLOT_NUMBER_IMPORT_WORLDMAP) {
|
||||
i.putExtra("import_export", true);
|
||||
|
||||
if (slot == SLOT_NUMBER_IMPORT_WORLDMAP) {
|
||||
i.putExtra("import_worldmap", true);
|
||||
}
|
||||
if (slot == SLOT_NUMBER_IMPORT_SAVEGAMES) {
|
||||
i.putExtra("import_savegames", true);
|
||||
}
|
||||
if (slot == SLOT_NUMBER_EXPORT_SAVEGAMES) {
|
||||
i.putExtra("export", true);
|
||||
}
|
||||
|
||||
} else if (slot < SLOT_NUMBER_FIRST_SLOT) {
|
||||
slot = SLOT_NUMBER_FIRST_SLOT;
|
||||
}
|
||||
|
||||
i.putExtra("slot", slot);
|
||||
if (success) {
|
||||
setResult(Activity.RESULT_OK, i);
|
||||
} else {
|
||||
setResult(Activity.RESULT_CANCELED, i);
|
||||
}
|
||||
LoadSaveActivity.this.finish();
|
||||
}
|
||||
|
||||
private int getFirstFreeSlot() {
|
||||
int slot;
|
||||
List<Integer> usedSlots = Savegames.getUsedSavegameSlots(this);
|
||||
if (usedSlots.isEmpty()) {
|
||||
slot = SLOT_NUMBER_FIRST_SLOT;
|
||||
} else {
|
||||
slot = Collections.max(usedSlots) + 1;
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
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.P) {
|
||||
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 CustomDialog 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
|
||||
|
||||
//region Export
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
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 target = DocumentFile.fromTreeUri(context, uri);
|
||||
if (target == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
File[] files = storageDir.listFiles();
|
||||
if (files == null) {
|
||||
showErrorExportingSaveGamesUnknown();
|
||||
return;
|
||||
}
|
||||
|
||||
boolean hasExistingFiles = false;
|
||||
for (File file : files) {
|
||||
String fileName = file.getName();
|
||||
|
||||
DocumentFile existingFile = target.findFile(fileName);
|
||||
if (existingFile != null) {
|
||||
hasExistingFiles = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasExistingFiles) {
|
||||
showConfirmOverwriteByExportQuestion(resolver, target, files);
|
||||
} else {
|
||||
exportSaveGamesFolderContentToFolder(target, files);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
private void exportSaveGamesFolderContentToFolder(DocumentFile target, File[] files) {
|
||||
DocumentFile[] sourceFiles = new DocumentFile[files.length];
|
||||
|
||||
File[] worldmapFiles = null;
|
||||
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File file = files[i];
|
||||
if (file.isFile()) {
|
||||
sourceFiles[i] = DocumentFile.fromFile(file);
|
||||
} else if (file.isDirectory() && Objects.equals(file.getName(),
|
||||
Constants.FILENAME_WORLDMAP_DIRECTORY)) {
|
||||
worldmapFiles = file.listFiles();
|
||||
}
|
||||
}
|
||||
Context context = this;
|
||||
File[] finalWorldmapFiles = worldmapFiles;
|
||||
CopyFilesToExternalFolder(target, sourceFiles, context, finalWorldmapFiles);
|
||||
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
private void CopyFilesToExternalFolder(DocumentFile target,
|
||||
DocumentFile[] sourceFiles,
|
||||
Context context,
|
||||
File[] finalWorldmapFiles) {
|
||||
AndroidStorage.copyDocumentFilesToDirAsync(sourceFiles,
|
||||
context,
|
||||
target,
|
||||
getString(R.string.loadsave_exporting_savegames),
|
||||
(success) -> {
|
||||
if (success) {
|
||||
CopyWorldmapFilesAsZip(target,
|
||||
context,
|
||||
finalWorldmapFiles);
|
||||
} else {
|
||||
completeLoadSaveActivity(
|
||||
SLOT_NUMBER_EXPORT_SAVEGAMES,
|
||||
false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
private void CopyWorldmapFilesAsZip(DocumentFile target,
|
||||
Context context,
|
||||
File[] finalWorldmapFiles) {
|
||||
AndroidStorage.createZipDocumentFileFromFilesAsync(finalWorldmapFiles,
|
||||
context,
|
||||
target,
|
||||
Constants.FILENAME_WORLDMAP_DIRECTORY,
|
||||
getString(R.string.loadsave_exporting_worldmap),
|
||||
(successWorldmap) -> completeLoadSaveActivity(
|
||||
SLOT_NUMBER_EXPORT_SAVEGAMES,
|
||||
successWorldmap));
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
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 = AndorsTrailApplication.getApplicationFromActivity(this)
|
||||
.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);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
private void importSaveGames(ContentResolver resolver,
|
||||
DocumentFile appSavegameFolder,
|
||||
List<DocumentFile> saveFiles) {
|
||||
int size = saveFiles.size();
|
||||
DocumentFile[] sources = new DocumentFile[size];
|
||||
DocumentFile[] targets = new DocumentFile[size];
|
||||
|
||||
boolean saveAsNew = false;
|
||||
for (int i = 0; i < size; i++) {
|
||||
DocumentFile file = saveFiles.get(i);
|
||||
if (file == null) {//null is value a marker that the next should be saved as new
|
||||
saveAsNew = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
int slot = getSlotFromSavegameFileName(file.getName());
|
||||
if (slot == -1) {
|
||||
//invalid file name
|
||||
continue;
|
||||
}
|
||||
|
||||
if (saveAsNew) {
|
||||
slot = getFirstFreeSlot();
|
||||
saveAsNew = false;
|
||||
}
|
||||
|
||||
String targetName = Savegames.getSlotFileName(slot);
|
||||
sources[i] = file;
|
||||
targets[i] = getOrCreateDocumentFile(appSavegameFolder, targetName);
|
||||
}
|
||||
|
||||
AndroidStorage.copyDocumentFilesFromToAsync(sources,
|
||||
this,
|
||||
targets,
|
||||
getString(R.string.loadsave_importing_savegames),
|
||||
(sucess) -> completeLoadSaveActivity(
|
||||
SLOT_NUMBER_IMPORT_SAVEGAMES,
|
||||
sucess));
|
||||
}
|
||||
|
||||
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)) {
|
||||
return -1;
|
||||
}
|
||||
String slotStr = fileName.substring(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX.length());
|
||||
|
||||
int slot;
|
||||
try {
|
||||
slot = Integer.parseInt(slotStr);
|
||||
return slot;
|
||||
} catch (NumberFormatException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
private void importWorldmap(Intent data) {
|
||||
Uri uri = data.getData();
|
||||
|
||||
Context context = AndorsTrailApplication.getApplicationFromActivity(this).getApplicationContext();
|
||||
|
||||
DocumentFile chosenZip = DocumentFile.fromSingleUri(context, uri);
|
||||
if (chosenZip == null || !chosenZip.isFile()) {
|
||||
showErrorImportingWorldmapWrongDirectory();
|
||||
return;
|
||||
}
|
||||
String chosenZipName = chosenZip.getName();
|
||||
if (!chosenZipName.startsWith(Constants.FILENAME_WORLDMAP_DIRECTORY)) {
|
||||
showErrorImportingWorldmapWrongDirectory();
|
||||
return;
|
||||
}
|
||||
|
||||
File ownWorldmapFolder = getOwnWorldmapFolder(context);
|
||||
|
||||
|
||||
AndroidStorage.unzipDocumentFileToDirectoryAsync(chosenZip,
|
||||
this,
|
||||
ownWorldmapFolder,
|
||||
false,
|
||||
getString(R.string.loadsave_importing_worldmap),
|
||||
(success) -> completeLoadSaveActivity(
|
||||
SLOT_NUMBER_IMPORT_WORLDMAP,
|
||||
success));
|
||||
}
|
||||
|
||||
private File getOwnWorldmapFolder(Context context) {
|
||||
File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
File ownWorldmapFolder = null;
|
||||
for (File f : storageDir.listFiles()) {
|
||||
if (f.getName().equals(Constants.FILENAME_WORLDMAP_DIRECTORY)) {
|
||||
ownWorldmapFolder = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ownWorldmapFolder == null) {
|
||||
ownWorldmapFolder = new File(storageDir, Constants.FILENAME_WORLDMAP_DIRECTORY);
|
||||
ownWorldmapFolder.mkdir();
|
||||
}
|
||||
return ownWorldmapFolder;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
private void clickExportSaveGames() {
|
||||
showStartExportInfo(view -> startActivityForResult(AndroidStorage.getNewOpenDirectoryIntent(),
|
||||
-SLOT_NUMBER_EXPORT_SAVEGAMES));
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
private void clickImportSaveGames() {
|
||||
showStartImportSavesInfo(view -> startActivityForResult(AndroidStorage.getNewSelectMultipleSavegameFilesIntent(),
|
||||
-SLOT_NUMBER_IMPORT_SAVEGAMES));
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
private void clickImportWorldmap() {
|
||||
showStartImportWorldmapInfo(view -> startActivityForResult(AndroidStorage.getNewSelectZipIntent(),
|
||||
-SLOT_NUMBER_IMPORT_WORLDMAP));
|
||||
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
private void showConfirmOverwriteByExportQuestion(ContentResolver resolver,
|
||||
DocumentFile targetFolder,
|
||||
File[] files) {
|
||||
final CustomDialog 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(targetFolder, files));
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.no);
|
||||
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
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_file_exists_question);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('\n');
|
||||
int amount = alreadyExistingFiles.size();
|
||||
|
||||
Context context = AndorsTrailApplication.getApplicationFromActivity(this).getApplicationContext();
|
||||
|
||||
ArrayList<CustomDialog> dialogs = new ArrayList<>(amount);
|
||||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
DocumentFile alreadyExistingFile = alreadyExistingFiles.get(i);
|
||||
int slot = getSlotFromSavegameFileName(alreadyExistingFile.getName());
|
||||
FileHeader existingFileHeader = Savegames.quickload(context, slot);
|
||||
FileHeader importedFileHeader = null;
|
||||
try (InputStream stream = resolver.openInputStream(alreadyExistingFile.getUri());
|
||||
DataInputStream dataStream = new DataInputStream(stream)) {
|
||||
importedFileHeader = new FileHeader(dataStream, true);
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
|
||||
StringBuilder messageSb = new StringBuilder();
|
||||
String existingFileDescription = getString(R.string.loadsave_import_existing_description,
|
||||
Integer.toString(slot),
|
||||
existingFileHeader.describe());
|
||||
String importedFileDescription = getString(R.string.loadsave_import_imported_description,
|
||||
Integer.toString(slot),
|
||||
importedFileHeader.describe());
|
||||
messageSb.append(getString(R.string.loadsave_import_file_exists_question,
|
||||
existingFileDescription,
|
||||
importedFileDescription));
|
||||
|
||||
|
||||
String m = messageSb.toString();
|
||||
CustomDialog dialog = CustomDialogFactory.createDialog(this,
|
||||
title,
|
||||
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||
m,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
true);
|
||||
|
||||
CustomDialogFactory.addButton(dialog, R.string.loadsave_import_option_keep_existing, v -> {
|
||||
//do nothing
|
||||
GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs);
|
||||
});
|
||||
|
||||
CustomDialogFactory.addButton(dialog, R.string.loadsave_import_option_keep_imported, v -> {
|
||||
newFiles.add(alreadyExistingFile);
|
||||
GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs);
|
||||
});
|
||||
|
||||
CustomDialogFactory.addButton(dialog, R.string.loadsave_import_option_add_as_new, v -> {
|
||||
newFiles.add(null);//add a null element as marker to know later if the next file
|
||||
// should be imported as new or overwrite the existing one
|
||||
newFiles.add(alreadyExistingFile);
|
||||
GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs);
|
||||
});
|
||||
|
||||
CustomDialogFactory.addCancelButton(dialog, android.R.string.cancel);
|
||||
CustomDialogFactory.setCancelListener(dialog, v -> {
|
||||
completeLoadSaveActivity(SLOT_NUMBER_IMPORT_SAVEGAMES, false);
|
||||
});
|
||||
|
||||
dialogs.add(dialog);
|
||||
}
|
||||
|
||||
GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
private void GoToNextConflictOrFinish(ContentResolver resolver,
|
||||
DocumentFile appSavegameFolder,
|
||||
List<DocumentFile> newFiles,
|
||||
ArrayList<CustomDialog> dialogs) {
|
||||
if (dialogs.stream().count() > 0) {
|
||||
CustomDialog d = dialogs.remove(0);
|
||||
CustomDialogFactory.show(d);
|
||||
} else {
|
||||
importSaveGames(resolver, appSavegameFolder, newFiles);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if (resultCode != Activity.RESULT_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
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
|
||||
|
||||
//region Import/Export
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
private void showStartExportInfo(OnClickListener onOk) {
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(this,
|
||||
getString(R.string.loadsave_export),
|
||||
getResources().getDrawable(android.R.drawable.ic_dialog_info),
|
||||
getString(R.string.loadsave_export_info),
|
||||
null,
|
||||
true);
|
||||
CustomDialogFactory.addButton(d, android.R.string.yes, onOk);
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.no);
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
private void showStartImportSavesInfo(OnClickListener onOk) {
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(this,
|
||||
getString(R.string.loadsave_import_save),
|
||||
getResources().getDrawable(android.R.drawable.ic_dialog_info),
|
||||
getString(R.string.loadsave_import_save_info),
|
||||
null,
|
||||
true);
|
||||
CustomDialogFactory.addButton(d, android.R.string.yes, onOk);
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.no);
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
private void showStartImportWorldmapInfo(OnClickListener onOk) {
|
||||
final CustomDialog d = CustomDialogFactory.createDialog(this,
|
||||
getString(R.string.loadsave_import_worldmap),
|
||||
getResources().getDrawable(android.R.drawable.ic_dialog_info),
|
||||
getString(R.string.loadsave_import_worldmap_info),
|
||||
null,
|
||||
true);
|
||||
CustomDialogFactory.addButton(d, android.R.string.yes, onOk);
|
||||
CustomDialogFactory.addDismissButton(d, android.R.string.no);
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
private void showErrorImportingWorldmapWrongDirectory() {
|
||||
final CustomDialog d = CustomDialogFactory.createErrorDialog(this,
|
||||
getString(R.string.loadsave_import_worldmap_unsuccessfull),
|
||||
getString(R.string.loadsave_import_worldmap_wrong_file));
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
private void showErrorExportingSaveGamesUnknown() {
|
||||
final CustomDialog d = CustomDialogFactory.createErrorDialog(this,
|
||||
getString(R.string.loadsave_export_unsuccessfull),
|
||||
getString(R.string.loadsave_export_error_unknown));
|
||||
CustomDialogFactory.show(d);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
private void showErrorLoadingEmptySlot() {
|
||||
final CustomDialog 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 CustomDialog 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 CustomDialog 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
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.activity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
|
||||
|
||||
public final class Preferences extends PreferenceActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(ThemeHelper.getBaseTheme());
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
super.onCreate(savedInstanceState);
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
|
||||
if (app.getPreferences().fullscreen) {
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
} else {
|
||||
getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
}
|
||||
|
||||
app.setLocale(this);
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
|
||||
app.setLocale(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.activity.fragment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.SimpleExpandableListAdapter;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Player;
|
||||
import com.gpl.rpg.AndorsTrail.model.quest.Quest;
|
||||
import com.gpl.rpg.AndorsTrail.model.quest.QuestLogEntry;
|
||||
import com.gpl.rpg.AndorsTrail.view.SpinnerEmulator;
|
||||
|
||||
public final class HeroinfoActivity_Quests extends Fragment {
|
||||
|
||||
private WorldContext world;
|
||||
|
||||
// private Button includeCompletedButton;
|
||||
// private Dialog includeCompletedDialog = null;
|
||||
// private ListView questlog_includecompleted;
|
||||
|
||||
private SimpleExpandableListAdapter questlog_contents_adapter;
|
||||
|
||||
private Player player;
|
||||
|
||||
private final List<Map<String, ?>> groupList = new ArrayList<Map<String, ?>>();
|
||||
private final List<List<Map<String, ?>>> childList = new ArrayList<List<Map<String,?>>>();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
final AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this.getActivity());
|
||||
if (!app.isInitialized()) return;
|
||||
this.world = app.getWorld();
|
||||
this.player = world.model.player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.questlog, container, false);
|
||||
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this.getActivity());
|
||||
if (!app.isInitialized()) return v;
|
||||
|
||||
Context ctx = getActivity();
|
||||
|
||||
|
||||
new SpinnerEmulator(v, R.id.questlog_includecompleted_button, R.array.questlog_includecompleted, R.string.questlog_includecompleted_prompt) {
|
||||
@Override
|
||||
public void setValue(int value) {
|
||||
world.model.uiSelections.selectedQuestFilter = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectionChanged(int value) {
|
||||
reloadQuests();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getValue() {
|
||||
return world.model.uiSelections.selectedQuestFilter;
|
||||
}
|
||||
};
|
||||
|
||||
ExpandableListView questlog_contents = (ExpandableListView) v.findViewById(R.id.questlog_contents);
|
||||
questlog_contents_adapter = new SimpleExpandableListAdapter(
|
||||
ctx
|
||||
, groupList
|
||||
, android.R.layout.simple_expandable_list_item_2
|
||||
, new String[] { mn_questName, mn_questStatus }
|
||||
, new int[] { android.R.id.text1, android.R.id.text2 }
|
||||
, childList
|
||||
, R.layout.questlogentry
|
||||
, new String[] { mn_logText }
|
||||
, new int[] { R.id.questlog_entrytext }
|
||||
);
|
||||
questlog_contents.setAdapter(questlog_contents_adapter);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
private static final String mn_questName = "questName";
|
||||
private static final String mn_questStatus = "questStatus";
|
||||
private static final String mn_logText = "logText";
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
update();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
reloadQuests();
|
||||
}
|
||||
|
||||
private void reloadQuests() {
|
||||
groupList.clear();
|
||||
childList.clear();
|
||||
|
||||
for (String questProgressID : player.getAllQuestProgressIDs()) {
|
||||
Quest q = world.quests.getQuest(questProgressID);
|
||||
if (q == null) continue; // This should not happen
|
||||
if (!q.showInLog) continue; // Do not show
|
||||
boolean isCompleted = q.isCompleted(player);
|
||||
|
||||
int v = world.model.uiSelections.selectedQuestFilter;
|
||||
if (v == 0) { // Active quests
|
||||
if (isCompleted) continue;
|
||||
} else if (v == 1) { // All quests
|
||||
// Always show.
|
||||
} else if (v == 2) { // Completed quests
|
||||
if (!isCompleted) continue;
|
||||
}
|
||||
|
||||
int statusResId;
|
||||
if (isCompleted) {
|
||||
statusResId = R.string.questlog_queststatus_completed;
|
||||
} else {
|
||||
statusResId = R.string.questlog_queststatus_inprogress;
|
||||
}
|
||||
|
||||
Map<String, Object> item = new HashMap<String, Object>();
|
||||
item.put(mn_questName, q.name);
|
||||
item.put(mn_questStatus, getString(R.string.questlog_queststatus, getString(statusResId)));
|
||||
groupList.add(item);
|
||||
|
||||
List<Map<String, ?>> logItemList = new ArrayList<Map<String, ?>>();
|
||||
for(Integer progress : player.getQuestProgress(q.questID)) {
|
||||
for(QuestLogEntry e : q.stages) {
|
||||
if (e.progress == progress.intValue()) {
|
||||
if (e.logtext.length() > 0) {
|
||||
item = new HashMap<String, Object>();
|
||||
item.put(mn_logText, e.logtext);
|
||||
logItemList.add(item);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
childList.add(logItemList);
|
||||
}
|
||||
questlog_contents_adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
@@ -1,416 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.activity.fragment;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences;
|
||||
import com.gpl.rpg.AndorsTrail.Dialogs;
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.WorldSetup;
|
||||
import com.gpl.rpg.AndorsTrail.activity.AboutActivity;
|
||||
import com.gpl.rpg.AndorsTrail.activity.LoadingActivity;
|
||||
import com.gpl.rpg.AndorsTrail.activity.Preferences;
|
||||
import com.gpl.rpg.AndorsTrail.controller.Constants;
|
||||
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.L;
|
||||
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
|
||||
|
||||
public class StartScreenActivity_MainMenu extends Fragment {
|
||||
|
||||
private static final int INTENTREQUEST_PREFERENCES = 7;
|
||||
public static final int INTENTREQUEST_LOADGAME = 9;
|
||||
|
||||
private boolean hasExistingGame = false;
|
||||
private Button startscreen_continue;
|
||||
private Button startscreen_newgame;
|
||||
private Button startscreen_load;
|
||||
private ViewGroup save_preview_holder;
|
||||
private ImageView save_preview_hero_icon;
|
||||
private TextView save_preview_hero_desc;
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
updatePreferences(false);
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
|
||||
if (container != null) {
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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));
|
||||
}
|
||||
});
|
||||
|
||||
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 CustomDialog 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);
|
||||
|
||||
} else {
|
||||
Dialogs.showLoad(StartScreenActivity_MainMenu.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
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());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@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 CustomDialog 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);
|
||||
CustomDialogFactory.show(d);
|
||||
if (!AndroidStorage.migrateToInternalStorage(activity.getApplicationContext())) {
|
||||
final CustomDialog 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() {
|
||||
// new AlertDialog.Builder(new ContextThemeWrapper(getActivity(), R.style.AndorsTrailStyle_Dialog))
|
||||
// .setTitle(R.string.startscreen_newgame)
|
||||
// .setMessage(R.string.startscreen_newgame_confirm)
|
||||
// .setIcon(android.R.drawable.ic_delete)
|
||||
// .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(DialogInterface dialog, int which) {
|
||||
// //continueGame(true);
|
||||
//// hasExistingGame = false;
|
||||
//// setButtonState(null, null, 0);
|
||||
// createNewGame();
|
||||
// }
|
||||
// })
|
||||
// .setNegativeButton(android.R.string.cancel, null)
|
||||
// .create().show();
|
||||
//
|
||||
//
|
||||
final CustomDialog 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);
|
||||
|
||||
}
|
||||
|
||||
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:
|
||||
boolean unsuccessful = resultCode != Activity.RESULT_OK;
|
||||
if(data == null) break;
|
||||
|
||||
final boolean wasImportOrExport = data.getBooleanExtra("import_export", false);
|
||||
if (wasImportOrExport) {
|
||||
String message = getImportExportMessage(!unsuccessful, data);
|
||||
Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
if (unsuccessful) break;
|
||||
final int slot = data.getIntExtra("slot", 1);
|
||||
continueGame(false, slot, null);
|
||||
break;
|
||||
case INTENTREQUEST_PREFERENCES:
|
||||
updatePreferences(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private String getImportExportMessage(boolean successful, Intent data) {
|
||||
String message = "";
|
||||
boolean isImportWorldmap = data.getBooleanExtra("import_worldmap", false);
|
||||
boolean isImportSaves = data.getBooleanExtra("import_savegames", false);
|
||||
boolean isExport = data.getBooleanExtra("export", false);
|
||||
|
||||
if(isImportWorldmap) {
|
||||
message = getString(successful ? R.string.loadsave_import_worldmap_successfull : R.string.loadsave_import_worldmap_unsuccessfull);
|
||||
} else if(isImportSaves) {
|
||||
message = getString(successful ? R.string.loadsave_import_save_successfull : R.string.loadsave_import_save_unsuccessfull);
|
||||
} else if(isExport) {
|
||||
message = getString(successful ? R.string.loadsave_export_successfull : R.string.loadsave_export_unsuccessfull);
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
private void updatePreferences(boolean alreadyStartedLoadingResources) {
|
||||
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(getActivity());
|
||||
AndorsTrailPreferences preferences = app.getPreferences();
|
||||
preferences.read(getActivity());
|
||||
if (app.setLocale(getActivity())) {
|
||||
if (alreadyStartedLoadingResources) {
|
||||
// Changing the locale after having loaded the game requires resources to
|
||||
// be re-loaded. Therefore, we just exit here.
|
||||
Toast.makeText(getActivity(), R.string.change_locale_requires_restart, Toast.LENGTH_LONG).show();
|
||||
doFinish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ThemeHelper.changeTheme(preferences.selectedTheme)) {
|
||||
// Changing the theme requires a restart to re-create all activities.
|
||||
Toast.makeText(getActivity(), R.string.change_theme_requires_restart, Toast.LENGTH_LONG).show();
|
||||
doFinish();
|
||||
return;
|
||||
}
|
||||
app.getWorld().tileManager.updatePreferences(preferences);
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private void doFinish() {
|
||||
//For Lollipop and above
|
||||
((AndorsTrailApplication) getActivity().getApplication()).discardWorld();
|
||||
getActivity().finish();
|
||||
}
|
||||
|
||||
|
||||
public interface OnNewGameRequestedListener {
|
||||
public void onNewGameRequested();
|
||||
}
|
||||
|
||||
private OnNewGameRequestedListener listener = null;
|
||||
|
||||
private void createNewGame() {
|
||||
if (listener != null) {
|
||||
listener.onNewGameRequested();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,342 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnLongClickListener;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.activity.HeroinfoActivity;
|
||||
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.util.Coord;
|
||||
import com.gpl.rpg.AndorsTrail.util.L;
|
||||
|
||||
public final class InputController implements OnClickListener, OnLongClickListener{
|
||||
private final ControllerContext controllers;
|
||||
private final WorldContext world;
|
||||
|
||||
private final Coord lastTouchPosition_tileCoords = new Coord();
|
||||
private int lastTouchPosition_dx = 0;
|
||||
private int lastTouchPosition_dy = 0;
|
||||
private long lastTouchEventTime = 0;
|
||||
private boolean isDpadActive = false;
|
||||
|
||||
private int keyState_dx = 0;
|
||||
private int keyState_dy = 0;
|
||||
private boolean keyState_attack = false;
|
||||
private boolean keyState_flee = false;
|
||||
private boolean keyState_endturn = false;
|
||||
|
||||
final private int KEY_UNHANDLED = 0; // Default, for unhandled keycodes
|
||||
final private int KEY_MOVE_UP = 1;
|
||||
final private int KEY_MOVE_DOWN = 2;
|
||||
final private int KEY_MOVE_LEFT = 3;
|
||||
final private int KEY_MOVE_RIGHT = 4;
|
||||
final private int KEY_MOVE_UP_LEFT = 5;
|
||||
final private int KEY_MOVE_UP_RIGHT = 6;
|
||||
final private int KEY_MOVE_DOWN_LEFT = 7;
|
||||
final private int KEY_MOVE_DOWN_RIGHT = 8;
|
||||
final private int KEY_ATTACK = 9;
|
||||
final private int KEY_FLEE = 10;
|
||||
final private int KEY_END_TURN = 11;
|
||||
final private int KEY_HERO_INFO = 12;
|
||||
final private int KEY_TOOLBOX = 13;
|
||||
|
||||
private SparseIntArray keyMap = new SparseIntArray(); // Android keycode to internal key event mapping. TODO: Configure via preferences
|
||||
|
||||
public InputController(ControllerContext controllers, WorldContext world) {
|
||||
this.controllers = controllers;
|
||||
this.world = world;
|
||||
initializeKeyMap();
|
||||
|
||||
}
|
||||
|
||||
/* New keyboard handler. Both Key Down and Key Up events handled here to allow conditional behaviours.
|
||||
On 4-way dpad controllers, cursor keys, and WASD, diagonals are generated by chording two keys.
|
||||
Single-key diagonals are supported on numeric keypad and 8-way dpads (not seen/tested in the wild).
|
||||
|
||||
Because two-key combos initially generate a ordinal movement (one key comes in first), which can
|
||||
be dangerous in tight spaces, modifiers are provided to "lock" the input until both keys are down.
|
||||
TODO: Use delay timer to enable chorded diagonals on first move without locking kludge?
|
||||
*/
|
||||
|
||||
// Map key codes to spectic internal actions
|
||||
// TODO: Move mapping out of code to JSON/XML file, or maybe player prefs
|
||||
private void initializeKeyMap() {
|
||||
int key;
|
||||
|
||||
// Keys mapping to UP
|
||||
key = KEY_MOVE_UP;
|
||||
keyMap.put(KeyEvent.KEYCODE_DPAD_UP, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_NUMPAD_8, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_8, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_W, key);
|
||||
|
||||
// Keys mapping to DOWN
|
||||
key = KEY_MOVE_DOWN;
|
||||
keyMap.put(KeyEvent.KEYCODE_DPAD_DOWN, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_NUMPAD_2, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_2, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_S, key);
|
||||
|
||||
// Keys mapping to LEFT
|
||||
key = KEY_MOVE_LEFT;
|
||||
keyMap.put(KeyEvent.KEYCODE_DPAD_LEFT, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_NUMPAD_4, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_4, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_A, key);
|
||||
|
||||
// Keys mapping to RIGHT
|
||||
key = KEY_MOVE_RIGHT;
|
||||
keyMap.put(KeyEvent.KEYCODE_DPAD_RIGHT, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_NUMPAD_6, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_6, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_D, key);
|
||||
|
||||
// Keys mapping to UP_LEFT
|
||||
key = KEY_MOVE_UP_LEFT;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
keyMap.put(KeyEvent.KEYCODE_DPAD_UP_LEFT, key);
|
||||
}
|
||||
keyMap.put(KeyEvent.KEYCODE_NUMPAD_7, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_7, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_MOVE_HOME, key);
|
||||
|
||||
// Keys mapping to UP_RIGHT
|
||||
key = KEY_MOVE_UP_RIGHT;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
keyMap.put(KeyEvent.KEYCODE_DPAD_UP_RIGHT, key);
|
||||
}
|
||||
keyMap.put(KeyEvent.KEYCODE_NUMPAD_9, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_9, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_PAGE_UP, key);
|
||||
|
||||
// Keys mapping to DOWN_LEFT
|
||||
key = KEY_MOVE_DOWN_LEFT;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
keyMap.put(KeyEvent.KEYCODE_DPAD_DOWN_LEFT, key);
|
||||
}
|
||||
keyMap.put(KeyEvent.KEYCODE_NUMPAD_1, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_1, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_MOVE_END, key);
|
||||
|
||||
// Keys mapping to DOWN_RIGHT
|
||||
key = KEY_MOVE_DOWN_RIGHT;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
keyMap.put(KeyEvent.KEYCODE_DPAD_DOWN_RIGHT, key);
|
||||
}
|
||||
keyMap.put(KeyEvent.KEYCODE_NUMPAD_3, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_3, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_PAGE_DOWN, key);
|
||||
|
||||
// Keys mapping to ATTACK
|
||||
key = KEY_ATTACK;
|
||||
keyMap.put(KeyEvent.KEYCODE_DPAD_CENTER, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_BUTTON_A, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_SPACE, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_NUMPAD_5, key);
|
||||
|
||||
// Keys mapping to FLEE
|
||||
key = KEY_FLEE;
|
||||
keyMap.put(KeyEvent.KEYCODE_BUTTON_X, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_F, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_NUMPAD_ENTER, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_ENTER, key);
|
||||
|
||||
// Keys mapping to END_TURN
|
||||
key = KEY_END_TURN;
|
||||
keyMap.put(KeyEvent.KEYCODE_BUTTON_Y, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_E, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_FORWARD_DEL, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_NUMPAD_DOT, key);
|
||||
|
||||
// Keys mapping to HERO_INFO
|
||||
key = KEY_HERO_INFO;
|
||||
//keyMap.put(KeyEvent.KEYCODE_BUTTON_SELECT, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_BUTTON_L1, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_NUM_LOCK, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_C, key);
|
||||
|
||||
// Keys mapping to TOOLBOX
|
||||
key = KEY_TOOLBOX;
|
||||
keyMap.put(KeyEvent.KEYCODE_BUTTON_R1, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_NUMPAD_DIVIDE, key);
|
||||
keyMap.put(KeyEvent.KEYCODE_B, key);
|
||||
}
|
||||
|
||||
// Generate game actions based on mapped keys
|
||||
public boolean onKeyboardAction(Context context, KeyEvent event, boolean acceptInput) {
|
||||
//L.log("onKeyboardAction(): Processing action " + event.getAction() + " for keyCode " + event.getKeyCode());
|
||||
|
||||
if (event.getAction() != KeyEvent.ACTION_DOWN && event.getAction() != KeyEvent.ACTION_UP) return false; // don't handle other actions
|
||||
boolean keydown = (event.getAction() == KeyEvent.ACTION_DOWN);
|
||||
boolean inihbit = (keyState_attack || keyState_flee); // used to inhibit movement if an action key is held down
|
||||
|
||||
switch (keyMap.get(event.getKeyCode())) {
|
||||
|
||||
// Ordinal directional keys - only modify one direction register; registers are combined when
|
||||
// keys used simultaneously to create synthetic diagonals
|
||||
case KEY_MOVE_UP:
|
||||
keyState_dy = keydown ? -1 : 0;
|
||||
if (acceptInput && !inihbit) onRelativeMovement(keyState_dx, keyState_dy);
|
||||
break;
|
||||
case KEY_MOVE_DOWN:
|
||||
keyState_dy = keydown ? 1 : 0;
|
||||
if (acceptInput && !inihbit) onRelativeMovement(keyState_dx, keyState_dy);
|
||||
break;
|
||||
case KEY_MOVE_LEFT:
|
||||
keyState_dx = keydown ? -1 : 0;
|
||||
if (acceptInput && !inihbit) onRelativeMovement(keyState_dx, keyState_dy);
|
||||
break;
|
||||
case KEY_MOVE_RIGHT:
|
||||
keyState_dx = keydown ? 1 : 0;
|
||||
if (acceptInput && !inihbit) onRelativeMovement(keyState_dx, keyState_dy);
|
||||
break;
|
||||
|
||||
// Diagonal directional keys. Modify both direction registers, can't be combined
|
||||
// TODO: store individual key position to allow combinations. May not be worth the trouble.
|
||||
case KEY_MOVE_UP_LEFT:
|
||||
keyState_dx = keydown ? -1 : 0;
|
||||
keyState_dy = keydown ? -1 : 0;
|
||||
if (acceptInput && !inihbit) onRelativeMovement(keyState_dx, keyState_dy);
|
||||
break;
|
||||
case KEY_MOVE_UP_RIGHT:
|
||||
keyState_dx = keydown ? 1 : 0;
|
||||
keyState_dy = keydown ? -1 : 0;
|
||||
if (acceptInput && !inihbit) onRelativeMovement(keyState_dx, keyState_dy);
|
||||
break;
|
||||
case KEY_MOVE_DOWN_LEFT:
|
||||
keyState_dx = keydown ? -1 : 0;
|
||||
keyState_dy = keydown ? 1 : 0;
|
||||
if (acceptInput && !inihbit) onRelativeMovement(keyState_dx, keyState_dy);
|
||||
break;
|
||||
case KEY_MOVE_DOWN_RIGHT:
|
||||
keyState_dx = keydown ? 1 : 0;
|
||||
keyState_dy = keydown ? 1 : 0;
|
||||
if (acceptInput && !inihbit) onRelativeMovement(keyState_dx, keyState_dy);
|
||||
break;
|
||||
|
||||
// Special key handling below - some combat/movement stuff done here because it's too
|
||||
// specific for logic in onRelativeMovement
|
||||
|
||||
// "Attack" shortcut - freeze movement to allow chorded direction when key is released.
|
||||
// if in combat, executes an attack on key release
|
||||
case KEY_ATTACK:
|
||||
if (keydown && !keyState_attack) { // key pressed - pause any movement
|
||||
if(!world.model.uiSelections.isInCombat) controllers.movementController.stopMovement();
|
||||
} else if (!keydown && keyState_attack) { // key released - execute attack / move in direction
|
||||
if (acceptInput) onRelativeMovement(keyState_dx, keyState_dy);
|
||||
}
|
||||
keyState_attack = keydown;
|
||||
break;
|
||||
|
||||
// "Flee" shortcut. Intitiates flee when pressed. If a direction is held, moves in chosen direction when released
|
||||
case KEY_FLEE:
|
||||
if (world.model.uiSelections.isInCombat) {
|
||||
if (keydown && !keyState_flee) { // button pressed - set flee; movement locked while pressed
|
||||
if(acceptInput) controllers.combatController.startFlee();
|
||||
} else if (!keydown && keyState_flee) { // button released - move flee direction, if held
|
||||
// We need to do a special call because the movement key may already be down, and if the device
|
||||
// doesn't generate repeat keystrokes, this handler won't get another event
|
||||
if ((keyState_dx != 0 || keyState_dy != 0) && allowInputInterval()) {
|
||||
if(acceptInput) controllers.combatController.executeMoveAttack(keyState_dx, keyState_dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
keyState_flee = keydown;
|
||||
break;
|
||||
|
||||
// "End Turn" shortcut. Flag prevents repeated end turn if key is held down.
|
||||
case KEY_END_TURN:
|
||||
if (acceptInput && keydown && !keyState_endturn) {
|
||||
if (world.model.uiSelections.isInCombat) controllers.combatController.endPlayerTurn();
|
||||
}
|
||||
keyState_endturn = keydown;
|
||||
break;
|
||||
|
||||
// "Hero Info" screen shortcut. New activity takes focus, so we don't need to worry about repeats.
|
||||
case KEY_HERO_INFO:
|
||||
if (acceptInput && keydown) context.startActivity(new Intent(context, HeroinfoActivity.class));
|
||||
break;
|
||||
|
||||
case KEY_TOOLBOX:
|
||||
// ??? ToolboxView toolboxview = context.getApplicationContext(). findViewById(R.id.main_toolboxview);
|
||||
|
||||
break;
|
||||
|
||||
case KEY_UNHANDLED: // Unhandled keycode
|
||||
return false;
|
||||
|
||||
default: // unhandled keymap code entry (should not happen)
|
||||
L.log("onKeyboardAction(): Unhandled keyMap code constant " + keyMap.get(event.getKeyCode()) + " for keyCode " + event.getKeyCode());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onRelativeMovement(int dx, int dy) {
|
||||
//L.log("onRelativeMovement(): dx=" + dx + " dy=" + dy + " combat: " + world.model.uiSelections.isInCombat);
|
||||
if (world.model.uiSelections.isInCombat) {
|
||||
if (allowInputInterval()) controllers.combatController.executeMoveAttack(dx, dy);
|
||||
} else if (dx == 0 && dy == 0) {
|
||||
controllers.movementController.stopMovement();
|
||||
} else {
|
||||
controllers.movementController.startMovement(dx, dy, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void onKeyboardCancel() {
|
||||
controllers.movementController.stopMovement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
if (!world.model.uiSelections.isInCombat) return;
|
||||
onRelativeMovement(lastTouchPosition_dx, lastTouchPosition_dy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View arg0) {
|
||||
if (world.model.uiSelections.isInCombat) {
|
||||
//TODO: Should be able to mark positions far away (mapwalk / ranged combat)
|
||||
if (lastTouchPosition_dx == 0 && lastTouchPosition_dy == 0) return false;
|
||||
if (Math.abs(lastTouchPosition_dx) > 1) return false;
|
||||
if (Math.abs(lastTouchPosition_dy) > 1) return false;
|
||||
|
||||
controllers.combatController.setCombatSelection(lastTouchPosition_tileCoords);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean allowInputInterval() {
|
||||
final long now = System.currentTimeMillis();
|
||||
if ((now - lastTouchEventTime) < Constants.MINIMUM_INPUT_INTERVAL) return false;
|
||||
lastTouchEventTime = now;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setDpadActive(boolean isDpadActive) {
|
||||
this.isDpadActive = isDpadActive;
|
||||
}
|
||||
|
||||
public void onTouchCancel() {
|
||||
controllers.movementController.stopMovement();
|
||||
}
|
||||
|
||||
public boolean onTouchedTile(int tile_x, int tile_y) {
|
||||
lastTouchPosition_tileCoords.set(tile_x, tile_y);
|
||||
lastTouchPosition_dx = tile_x - world.model.player.position.x;
|
||||
lastTouchPosition_dy = tile_y - world.model.player.position.y;
|
||||
|
||||
if (world.model.uiSelections.isInCombat || isDpadActive) return false;
|
||||
|
||||
controllers.movementController.startMovement(lastTouchPosition_dx, lastTouchPosition_dy, lastTouchPosition_tileCoords);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.model;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import android.content.res.Resources;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.MonsterType;
|
||||
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
|
||||
import com.gpl.rpg.AndorsTrail.model.quest.Quest;
|
||||
import com.gpl.rpg.AndorsTrail.util.HashMapHelper;
|
||||
|
||||
public final class GameStatistics {
|
||||
private int deaths = 0;
|
||||
private final HashMap<String, Integer> killedMonstersByTypeID = new HashMap<String, Integer>();
|
||||
private final HashMap<String, Integer> killedMonstersByName = new HashMap<String, Integer>();
|
||||
private final HashMap<String, Integer> usedItems = new HashMap<String, Integer>();
|
||||
private int spentGold = 0;
|
||||
private boolean unlimitedSaves = true;
|
||||
private int startLives = -1; // -1 --> unlimited
|
||||
|
||||
public GameStatistics(boolean unlimitedSaves, int startLives) {
|
||||
this.unlimitedSaves = unlimitedSaves;
|
||||
this.startLives = startLives;
|
||||
}
|
||||
|
||||
public void addMonsterKill(MonsterType monsterType) {
|
||||
// Track monster kills by type ID, for savegame file
|
||||
killedMonstersByTypeID.put(monsterType.id, getNumberOfKillsForMonsterType(monsterType.id) + 1);
|
||||
|
||||
// Also track by name, for statistics display (multiple IDs w/same name don't matter to player)
|
||||
killedMonstersByName.put(monsterType.name, getNumberOfKillsForMonsterName(monsterType.name) + 1);
|
||||
}
|
||||
|
||||
public void addPlayerDeath(int lostExp) {
|
||||
++deaths;
|
||||
}
|
||||
public void addGoldSpent(int amount) {
|
||||
spentGold += amount;
|
||||
}
|
||||
public void addItemUsage(ItemType type) {
|
||||
final String n = type.id;
|
||||
usedItems.put(n, HashMapHelper.getOrDefault(usedItems, n,0) + 1);
|
||||
}
|
||||
|
||||
public int getDeaths() {
|
||||
return deaths;
|
||||
}
|
||||
|
||||
public int getSpentGold() {
|
||||
return spentGold;
|
||||
}
|
||||
|
||||
public boolean hasUnlimitedSaves() { return unlimitedSaves; }
|
||||
|
||||
public boolean hasUnlimitedLives() { return startLives == -1; }
|
||||
|
||||
public int getStartLives() { return startLives; }
|
||||
|
||||
public int getLivesLeft() { return hasUnlimitedLives() ? -1 : startLives - deaths; }
|
||||
|
||||
public boolean isDead() { return !hasUnlimitedLives() && getLivesLeft() < 1; }
|
||||
|
||||
public int getNumberOfKillsForMonsterType(String monsterTypeID) {
|
||||
return HashMapHelper.getOrDefault(killedMonstersByTypeID, monsterTypeID, 0);
|
||||
}
|
||||
|
||||
public int getNumberOfKillsForMonsterName(String monsterName) {
|
||||
return HashMapHelper.getOrDefault(killedMonstersByName, monsterName, 0);
|
||||
}
|
||||
|
||||
public String getTop5MostCommonlyKilledMonsters(WorldContext world, Resources res) {
|
||||
if (killedMonstersByTypeID.isEmpty()) return null;
|
||||
List<Entry<String, Integer>> entries = new ArrayList<Entry<String, Integer>>(killedMonstersByName.entrySet());
|
||||
Collections.sort(entries, descendingValueComparator);
|
||||
StringBuilder sb = new StringBuilder(100);
|
||||
int i = 0;
|
||||
for (Entry<String, Integer> e : entries) {
|
||||
if (i++ >= 5) break;
|
||||
sb.append(res.getString(R.string.heroinfo_gamestats_name_and_qty, e.getKey(), e.getValue())).append('\n');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getMostPowerfulKilledMonster(WorldContext world) {
|
||||
if (killedMonstersByTypeID.isEmpty()) return null;
|
||||
HashMap<String, Integer> expPerMonsterType = new HashMap<String, Integer>(killedMonstersByTypeID.size());
|
||||
for (String monsterTypeID : killedMonstersByTypeID.keySet()) {
|
||||
MonsterType t = world.monsterTypes.getMonsterType(monsterTypeID);
|
||||
expPerMonsterType.put(monsterTypeID, t != null ? t.exp : 0);
|
||||
}
|
||||
String monsterTypeID = Collections.min(expPerMonsterType.entrySet(), descendingValueComparator).getKey();
|
||||
MonsterType t = world.monsterTypes.getMonsterType(monsterTypeID);
|
||||
return t != null ? t.name : null;
|
||||
}
|
||||
|
||||
public String getMostCommonlyUsedItem(WorldContext world, Resources res) {
|
||||
if (usedItems.isEmpty()) return null;
|
||||
Entry<String, Integer> e = Collections.min(usedItems.entrySet(), descendingValueComparator);
|
||||
String itemTypeID = e.getKey();
|
||||
ItemType t = world.itemTypes.getItemType(itemTypeID);
|
||||
if (t == null) return null;
|
||||
return res.getString(R.string.heroinfo_gamestats_name_and_qty, t.getName(world.model.player), e.getValue());
|
||||
}
|
||||
|
||||
public int getNumberOfUsedBonemealPotions() {
|
||||
int result = 0;
|
||||
Integer v;
|
||||
if ((v = usedItems.get("bonemeal_potion")) != null) result += v;
|
||||
if ((v = usedItems.get("pot_bm_lodar")) != null) result += v;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getNumberOfCompletedQuests(WorldContext world) {
|
||||
int result = 0;
|
||||
for (Quest q : world.quests.getAllQuests()) {
|
||||
if (!q.showInLog) continue;
|
||||
if (q.isCompleted(world.model.player)) ++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getNumberOfVisitedMaps(WorldContext world) {
|
||||
int result = 0;
|
||||
for (PredefinedMap m : world.maps.getAllMaps()) {
|
||||
if (m.visited) ++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getNumberOfUsedItems() {
|
||||
return HashMapHelper.sumIntegerValues(usedItems);
|
||||
}
|
||||
|
||||
public int getNumberOfTimesItemHasBeenUsed(String itemId) {
|
||||
return HashMapHelper.getOrDefault(usedItems, itemId, 0);
|
||||
}
|
||||
|
||||
public int getNumberOfKilledMonsters() {
|
||||
return HashMapHelper.sumIntegerValues(killedMonstersByTypeID);
|
||||
}
|
||||
|
||||
private static final Comparator<Entry<String, Integer>> descendingValueComparator = new Comparator<Entry<String, Integer>>() {
|
||||
@Override
|
||||
public int compare(Entry<String, Integer> a, Entry<String, Integer> b) {
|
||||
return b.getValue().compareTo(a.getValue());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// ====== PARCELABLE ===================================================================
|
||||
|
||||
public GameStatistics(DataInputStream src, WorldContext world, int fileversion) throws IOException {
|
||||
this.deaths = src.readInt();
|
||||
final int numMonsters = src.readInt();
|
||||
for(int i = 0; i < numMonsters; ++i) {
|
||||
String id = src.readUTF();
|
||||
final int value = src.readInt();
|
||||
if(fileversion <= 23) {
|
||||
MonsterType type = world.monsterTypes.guessMonsterTypeFromName(id);
|
||||
if (type == null) continue;
|
||||
id = type.id;
|
||||
}
|
||||
this.killedMonstersByTypeID.put(id, value);
|
||||
|
||||
// Also track by name, for statistics display (multiple IDs w/same name don't matter to player)
|
||||
MonsterType t = world.monsterTypes.getMonsterType(id);
|
||||
|
||||
if (t != null) killedMonstersByName.put(t.name, getNumberOfKillsForMonsterName(t.name) + value);
|
||||
}
|
||||
|
||||
if (fileversion <= 17) return;
|
||||
|
||||
final int numItems = src.readInt();
|
||||
for(int i = 0; i < numItems; ++i) {
|
||||
final String name = src.readUTF();
|
||||
final int value = src.readInt();
|
||||
this.usedItems.put(name, value);
|
||||
}
|
||||
this.spentGold = src.readInt();
|
||||
|
||||
if (fileversion < 49) return;
|
||||
|
||||
this.startLives = src.readInt();
|
||||
this.unlimitedSaves = src.readBoolean();
|
||||
}
|
||||
|
||||
public void writeToParcel(DataOutputStream dest) throws IOException {
|
||||
dest.writeInt(deaths);
|
||||
Set<Entry<String, Integer> > set = killedMonstersByTypeID.entrySet();
|
||||
dest.writeInt(set.size());
|
||||
for (Entry<String, Integer> e : set) {
|
||||
dest.writeUTF(e.getKey());
|
||||
dest.writeInt(e.getValue());
|
||||
}
|
||||
set = usedItems.entrySet();
|
||||
dest.writeInt(set.size());
|
||||
for (Entry<String, Integer> e : set) {
|
||||
dest.writeUTF(e.getKey());
|
||||
dest.writeInt(e.getValue());
|
||||
}
|
||||
dest.writeInt(spentGold);
|
||||
dest.writeInt(startLives);
|
||||
dest.writeBoolean(unlimitedSaves);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.model;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.model.map.LayeredTileMap;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
|
||||
import com.gpl.rpg.AndorsTrail.resource.tiles.TileCollection;
|
||||
|
||||
public final class MapBundle {
|
||||
public PredefinedMap map;
|
||||
public LayeredTileMap tileMap;
|
||||
public TileCollection tiles;
|
||||
}
|
||||
@@ -1,365 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.resource;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Collection;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.model.conversation.ConversationCollection;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.TMXMapTranslator;
|
||||
import com.gpl.rpg.AndorsTrail.resource.parsers.ActorConditionsTypeParser;
|
||||
import com.gpl.rpg.AndorsTrail.resource.parsers.ConversationListParser;
|
||||
import com.gpl.rpg.AndorsTrail.resource.parsers.DropListParser;
|
||||
import com.gpl.rpg.AndorsTrail.resource.parsers.ItemCategoryParser;
|
||||
import com.gpl.rpg.AndorsTrail.resource.parsers.ItemTypeParser;
|
||||
import com.gpl.rpg.AndorsTrail.resource.parsers.MonsterTypeParser;
|
||||
import com.gpl.rpg.AndorsTrail.resource.parsers.QuestParser;
|
||||
import com.gpl.rpg.AndorsTrail.resource.parsers.WorldMapParser;
|
||||
import com.gpl.rpg.AndorsTrail.util.L;
|
||||
import com.gpl.rpg.AndorsTrail.util.Size;
|
||||
|
||||
public final class ResourceLoader {
|
||||
|
||||
private static final int itemCategoriesResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_itemcategories_debug : R.array.loadresource_itemcategories;
|
||||
private static final int actorConditionsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_actorconditions_debug : R.array.loadresource_actorconditions;
|
||||
private static final int itemsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_items_debug : R.array.loadresource_items;
|
||||
private static final int droplistsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_droplists_debug : R.array.loadresource_droplists;
|
||||
private static final int questsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_quests_debug : R.array.loadresource_quests;
|
||||
private static final int conversationsListsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_conversationlists_debug : R.array.loadresource_conversationlists;
|
||||
private static final int monstersResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_monsters_debug : R.array.loadresource_monsters;
|
||||
private static final int mapsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_maps_debug : R.array.loadresource_maps;
|
||||
|
||||
private static DynamicTileLoader loader;
|
||||
private static TranslationLoader translationLoader;
|
||||
private static long taskStart;
|
||||
private static void timingCheckpoint(String loaderName) {
|
||||
long now = System.currentTimeMillis();
|
||||
long duration = now - taskStart;
|
||||
L.log(loaderName + " ran for " + duration + " ms.");
|
||||
taskStart = now;
|
||||
}
|
||||
|
||||
public static void loadResourcesSync(WorldContext world, Resources r) {
|
||||
long start = System.currentTimeMillis();
|
||||
taskStart = start;
|
||||
|
||||
final int mTileSize = world.tileManager.tileSize;
|
||||
|
||||
|
||||
loader = new DynamicTileLoader(world.tileManager.tileCache);
|
||||
prepareTilesets(loader, mTileSize);
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("prepareTilesets");
|
||||
|
||||
// ========================================================================
|
||||
// Load various ui icons
|
||||
// HeroCollection.prepareHeroesTileId(loader);
|
||||
/*TileManager.iconID_CHAR_HERO_0 = */loader.prepareTileID(R.drawable.char_hero, 0);
|
||||
/*TileManager.iconID_CHAR_HERO_1 = */loader.prepareTileID(R.drawable.char_hero_maksiu_girl_01, 0);
|
||||
/*TileManager.iconID_CHAR_HERO_2 = */loader.prepareTileID(R.drawable.char_hero_maksiu_boy_01, 0);
|
||||
/*TileManager.iconID_selection_red = */loader.prepareTileID(R.drawable.ui_selections, 0);
|
||||
/*TileManager.iconID_selection_yellow = */loader.prepareTileID(R.drawable.ui_selections, 1);
|
||||
/*TileManager.iconID_groundbag = */loader.prepareTileID(R.drawable.ui_icon_equipment, 0);
|
||||
/*TileManager.iconID_boxopened = */loader.prepareTileID(R.drawable.ui_quickslots, 1);
|
||||
/*TileManager.iconID_boxclosed = */loader.prepareTileID(R.drawable.ui_quickslots, 0);
|
||||
/*TileManager.iconID_selection_blue = */loader.prepareTileID(R.drawable.ui_selections, 2);
|
||||
/*TileManager.iconID_selection_purple = */loader.prepareTileID(R.drawable.ui_selections, 3);
|
||||
/*TileManager.iconID_selection_green = */loader.prepareTileID(R.drawable.ui_selections, 4);
|
||||
for(int i = 0; i < 5; ++i) {
|
||||
loader.prepareTileID(R.drawable.ui_splatters1, i);
|
||||
loader.prepareTileID(R.drawable.ui_splatters1, i+8);
|
||||
}
|
||||
loader.prepareTileID(R.drawable.ui_icon_immunity, 0);
|
||||
|
||||
//Placeholders for dynamic map tiles
|
||||
loader.prepareTileID(R.drawable.map_dynamic_placeholders, 0);
|
||||
loader.prepareTileID(R.drawable.map_dynamic_placeholders, 1);
|
||||
loader.prepareTileID(R.drawable.map_dynamic_placeholders, 2);
|
||||
loader.prepareTileID(R.drawable.map_dynamic_placeholders, 3);
|
||||
loader.prepareTileID(R.drawable.map_dynamic_placeholders, 4);
|
||||
loader.prepareTileID(R.drawable.map_dynamic_placeholders, 5);
|
||||
loader.prepareTileID(R.drawable.map_dynamic_placeholders, 6);
|
||||
loader.prepareTileID(R.drawable.map_dynamic_placeholders, 7);
|
||||
loader.prepareTileID(R.drawable.map_dynamic_placeholders, 8);
|
||||
loader.prepareTileID(R.drawable.map_dynamic_placeholders, 9);
|
||||
|
||||
// Load effects
|
||||
world.visualEffectTypes.initialize(loader);
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("VisualEffectLoader");
|
||||
|
||||
translationLoader = new TranslationLoader(r.getAssets(), r);
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Load skills
|
||||
world.skills.initialize();
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("SkillLoader");
|
||||
|
||||
// ========================================================================
|
||||
// Load item categories
|
||||
final ItemCategoryParser itemCategoryParser = new ItemCategoryParser(translationLoader);
|
||||
final TypedArray categoriesToLoad = r.obtainTypedArray(itemCategoriesResourceId);
|
||||
for (int i = 0; i < categoriesToLoad.length(); ++i) {
|
||||
world.itemCategories.initialize(itemCategoryParser, readStringFromRaw(r, categoriesToLoad, i));
|
||||
}
|
||||
categoriesToLoad.recycle();
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("ItemCategoryParser");
|
||||
|
||||
// ========================================================================
|
||||
// Load condition types
|
||||
final ActorConditionsTypeParser actorConditionsTypeParser = new ActorConditionsTypeParser(loader, translationLoader);
|
||||
final TypedArray conditionsToLoad = r.obtainTypedArray(actorConditionsResourceId);
|
||||
for (int i = 0; i < conditionsToLoad.length(); ++i) {
|
||||
world.actorConditionsTypes.initialize(actorConditionsTypeParser, readStringFromRaw(r, conditionsToLoad, i));
|
||||
}
|
||||
conditionsToLoad.recycle();
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("ActorConditionsTypeParser");
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Load preloaded tiles
|
||||
loader.flush();
|
||||
world.tileManager.loadPreloadedTiles(r);
|
||||
}
|
||||
|
||||
public static void loadResourcesAsync(WorldContext world, Resources r) {
|
||||
long start = System.currentTimeMillis();
|
||||
taskStart = start;
|
||||
|
||||
// ========================================================================
|
||||
// Load items
|
||||
final ItemTypeParser itemTypeParser = new ItemTypeParser(loader, world.actorConditionsTypes, world.itemCategories, translationLoader);
|
||||
final TypedArray itemsToLoad = r.obtainTypedArray(itemsResourceId);
|
||||
for (int i = 0; i < itemsToLoad.length(); ++i) {
|
||||
world.itemTypes.initialize(itemTypeParser, readStringFromRaw(r, itemsToLoad, i));
|
||||
}
|
||||
itemsToLoad.recycle();
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("ItemTypeParser");
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Load droplists
|
||||
final DropListParser dropListParser = new DropListParser(world.itemTypes);
|
||||
final TypedArray droplistsToLoad = r.obtainTypedArray(droplistsResourceId);
|
||||
for (int i = 0; i < droplistsToLoad.length(); ++i) {
|
||||
world.dropLists.initialize(dropListParser, readStringFromRaw(r, droplistsToLoad, i));
|
||||
}
|
||||
droplistsToLoad.recycle();
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("DropListParser");
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Load quests
|
||||
final QuestParser questParser = new QuestParser(translationLoader);
|
||||
final TypedArray questsToLoad = r.obtainTypedArray(questsResourceId);
|
||||
for (int i = 0; i < questsToLoad.length(); ++i) {
|
||||
world.quests.initialize(questParser, readStringFromRaw(r, questsToLoad, i));
|
||||
}
|
||||
questsToLoad.recycle();
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("QuestParser");
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Load conversations
|
||||
final ConversationListParser conversationListParser = new ConversationListParser(translationLoader);
|
||||
final TypedArray conversationsListsToLoad = r.obtainTypedArray(conversationsListsResourceId);
|
||||
for (int i = 0; i < conversationsListsToLoad.length(); ++i) {
|
||||
ConversationCollection conversations = new ConversationCollection();
|
||||
Collection<String> ids = conversations.initialize(conversationListParser, readStringFromRaw(r, conversationsListsToLoad, i));
|
||||
world.conversationLoader.addIDs(conversationsListsToLoad.getResourceId(i, -1), ids);
|
||||
}
|
||||
conversationsListsToLoad.recycle();
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("ConversationListParser");
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Load monsters
|
||||
final MonsterTypeParser monsterTypeParser = new MonsterTypeParser(world.dropLists, world.actorConditionsTypes, loader, translationLoader);
|
||||
final TypedArray monstersToLoad = r.obtainTypedArray(monstersResourceId);
|
||||
for (int i = 0; i < monstersToLoad.length(); ++i) {
|
||||
world.monsterTypes.initialize(monsterTypeParser, readStringFromRaw(r, monstersToLoad, i));
|
||||
}
|
||||
monstersToLoad.recycle();
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("MonsterTypeParser");
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Load maps
|
||||
TMXMapTranslator mapReader = new TMXMapTranslator();
|
||||
final TypedArray mapsToLoad = r.obtainTypedArray(mapsResourceId);
|
||||
for (int i = 0; i < mapsToLoad.length(); ++i) {
|
||||
final int mapResourceId = mapsToLoad.getResourceId(i, -1);
|
||||
final String mapName = r.getResourceEntryName(mapResourceId);
|
||||
mapReader.read(r, mapResourceId, mapName);
|
||||
}
|
||||
mapsToLoad.recycle();
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("TMXMapReader");
|
||||
world.maps.addAll(mapReader.transformMaps(world.monsterTypes, world.dropLists));
|
||||
loader.prepareAllMapTiles();
|
||||
mapReader = null;
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("mapReader.transformMaps");
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Load graphics resources (icons and tiles)
|
||||
loader.flush();
|
||||
loader = null;
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("DynamicTileLoader");
|
||||
// ========================================================================
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Load worldmap coordinates
|
||||
WorldMapParser.read(r, R.xml.worldmap, world.maps, translationLoader);
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("WorldMapParser");
|
||||
// ========================================================================
|
||||
|
||||
translationLoader.close();
|
||||
|
||||
|
||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
|
||||
long duration = System.currentTimeMillis() - start;
|
||||
L.log("ResourceLoader ran for " + duration + " ms.");
|
||||
}
|
||||
}
|
||||
|
||||
public static String readStringFromRaw(final Resources r, final TypedArray array, final int index) {
|
||||
return readStringFromRaw(r, array.getResourceId(index, -1));
|
||||
}
|
||||
public static String readStringFromRaw(final Resources r, final int resourceID) {
|
||||
InputStream is = r.openRawResource(resourceID);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
||||
StringBuilder sb = new StringBuilder(1000);
|
||||
String line;
|
||||
try {
|
||||
while((line = br.readLine()) != null) sb.append(line);
|
||||
br.close();
|
||||
is.close();
|
||||
return sb.toString();
|
||||
} catch (IOException e) {
|
||||
L.log("ERROR: Reading from resource " + resourceID + " failed. " + e.toString());
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static void prepareTilesets(DynamicTileLoader loader, int mTileSize) {
|
||||
final Size sz1x1 = new Size(1, 1);
|
||||
final Size sz2x1 = new Size(2, 1);
|
||||
final Size sz2x2 = new Size(2, 2);
|
||||
final Size sz2x3 = new Size(2, 3);
|
||||
final Size sz3x1 = new Size(3, 1);
|
||||
final Size sz5x1 = new Size(5, 1);
|
||||
final Size sz6x1 = new Size(6, 1);
|
||||
final Size sz7x1 = new Size(7, 1);
|
||||
final Size sz8x3 = new Size(8, 3);
|
||||
final Size sz20x12 = new Size(20, 12);
|
||||
final Size mapTileSize = new Size(16, 8);
|
||||
final Size sz8x8 = new Size(8, 8);
|
||||
|
||||
|
||||
loader.prepareTileset(R.drawable.char_hero, "char_hero", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.char_hero_maksiu_girl_01, "char_hero_maksiu_girl_01", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.char_hero_maksiu_boy_01, "char_hero_maksiu_boy_01", sz1x1, sz1x1, mTileSize);
|
||||
|
||||
loader.prepareTileset(R.drawable.ui_selections, "ui_selections", new Size(5, 1), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.ui_quickslots, "ui_quickslots", sz2x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.ui_icon_equipment, "ui_icon_equipment", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.ui_splatters1, "ui_splatters1", new Size(8, 2), sz1x1, mTileSize);
|
||||
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.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_eye4, "monsters_eye4", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_giantbasilisk, "monsters_giantbasilisk", sz1x1, sz2x2, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_bosses_2x2, "monsters_bosses_2x2", sz1x1, sz2x2, mTileSize);
|
||||
|
||||
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_55, "map_55", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_56, "map_56", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_57, "map_57", 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_15, "obj_15", sz8x8, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.obj_16, "obj_16", 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);
|
||||
loader.prepareTileset(R.drawable.effect_poison1, "effect_poison1", new Size(8, 2), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.effect_miss1, "effect_miss1", new Size(8, 2), sz1x1, mTileSize);
|
||||
}
|
||||
}
|
||||
@@ -1,394 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.savegames;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.controller.Constants;
|
||||
import com.gpl.rpg.AndorsTrail.model.ModelContainer;
|
||||
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
// Create the savegame in a temporary memorystream first to ensure that the savegame can
|
||||
// be created correctly. We don't want to trash the user's file unneccessarily if there is an error.
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
saveWorld(world, bos, displayInfo);
|
||||
byte[] savegame = bos.toByteArray();
|
||||
bos.close();
|
||||
|
||||
FileOutputStream fos = getOutputFile(androidContext, slot);
|
||||
fos.write(savegame);
|
||||
fos.close();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
L.log("Error saving world: " + e.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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 (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
|
||||
L.log("Internal cheatcheck file savedVersion: " + cheatDetection.savedVersion);
|
||||
}
|
||||
|
||||
dataInputStream.close();
|
||||
fileInputStream.close();
|
||||
}
|
||||
|
||||
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 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 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;
|
||||
|
||||
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);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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);
|
||||
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();
|
||||
}
|
||||
|
||||
private static final Pattern savegameFilenamePattern = Pattern.compile(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + "(\\d+)");
|
||||
|
||||
public static List<Integer> getUsedSavegameSlots(Context context) {
|
||||
try {
|
||||
final List<Integer> result = new ArrayList<Integer>();
|
||||
AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY).listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File f, String filename) {
|
||||
Matcher m = savegameFilenamePattern.matcher(filename);
|
||||
if (m != null && m.matches()) {
|
||||
result.add(Integer.parseInt(m.group(1)));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
Collections.sort(result);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
return new ArrayList<Integer>();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class CheatDetection {
|
||||
public final int fileversion;
|
||||
public final long savedVersion;
|
||||
|
||||
// ====== PARCELABLE ===================================================================
|
||||
|
||||
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 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 ===================================================================
|
||||
|
||||
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 >= 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,472 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.util;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.support.v4.provider.DocumentFile;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.controller.Constants;
|
||||
import com.gpl.rpg.AndorsTrail.util.BackgroundWorker.BackgroundWorkerCallback;
|
||||
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
public final class AndroidStorage {
|
||||
public static File getStorageDirectory(Context context, String name) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
return context.getExternalFilesDir(name);
|
||||
} else {
|
||||
File root = Environment.getExternalStorageDirectory();
|
||||
return new File(root, name);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean shouldMigrateToInternalStorage(Context context) {
|
||||
boolean ret = false;
|
||||
File externalSaveGameDirectory = new File(Environment.getExternalStorageDirectory(),
|
||||
Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
File internalSaveGameDirectory = getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||
|
||||
if (externalSaveGameDirectory.exists()
|
||||
&& externalSaveGameDirectory.isDirectory()
|
||||
&& externalSaveGameDirectory.listFiles().length > 0
|
||||
&& (!internalSaveGameDirectory.exists()
|
||||
|| internalSaveGameDirectory.isDirectory()
|
||||
&& internalSaveGameDirectory.listFiles().length < 2)) {
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static boolean migrateToInternalStorage(Context context) {
|
||||
try {
|
||||
copy(new File(Environment.getExternalStorageDirectory(), Constants.CHEAT_DETECTION_FOLDER),
|
||||
getStorageDirectory(context, Constants.CHEAT_DETECTION_FOLDER));
|
||||
copy(new File(Environment.getExternalStorageDirectory(), Constants.FILENAME_SAVEGAME_DIRECTORY),
|
||||
getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY));
|
||||
} catch (IOException e) {
|
||||
L.log("Error migrating data: " + e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void copy(File sourceLocation, File targetLocation) throws IOException {
|
||||
if (!sourceLocation.exists()) {
|
||||
return;
|
||||
}
|
||||
if (sourceLocation.isDirectory()) {
|
||||
copyDirectory(sourceLocation, targetLocation);
|
||||
} else {
|
||||
copyFile(sourceLocation, targetLocation);
|
||||
}
|
||||
}
|
||||
|
||||
private static void copyDirectory(File source, File target) throws IOException {
|
||||
if (!target.exists()) {
|
||||
target.mkdir();
|
||||
}
|
||||
|
||||
for (String f : source.list()) {
|
||||
copy(new File(source, f), new File(target, f));
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyFile(File source, File target) throws IOException {
|
||||
try (InputStream in = new FileInputStream(source); OutputStream out = new FileOutputStream(target)) {
|
||||
copyStream(in, out);
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyStream(InputStream in, OutputStream out) throws IOException {
|
||||
byte[] buf = new byte[1024];
|
||||
int length;
|
||||
while ((length = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, length);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
public static void createZipDocumentFileFromFilesAsync(File[] files,
|
||||
Context context,
|
||||
DocumentFile targetDirectory,
|
||||
String fileName,
|
||||
String loadingMessage,
|
||||
Consumer<Boolean> callback) {
|
||||
|
||||
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
|
||||
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
|
||||
progressDialog.setOnCancelListener(dialog -> worker.cancel());
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Handler handler = Handler.createAsync(Looper.getMainLooper());
|
||||
|
||||
|
||||
worker.setTask(workerCallback -> {
|
||||
try {
|
||||
workerCallback.onInitialize();
|
||||
|
||||
//region create zip file
|
||||
File zip = File.createTempFile("temp_worldmap", ".zip");
|
||||
try (OutputStream out = new FileOutputStream(zip)) {
|
||||
ZipOutputStream zipOut = new ZipOutputStream(out);
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File file = files[i];
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
workerCallback.onProgress((float) i / files.length);
|
||||
zipOut.putNextEntry(new ZipEntry(file.getName()));
|
||||
copyStream(fis, zipOut);
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
}
|
||||
zipOut.close();
|
||||
}
|
||||
//endregion
|
||||
|
||||
DocumentFile worldmapZip = DocumentFile.fromFile(zip);
|
||||
DocumentFile worldmapTarget = targetDirectory.createFile("application/zip", fileName);
|
||||
if (worldmapTarget != null && worldmapTarget.exists()) {
|
||||
AndroidStorage.copyDocumentFile(worldmapZip, resolver, worldmapTarget);
|
||||
workerCallback.onComplete(true);
|
||||
} else {
|
||||
throw new FileNotFoundException("Could not create File");
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
if (worker.isCancelled()) {
|
||||
workerCallback.onFailure(new CancellationException("Cancelled"));
|
||||
} else {
|
||||
workerCallback.onFailure(e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
workerCallback.onFailure(e);
|
||||
}
|
||||
});
|
||||
|
||||
worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback));
|
||||
worker.run();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void unzipToDirectory(File zipFile,
|
||||
File targetDirectory,
|
||||
boolean overwriteNotSkip) throws IOException {
|
||||
|
||||
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
|
||||
unzipStreamToDirectory(targetDirectory, overwriteNotSkip, zis);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
public static void unzipDocumentFileToDirectoryAsync(DocumentFile zipFile,
|
||||
Context context,
|
||||
File targetDirectory,
|
||||
boolean overwriteNotSkip,
|
||||
String loadingMessage,
|
||||
Consumer<Boolean> callback) {
|
||||
|
||||
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
|
||||
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
|
||||
progressDialog.setOnCancelListener(dialog -> worker.cancel());
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Handler handler = Handler.createAsync(Looper.getMainLooper());
|
||||
|
||||
worker.setTask(workerCallback -> {
|
||||
try {
|
||||
workerCallback.onInitialize();
|
||||
workerCallback.onProgress(-1);//set dummy progress since we don't know the
|
||||
// progress of the unzip
|
||||
unzipDocumentFileToDirectory(zipFile, resolver, targetDirectory, overwriteNotSkip);
|
||||
workerCallback.onComplete(true);
|
||||
} catch (IOException e) {
|
||||
workerCallback.onFailure(e);
|
||||
}
|
||||
});
|
||||
|
||||
worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback));
|
||||
worker.run();
|
||||
|
||||
}
|
||||
|
||||
public static void unzipDocumentFileToDirectory(DocumentFile zipFile,
|
||||
ContentResolver resolver,
|
||||
File targetDirectory,
|
||||
boolean overwriteNotSkip) throws IOException {
|
||||
try (ZipInputStream zis = new ZipInputStream(resolver.openInputStream(zipFile.getUri()))) {
|
||||
unzipStreamToDirectory(targetDirectory, overwriteNotSkip, zis);
|
||||
}
|
||||
}
|
||||
|
||||
private static void unzipStreamToDirectory(File targetDirectory,
|
||||
boolean overwriteNotSkip,
|
||||
ZipInputStream zis) throws IOException {
|
||||
ZipEntry entry;
|
||||
while ((entry = zis.getNextEntry()) != null) {
|
||||
File file = new File(targetDirectory, entry.getName());
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
file.mkdirs();
|
||||
} else {
|
||||
file.getParentFile().mkdirs();
|
||||
if (file.exists() && !overwriteNotSkip) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
copyStream(zis, fos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile,
|
||||
ContentResolver resolver,
|
||||
DocumentFile targetFolder) throws IOException {
|
||||
copyDocumentFileToNewOrExistingFile(sourceFile,
|
||||
resolver,
|
||||
targetFolder,
|
||||
Constants.NO_FILE_EXTENSION_MIME_TYPE);
|
||||
}
|
||||
|
||||
|
||||
public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile,
|
||||
ContentResolver resolver,
|
||||
DocumentFile targetFolder,
|
||||
String mimeType) throws IOException {
|
||||
String fileName = sourceFile.getName();
|
||||
DocumentFile file = targetFolder.findFile(fileName);
|
||||
if (file == null) {
|
||||
file = targetFolder.createFile(mimeType, fileName);
|
||||
}
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
AndroidStorage.copyDocumentFile(sourceFile, resolver, file);
|
||||
}
|
||||
|
||||
public static void copyDocumentFile(DocumentFile sourceFile,
|
||||
ContentResolver resolver,
|
||||
DocumentFile targetFile) throws IOException {
|
||||
try (OutputStream outputStream = resolver.openOutputStream(targetFile.getUri());
|
||||
InputStream inputStream = resolver.openInputStream(sourceFile.getUri())) {
|
||||
copyStream(inputStream, outputStream);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getUrlForFile(Context context, File worldmap) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
String applicationId = context.getPackageName();
|
||||
Uri uri = FileProvider.getUriForFile(context, applicationId + ".fileprovider", worldmap);
|
||||
return uri.toString();
|
||||
} else {
|
||||
return "file://" + worldmap.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public static Intent getNewOpenDirectoryIntent() {
|
||||
return new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public static Intent getNewSelectMultipleSavegameFilesIntent() {
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
|
||||
intent.setType(Constants.SAVEGAME_FILE_MIME_TYPE);
|
||||
return intent;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public static Intent getNewSelectZipIntent() {
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("application/zip");
|
||||
return intent;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
public static void copyDocumentFilesFromToAsync(DocumentFile[] sources,
|
||||
Context context,
|
||||
DocumentFile[] targets,
|
||||
String loadingMessage,
|
||||
Consumer<Boolean> callback) {
|
||||
if (sources.length != targets.length) {
|
||||
throw new IllegalArgumentException("Both arrays, target & source have to have the same size");
|
||||
}
|
||||
|
||||
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
|
||||
|
||||
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
|
||||
progressDialog.setOnCancelListener(dialog -> worker.cancel());
|
||||
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Handler handler = Handler.createAsync(Looper.getMainLooper());
|
||||
|
||||
worker.setTask(workerCallback -> {
|
||||
try {
|
||||
workerCallback.onInitialize();
|
||||
for (int i = 0; i < sources.length; i++) {
|
||||
if (worker.isCancelled()) {
|
||||
workerCallback.onFailure(new CancellationException("Cancelled"));
|
||||
return;
|
||||
}
|
||||
DocumentFile source = sources[i];
|
||||
DocumentFile target = targets[i];
|
||||
|
||||
if (source == null || target == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
copyDocumentFile(source, resolver, target);
|
||||
float progress = i / (float) sources.length;
|
||||
workerCallback.onProgress(progress);
|
||||
}
|
||||
workerCallback.onComplete(true);
|
||||
} catch (NullPointerException e) {
|
||||
if (worker.isCancelled()) {
|
||||
workerCallback.onFailure(new CancellationException("Cancelled"));
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
workerCallback.onFailure(e);
|
||||
}
|
||||
});
|
||||
worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback));
|
||||
worker.run();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
public static void copyDocumentFilesToDirAsync(DocumentFile[] files,
|
||||
Context context,
|
||||
DocumentFile targetDirectory,
|
||||
String loadingMessage,
|
||||
Consumer<Boolean> callback) {
|
||||
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
|
||||
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
|
||||
progressDialog.setOnCancelListener(dialog -> worker.cancel());
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Handler handler = Handler.createAsync(Looper.getMainLooper());
|
||||
|
||||
worker.setTask(workerCallback -> {
|
||||
try {
|
||||
workerCallback.onInitialize();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
if (worker.isCancelled()) {
|
||||
workerCallback.onFailure(new CancellationException("Cancelled"));
|
||||
return;
|
||||
}
|
||||
DocumentFile file = files[i];
|
||||
if (file == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
copyDocumentFileToNewOrExistingFile(file, resolver, targetDirectory);
|
||||
float progress = i / (float) files.length;
|
||||
workerCallback.onProgress(progress);
|
||||
}
|
||||
workerCallback.onComplete(true);
|
||||
} catch (NullPointerException e) {
|
||||
if (worker.isCancelled()) {
|
||||
workerCallback.onFailure(new CancellationException("Cancelled"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
workerCallback.onFailure(e);
|
||||
}
|
||||
});
|
||||
worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback));
|
||||
worker.run();
|
||||
}
|
||||
|
||||
private static BackgroundWorkerCallback<Boolean> getDefaultBackgroundWorkerCallback(Handler handler,
|
||||
CustomDialogFactory.CustomDialog progressDialog,
|
||||
Consumer<Boolean> callback) {
|
||||
return new BackgroundWorkerCallback<Boolean>() {
|
||||
private int progress = -1;
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
handler.post(() -> {
|
||||
CustomDialogFactory.show(progressDialog);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(float progress) {
|
||||
handler.post(() -> {
|
||||
int intProgress = (int) (progress * 100);
|
||||
if (this.progress == intProgress) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.progress = intProgress;
|
||||
|
||||
if (progress == -1) {
|
||||
CustomDialogFactory.setDesc(progressDialog, null);
|
||||
return;
|
||||
}
|
||||
|
||||
CustomDialogFactory.setDesc(progressDialog, intProgress + "%");
|
||||
});
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
this.onComplete(false);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
@Override
|
||||
public void onComplete(Boolean result) {
|
||||
handler.post(() -> {
|
||||
progressDialog.dismiss();
|
||||
callback.accept(result);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static CustomDialogFactory.CustomDialog getLoadingDialog(Context context) {
|
||||
return getLoadingDialog(context, null);
|
||||
}
|
||||
|
||||
private static CustomDialogFactory.CustomDialog getLoadingDialog(Context context, String message) {
|
||||
if (message == null) {
|
||||
message = context.getResources().getString(R.string.dialog_loading_message);
|
||||
}
|
||||
|
||||
CustomDialogFactory.CustomDialog dialog = CustomDialogFactory.createDialog(context,
|
||||
message,
|
||||
context.getResources()
|
||||
.getDrawable(R.drawable.loading_anim),
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false);
|
||||
CustomDialogFactory.addCancelButton(dialog, android.R.string.no);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.util;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public final class BackgroundWorker<T> {
|
||||
boolean cancelled = false;
|
||||
worker<T> task;
|
||||
BackgroundWorkerCallback<T> callback;
|
||||
|
||||
public void setTask(worker<T> task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public void setCallback(BackgroundWorkerCallback<T> callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
interface worker<T> {
|
||||
void doWork(BackgroundWorkerCallback<T> callback);
|
||||
}
|
||||
|
||||
interface BackgroundWorkerCallback<T> {
|
||||
void onInitialize();
|
||||
|
||||
default void onProgress(float progress) {
|
||||
}
|
||||
|
||||
void onFailure(Exception e);
|
||||
|
||||
void onComplete(T result);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
Executors.newSingleThreadExecutor().execute(() -> {
|
||||
task.doWork(callback);
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public final class HashMapHelper {
|
||||
public static <K,V> V getOrDefault(HashMap<K,V> map, K key, V defaultValue) {
|
||||
V v = map.get(key);
|
||||
return v == null ? defaultValue : v;
|
||||
}
|
||||
public static <K> Integer sumIntegerValues(HashMap<K,Integer> map) {
|
||||
int sum = 0;
|
||||
for (Integer v : map.values()) sum += v;
|
||||
return sum;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,247 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface.OnDismissListener;
|
||||
import android.content.DialogInterface.OnCancelListener;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.R;
|
||||
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
|
||||
|
||||
public class CustomDialogFactory {
|
||||
|
||||
public static class CustomDialog extends android.app.Dialog {
|
||||
public CustomDialog(Context context) {
|
||||
super(context);
|
||||
}
|
||||
boolean verticalButtons = false;
|
||||
}
|
||||
|
||||
public static CustomDialog createDialog(final Context context, String title, Drawable icon,
|
||||
String desc, View content, boolean hasButtons, boolean canDismiss) {
|
||||
return createDialog(context, title, icon, desc, content, hasButtons, canDismiss, false);
|
||||
}
|
||||
|
||||
public static CustomDialog createDialog(final Context context, String title, Drawable icon,
|
||||
String desc, View content, boolean hasButtons) {
|
||||
return createDialog(context, title, icon, desc, content, hasButtons, true);
|
||||
}
|
||||
|
||||
public static CustomDialog createDialog(final Context context, String title, Drawable icon,
|
||||
String desc, View content, boolean hasButtons,
|
||||
final boolean canDismiss, final boolean verticalButtons) {
|
||||
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.verticalButtons = verticalButtons;
|
||||
|
||||
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 = getButtonContainer(dialog);
|
||||
ViewGroup unusedButtonsHolder = getUnusedButtonContainer(dialog);
|
||||
|
||||
unusedButtonsHolder.setVisibility(View.GONE);
|
||||
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 CustomDialog addButton(final CustomDialog dialog, String text, final OnClickListener listener) {
|
||||
return addButton(dialog, -1, text, listener);
|
||||
}
|
||||
public static CustomDialog addButton(final CustomDialog dialog, int textId, final OnClickListener listener) {
|
||||
return addButton(dialog, textId, null, listener);
|
||||
}
|
||||
public static CustomDialog addButton(final CustomDialog dialog, int textId, String text, final OnClickListener listener) {
|
||||
Button template = getButtonTemplate(dialog);
|
||||
LayoutParams params = template.getLayoutParams();
|
||||
ViewGroup buttonsHolder = getButtonContainer(dialog);
|
||||
|
||||
Button b = new Button(dialog.getContext());
|
||||
b.setLayoutParams(params);
|
||||
//Old android versions need this "reminder"
|
||||
b.setBackgroundDrawable(ThemeHelper.getThemeDrawable(dialog.getContext(), R.attr.ui_theme_textbutton_drawable));
|
||||
b.setTextColor(ThemeHelper.getThemeColor(dialog.getContext(), R.attr.ui_theme_dialogue_light_color));
|
||||
|
||||
if(textId != -1) {
|
||||
b.setText(textId);
|
||||
} else {
|
||||
b.setText(text);
|
||||
}
|
||||
|
||||
b.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
listener.onClick(v);
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
buttonsHolder.addView(b, params);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static CustomDialog addDismissButton(final CustomDialog dialog, int textId) {
|
||||
return CustomDialogFactory.addButton(dialog, textId, new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
public static CustomDialog addCancelButton(final CustomDialog dialog, int textId) {
|
||||
return CustomDialogFactory.addButton(dialog, textId, new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static CustomDialog setDismissListener(CustomDialog dialog, OnDismissListener listener) {
|
||||
dialog.setOnDismissListener(listener);
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static CustomDialog setCancelListener(CustomDialog dialog, OnCancelListener listener) {
|
||||
dialog.setOnCancelListener(listener);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static void show(CustomDialog dialog) {
|
||||
|
||||
dialog.findViewById(R.id.dialog_template_button).setVisibility(View.GONE);
|
||||
dialog.findViewById(R.id.dialog_template_button_vertical).setVisibility(View.GONE);
|
||||
dialog.show();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static ViewGroup getUnusedButtonContainer(CustomDialog dialog) {
|
||||
if (dialog.verticalButtons)
|
||||
return (ViewGroup) dialog.findViewById(R.id.dialog_button_container);
|
||||
else
|
||||
return (ViewGroup) dialog.findViewById(R.id.dialog_button_container_vertical);
|
||||
}
|
||||
|
||||
private static ViewGroup getButtonContainer(CustomDialog dialog) {
|
||||
if (dialog.verticalButtons)
|
||||
return (ViewGroup) dialog.findViewById(R.id.dialog_button_container_vertical);
|
||||
else
|
||||
return (ViewGroup) dialog.findViewById(R.id.dialog_button_container);
|
||||
}
|
||||
|
||||
private static Button getButtonTemplate(CustomDialog dialog) {
|
||||
if (dialog.verticalButtons)
|
||||
return (Button) dialog.findViewById(R.id.dialog_template_button_vertical);
|
||||
else
|
||||
return (Button) dialog.findViewById(R.id.dialog_template_button);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class CombatControllerTest {
|
||||
@Test
|
||||
public void getAverageDamagePerHit() throws Exception {
|
||||
Actor attacker = new Actor(null, false, false);
|
||||
attacker.attackChance = 100;
|
||||
attacker.damagePotential.set(5, 3);
|
||||
|
||||
Actor target = new Actor(null, false, false);
|
||||
target.damageResistance = 3;
|
||||
target.blockChance = 50;
|
||||
|
||||
float averageDamagePerHit = CombatController.getAverageDamagePerHit(attacker, target);
|
||||
assertEquals(0.5, averageDamagePerHit, 0.01);
|
||||
|
||||
attacker.criticalSkill = 30;
|
||||
attacker.criticalMultiplier = 2.5f;
|
||||
|
||||
averageDamagePerHit = CombatController.getAverageDamagePerHit(attacker, target);
|
||||
assertEquals(1.038, averageDamagePerHit, 0.01);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.2.1'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
}
|
||||
}
|
||||
BIN
AndorsTrail/gradle/wrapper/gradle-wrapper.jar
vendored
89
AndorsTrail/gradlew.bat
vendored
@@ -1,89 +0,0 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -1 +0,0 @@
|
||||
andor@andorstrail.com
|
||||
@@ -1 +0,0 @@
|
||||
http://andorstrail.com
|
||||
@@ -1 +0,0 @@
|
||||
en-US
|
||||
|
Before Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 164 KiB |
|
Before Width: | Height: | Size: 435 KiB |
|
Before Width: | Height: | Size: 210 KiB |
|
Before Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 334 KiB |
|
Before Width: | Height: | Size: 430 KiB |
|
Before Width: | Height: | Size: 403 KiB |
|
Before Width: | Height: | Size: 542 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 270 KiB |
|
Before Width: | Height: | Size: 502 KiB |
|
Before Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 337 KiB |