Compare commits

...

1 Commits

Author SHA1 Message Date
OMGeeky
f78a991a74 implement a version for savegame naming 2023-12-02 19:20:27 +01:00
7 changed files with 72 additions and 13 deletions

View File

@@ -32,7 +32,7 @@ public final class AndorsTrailApplication extends Application {
public static final boolean IS_RELEASE_VERSION = !CURRENT_VERSION_DISPLAY.matches(".*[a-d].*"); public static final boolean IS_RELEASE_VERSION = !CURRENT_VERSION_DISPLAY.matches(".*[a-d].*");
public static final boolean DEVELOPMENT_INCOMPATIBLE_SAVEGAMES = DEVELOPMENT_DEBUGRESOURCES || DEVELOPMENT_DEBUGBUTTONS || DEVELOPMENT_FASTSPEED || !IS_RELEASE_VERSION; public static final boolean DEVELOPMENT_INCOMPATIBLE_SAVEGAMES = DEVELOPMENT_DEBUGRESOURCES || DEVELOPMENT_DEBUGBUTTONS || DEVELOPMENT_FASTSPEED || !IS_RELEASE_VERSION;
public static final int DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION = 999; public static final int DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION = 999;
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 74; public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 75;
private final AndorsTrailPreferences preferences = new AndorsTrailPreferences(); private final AndorsTrailPreferences preferences = new AndorsTrailPreferences();
private WorldContext world = new WorldContext(); private WorldContext world = new WorldContext();

View File

@@ -22,11 +22,15 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.documentfile.provider.DocumentFile; import androidx.documentfile.provider.DocumentFile;
import android.text.InputType;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@@ -55,6 +59,8 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
private ModelContainer model; private ModelContainer model;
private TileManager tileManager; private TileManager tileManager;
private AndorsTrailPreferences preferences; private AndorsTrailPreferences preferences;
private String newSaveName;
private LayoutParams save_name_inputParams;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@@ -85,6 +91,9 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
Button slotTemplateButton = (Button) findViewById(R.id.loadsave_slot_n); Button slotTemplateButton = (Button) findViewById(R.id.loadsave_slot_n);
LayoutParams params = slotTemplateButton.getLayoutParams(); LayoutParams params = slotTemplateButton.getLayoutParams();
slotList.removeView(slotTemplateButton); slotList.removeView(slotTemplateButton);
EditText save_name_inputTemplateEditText = (EditText) findViewById(R.id.save_name_input);
save_name_inputParams = slotTemplateButton.getLayoutParams();
slotList.removeView(save_name_inputTemplateEditText);
ViewGroup newSlotContainer = (ViewGroup) findViewById(R.id.loadsave_save_to_new_slot_container); ViewGroup newSlotContainer = (ViewGroup) findViewById(R.id.loadsave_save_to_new_slot_container);
Button createNewSlot = (Button) findViewById(R.id.loadsave_save_to_new_slot); Button createNewSlot = (Button) findViewById(R.id.loadsave_save_to_new_slot);
@@ -216,9 +225,9 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
} else if (slot < SLOT_NUMBER_FIRST_SLOT) { } else if (slot < SLOT_NUMBER_FIRST_SLOT) {
slot = SLOT_NUMBER_FIRST_SLOT; slot = SLOT_NUMBER_FIRST_SLOT;
} }
i.putExtra("slot", slot); i.putExtra("slot", slot);
if (success) { if (success) {
i.putExtra(Constants.SAVEGAME_NAME_INTENT_EXTRA, newSaveName);
setResult(Activity.RESULT_OK, i); setResult(Activity.RESULT_OK, i);
} else { } else {
setResult(Activity.RESULT_CANCELED, i); setResult(Activity.RESULT_CANCELED, i);
@@ -312,7 +321,7 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
if (message != null) { if (message != null) {
showConfirmOverwriteQuestion(slot, message); showConfirmOverwriteQuestion(slot, message);
} else { } else {
completeLoadSaveActivity(slot); showNameSaveQuestion(slot);
} }
} }
@@ -866,7 +875,33 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
null, null,
true); true);
CustomDialogFactory.addButton(d, android.R.string.yes, v -> completeLoadSaveActivity(slot)); CustomDialogFactory.addButton(d, android.R.string.ok, v -> showNameSaveQuestion(slot));
CustomDialogFactory.addDismissButton(d, android.R.string.no);
CustomDialogFactory.show(d);
}
private void showNameSaveQuestion(final int slot) {
final String title = getString(R.string.loadsave_save_name_question);
final EditText input = new EditText(this);
input.setLayoutParams(save_name_inputParams);
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
final CustomDialog d = CustomDialogFactory.createDialog(this,
title,
getResources().getDrawable(android.R.drawable.ic_menu_save),
null,
input,
true);
CustomDialogFactory.addButton(d, android.R.string.ok, v -> {
final String name = input.getText().toString();
Log.d("com.gpl.rpg.AndorsTrail.beta2", "showNameSaveQuestion: ");
if (name.length() == 0) {
Toast.makeText(this, getString(R.string.loadsave_save_name_empty), Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this, getString(R.string.loadsave_save_name_filled, name), Toast.LENGTH_SHORT).show();
}
newSaveName = name;
completeLoadSaveActivity(slot);});
CustomDialogFactory.addDismissButton(d, android.R.string.no); CustomDialogFactory.addDismissButton(d, android.R.string.no);
CustomDialogFactory.show(d); CustomDialogFactory.show(d);
} }

View File

@@ -148,7 +148,8 @@ public final class MainActivity
case INTENTREQUEST_SAVEGAME: case INTENTREQUEST_SAVEGAME:
if (resultCode != Activity.RESULT_OK) break; if (resultCode != Activity.RESULT_OK) break;
final int slot = data.getIntExtra("slot", 1); final int slot = data.getIntExtra("slot", 1);
if (save(slot)) { final String saveName = data.getStringExtra(Constants.SAVEGAME_NAME_INTENT_EXTRA);
if (save(slot, saveName)) {
Toast.makeText(this, getResources().getString(R.string.menu_save_gamesaved, slot), Toast.LENGTH_SHORT).show(); Toast.makeText(this, getResources().getString(R.string.menu_save_gamesaved, slot), Toast.LENGTH_SHORT).show();
if (!world.model.statistics.hasUnlimitedSaves()) { if (!world.model.statistics.hasUnlimitedSaves()) {
finish(); finish();
@@ -161,7 +162,10 @@ public final class MainActivity
} }
private boolean save(int slot) { private boolean save(int slot) {
return Savegames.saveWorld(world, this, slot); return save(slot, null);
}
private boolean save(int slot, String saveName) {
return Savegames.saveWorld(world, this, slot, saveName);
} }
@Override @Override

View File

@@ -42,6 +42,7 @@ public final class Constants {
public static final String PREFERENCE_MODEL_LASTRUNVERSION = "lastversion"; public static final String PREFERENCE_MODEL_LASTRUNVERSION = "lastversion";
public static final String FILENAME_SAVEGAME_QUICKSAVE = "savegame"; public static final String FILENAME_SAVEGAME_QUICKSAVE = "savegame";
public static final String SAVEGAME_NAME_INTENT_EXTRA = "savegame_name";
public static final String FILENAME_SAVEGAME_DIRECTORY = "andors-trail"; public static final String FILENAME_SAVEGAME_DIRECTORY = "andors-trail";
public static final String FILENAME_WORLDMAP_DIRECTORY = "worldmap"; public static final String FILENAME_WORLDMAP_DIRECTORY = "worldmap";
public static final String FILENAME_WORLDMAP_HTMLFILE_PREFIX = "worldmap_"; public static final String FILENAME_WORLDMAP_HTMLFILE_PREFIX = "worldmap_";

View File

@@ -47,7 +47,7 @@ public final class Savegames {
, cheatingDetected , cheatingDetected
} }
public static boolean saveWorld(WorldContext world, Context androidContext, int slot) { public static boolean saveWorld(WorldContext world, Context androidContext, int slot, String saveName) {
try { try {
final String displayInfo = androidContext.getString(R.string.savegame_currenthero_displayinfo, world.model.player.getLevel(), world.model.player.getTotalExperience(), world.model.player.getGold()); 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()) { if (slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
@@ -59,7 +59,7 @@ public final class Savegames {
// Create the savegame in a temporary memorystream first to ensure that the savegame can // 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. // be created correctly. We don't want to trash the user's file unneccessarily if there is an error.
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
saveWorld(world, bos, displayInfo); saveWorld(world, bos, displayInfo, saveName);
byte[] savegame = bos.toByteArray(); byte[] savegame = bos.toByteArray();
bos.close(); bos.close();
@@ -108,7 +108,7 @@ public final class Savegames {
fos.close(); fos.close();
if (result == LoadSavegameResult.success && slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) { if (result == LoadSavegameResult.success && slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
// save to the quicksave slot before deleting the file // save to the quicksave slot before deleting the file
if (!saveWorld(world, androidContext, SLOT_QUICKSAVE)) { if (!saveWorld(world, androidContext, SLOT_QUICKSAVE, fh.saveName)) {
return LoadSavegameResult.unknownError; return LoadSavegameResult.unknownError;
} }
getSlotFile(slot, androidContext).delete(); getSlotFile(slot, androidContext).delete();
@@ -210,14 +210,16 @@ public final class Savegames {
} }
public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException { public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo, String saveName) throws IOException {
DataOutputStream dest = new DataOutputStream(outStream); DataOutputStream dest = new DataOutputStream(outStream);
final String savegameName = saveName == null ? "" : saveName;
FileHeader.writeToParcel(dest, world.model.player.getName(), FileHeader.writeToParcel(dest, world.model.player.getName(),
displayInfo, world.model.player.iconID, displayInfo, world.model.player.iconID,
world.model.statistics.isDead(), world.model.statistics.isDead(),
world.model.statistics.hasUnlimitedSaves(), world.model.statistics.hasUnlimitedSaves(),
world.model.player.id, world.model.player.id,
world.model.player.savedVersion); world.model.player.savedVersion,
savegameName);
world.maps.writeToParcel(dest, world); world.maps.writeToParcel(dest, world);
world.model.writeToParcel(dest); world.model.writeToParcel(dest);
dest.close(); dest.close();
@@ -334,9 +336,10 @@ public final class Savegames {
public final boolean hasUnlimitedSaves; public final boolean hasUnlimitedSaves;
public final String playerId; public final String playerId;
public final long savedVersion; public final long savedVersion;
public final String saveName;
public String describe() { public String describe() {
return (fileversion == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION ? "(D) " : "") + playerName + ", " + displayInfo; return (fileversion == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION ? "(D) " : "") + (saveName == null || saveName.equals("") ? "" : "[" + saveName + "] ") + playerName + ", " + displayInfo;
} }
@@ -378,9 +381,14 @@ public final class Savegames {
this.playerId = ""; this.playerId = "";
this.savedVersion = 0; this.savedVersion = 0;
} }
if(fileversion >= 75) {
this.saveName = src.readUTF();
} else {
this.saveName = "";
}
} }
public static void writeToParcel(DataOutputStream dest, String playerName, String displayInfo, int iconID, boolean isDead, boolean hasUnlimitedSaves, String playerId, long savedVersion) throws IOException { public static void writeToParcel(DataOutputStream dest, String playerName, String displayInfo, int iconID, boolean isDead, boolean hasUnlimitedSaves, String playerId, long savedVersion, String saveName) throws IOException {
dest.writeInt(AndorsTrailApplication.CURRENT_VERSION); dest.writeInt(AndorsTrailApplication.CURRENT_VERSION);
dest.writeUTF(playerName); dest.writeUTF(playerName);
dest.writeUTF(displayInfo); dest.writeUTF(displayInfo);
@@ -389,6 +397,7 @@ public final class Savegames {
dest.writeBoolean(hasUnlimitedSaves); dest.writeBoolean(hasUnlimitedSaves);
dest.writeUTF(playerId); dest.writeUTF(playerId);
dest.writeLong(savedVersion); dest.writeLong(savedVersion);
dest.writeUTF(saveName);
} }
} }
} }

View File

@@ -46,6 +46,13 @@
android:layout_marginTop="2dp" android:layout_marginTop="2dp"
android:layout_marginBottom="2dp" android:layout_marginBottom="2dp"
/> />
<EditText
android:id="@+id/save_name_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:layout_marginBottom="2dp"
/>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View File

@@ -13,6 +13,9 @@
<string name="loadsave_title_save">Save game</string> <string name="loadsave_title_save">Save game</string>
<string name="loadsave_title_load">Load saved game</string> <string name="loadsave_title_load">Load saved game</string>
<string name="loadsave_selectslot">Select slot</string> <string name="loadsave_selectslot">Select slot</string>
<string name="loadsave_save_name_empty">The entered name was empty</string>
<string name="loadsave_save_name_filled">Saving under name: \'%1$s\'</string>
<string name="loadsave_save_name_question">Input save name (or leave empty)</string>
<string name="savegame_currenthero_displayinfo">level %1$d, %2$d exp, %3$d gold</string> <string name="savegame_currenthero_displayinfo">level %1$d, %2$d exp, %3$d gold</string>
<string name="dialog_loading_message">Loading resources…</string> <string name="dialog_loading_message">Loading resources…</string>