Save 'isActive' for MapObjects & SpawnArea in savegames

* Stores the "isActive" boolean in savegames for map objects and spawn areas
* Adds functions in MapController to activate and deactivate MapObject areas
* Adds functions in MonsterSpawnController to activate and deactivate MonsterSpawnAreas
* When a spawn area is deactivated, all monsters should be removed, since the spawn area is considered to be non-existant.
* Adds boolean "isActiveForNewGame" to map objects and spawn areas, that specify what "isActive" should be set to when starting a game. (Initially, all of these are true)
* This commit does not add any way to actually activate or deactive areas. That can come as a later commit (possibly using script effects to do that).
This commit is contained in:
Oskar Wiksten
2013-10-27 09:15:52 +01:00
parent c001532106
commit 20ed608523
7 changed files with 93 additions and 30 deletions

View File

@@ -21,7 +21,7 @@ public final class AndorsTrailApplication extends Application {
public static final boolean DEVELOPMENT_VALIDATEDATA = true;
public static final boolean DEVELOPMENT_DEBUGMESSAGES = true;
public static final boolean DEVELOPMENT_INCOMPATIBLE_SAVEGAMES = DEVELOPMENT_DEBUGRESOURCES || DEVELOPMENT_DEBUGBUTTONS || true;
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? 999 : 40;
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? 999 : 41;
public static final String CURRENT_VERSION_DISPLAY = "0.7.1dev";
public static final boolean IS_RELEASE_VERSION = !CURRENT_VERSION_DISPLAY.matches(".*[a-d].*");

View File

@@ -1,7 +1,5 @@
package com.gpl.rpg.AndorsTrail.controller;
import java.util.List;
import android.content.res.Resources;
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
@@ -18,6 +16,8 @@ import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
import com.gpl.rpg.AndorsTrail.model.map.ReplaceableMapSection;
import com.gpl.rpg.AndorsTrail.util.Coord;
import java.util.List;
public final class MapController {
private final ControllerContext controllers;
@@ -212,4 +212,14 @@ public final class MapController {
public void prepareScriptsOnCurrentMap() {
mapScriptExecutor = new ConversationController.ConversationStatemachine(world, controllers, conversationStateListener);
}
public void activateMapObject(PredefinedMap map, MapObject o) {
if (o.isActive) return;
o.isActive = true;
if (o.type == MapObject.MapObjectType.container) map.createContainerLoot(o);
}
public void deactivateMapObject(MapObject o) {
o.isActive = false;
}
}

View File

@@ -78,4 +78,16 @@ public final class MonsterSpawningController {
monsterSpawnListeners.onMonsterRemoved(map, m, m.rectPosition);
}
public void activateSpawnArea(PredefinedMap map, LayeredTileMap tileMap, MonsterSpawnArea spawnArea, boolean spawnAll) {
spawnArea.isActive = true;
if (spawnAll) {
boolean respawnUniqueMonsters = true;
spawnAllInArea(map, tileMap, spawnArea, respawnUniqueMonsters);
}
}
public void deactivateSpawnArea(MonsterSpawnArea spawnArea) {
spawnArea.isActive = false;
spawnArea.removeAllMonsters();
}
}

View File

@@ -30,7 +30,8 @@ public final class MapObject {
public final Requirement enteringRequirement;
public final DropList dropList;
public final MapObjectEvaluationType evaluateWhen;
public boolean isActive = true;
public boolean isActive;
public final boolean isActiveForNewGame;
private MapObject(
final CoordRect position
@@ -42,6 +43,7 @@ public final class MapObject {
, final DropList dropList
, final MapObjectEvaluationType evaluateWhen
, final String group
, final boolean isActiveForNewGame
) {
this.position = new CoordRect(position);
this.type = type;
@@ -52,14 +54,21 @@ public final class MapObject {
this.dropList = dropList;
this.evaluateWhen = evaluateWhen;
this.group = group;
this.isActiveForNewGame = isActiveForNewGame;
this.isActive = isActiveForNewGame;
}
public void resetForNewGame() {
isActive = isActiveForNewGame;
}
public static MapObject createMapSignEvent(
final CoordRect position
, final String phraseID
, String group
, boolean isActiveForNewGame
) {
return new MapObject(position, MapObjectType.sign, phraseID, null, null, null, null, MapObjectEvaluationType.whenEntering, group);
return new MapObject(position, MapObjectType.sign, phraseID, null, null, null, null, MapObjectEvaluationType.whenEntering, group, isActiveForNewGame);
}
public static MapObject createMapChangeArea(
@@ -68,16 +77,18 @@ public final class MapObject {
, final String destinationMap
, final String destinationPlace
, String group
, boolean isActiveForNewGame
) {
return new MapObject(position, MapObjectType.newmap, thisMapTitle, destinationMap, destinationPlace, null, null, MapObjectEvaluationType.whenEntering, group);
return new MapObject(position, MapObjectType.newmap, thisMapTitle, destinationMap, destinationPlace, null, null, MapObjectEvaluationType.whenEntering, group, isActiveForNewGame);
}
public static MapObject createRestArea(
final CoordRect position
, final String placeId
, String group
, boolean isActiveForNewGame
) {
return new MapObject(position, MapObjectType.rest, placeId, null, null, null, null, MapObjectEvaluationType.whenEntering, group);
return new MapObject(position, MapObjectType.rest, placeId, null, null, null, null, MapObjectEvaluationType.whenEntering, group, isActiveForNewGame);
}
public static MapObject createKeyArea(
@@ -85,16 +96,18 @@ public final class MapObject {
, final String phraseID
, final Requirement enteringRequirement
, String group
, boolean isActiveForNewGame
) {
return new MapObject(position, MapObjectType.keyarea, phraseID, null, null, enteringRequirement, null, MapObjectEvaluationType.whenEntering, group);
return new MapObject(position, MapObjectType.keyarea, phraseID, null, null, enteringRequirement, null, MapObjectEvaluationType.whenEntering, group, isActiveForNewGame);
}
public static MapObject createContainerArea(
final CoordRect position
, final DropList dropList
, String group
, boolean isActiveForNewGame
) {
return new MapObject(position, MapObjectType.container, null, null, null, null, dropList, MapObjectEvaluationType.whenEntering, group);
return new MapObject(position, MapObjectType.container, null, null, null, null, dropList, MapObjectEvaluationType.whenEntering, group, isActiveForNewGame);
}
public static MapObject createScriptArea(
@@ -102,7 +115,8 @@ public final class MapObject {
, final String phraseID
, final MapObjectEvaluationType evaluateWhen
, String group
, boolean isActiveForNewGame
) {
return new MapObject(position, MapObjectType.script, phraseID, null, null, null, null, evaluateWhen, group);
return new MapObject(position, MapObjectType.script, phraseID, null, null, null, null, evaluateWhen, group, isActiveForNewGame);
}
}

View File

@@ -21,7 +21,8 @@ public final class MonsterSpawnArea {
public final ArrayList<Monster> monsters = new ArrayList<Monster>();
public final boolean isUnique; // unique == non-respawnable
public final String group;
public boolean isActive = true;
public boolean isActive;
public final boolean isActiveForNewGame;
public MonsterSpawnArea(
CoordRect area
@@ -30,6 +31,7 @@ public final class MonsterSpawnArea {
, String[] monsterTypeIDs
, boolean isUnique
, String group
, boolean isActiveForNewGame
) {
this.area = area;
this.quantity = quantity;
@@ -37,6 +39,8 @@ public final class MonsterSpawnArea {
this.monsterTypeIDs = monsterTypeIDs;
this.isUnique = isUnique;
this.group = group;
this.isActiveForNewGame = isActiveForNewGame;
this.isActive = isActiveForNewGame;
}
public Monster getMonsterAt(final Coord p) { return getMonsterAt(p.x, p.y); }
@@ -106,6 +110,7 @@ public final class MonsterSpawnArea {
public void resetForNewGame() {
removeAllMonsters();
isActive = isActiveForNewGame;
}
@@ -113,16 +118,29 @@ public final class MonsterSpawnArea {
public void readFromParcel(DataInputStream src, WorldContext world, int fileversion) throws IOException {
monsters.clear();
quantity.current = src.readInt();
for(int i = 0; i < quantity.current; ++i) {
monsters.add(Monster.readFromParcel(src, world, fileversion));
boolean shouldReadListOfMonsters;
if (fileversion >= 41) {
isActive = src.readBoolean();
shouldReadListOfMonsters = isActive;
} else {
isActive = isActiveForNewGame;
shouldReadListOfMonsters = true;
}
if (shouldReadListOfMonsters) {
quantity.current = src.readInt();
for(int i = 0; i < quantity.current; ++i) {
monsters.add(Monster.readFromParcel(src, world, fileversion));
}
}
}
public void writeToParcel(DataOutputStream dest, int flags) throws IOException {
dest.writeInt(monsters.size());
for (Monster m : monsters) {
m.writeToParcel(dest, flags);
dest.writeBoolean(isActive);
if (isActive) {
dest.writeInt(monsters.size());
for (Monster m : monsters) {
m.writeToParcel(dest, flags);
}
}
}
}

View File

@@ -154,6 +154,9 @@ public final class PredefinedMap {
for (MonsterSpawnArea a : spawnAreas) {
a.resetForNewGame();
}
for (MapObject o : eventObjects) {
o.resetForNewGame();
}
resetTemporaryData();
groundBags.clear();
visited = false;
@@ -184,21 +187,27 @@ public final class PredefinedMap {
if (!groundBags.isEmpty()) return true;
for (MonsterSpawnArea a : spawnAreas) {
if (a.isUnique) return true;
if (a.isActive != a.isActiveForNewGame) return true;
}
for (MapObject o : eventObjects) {
if (o.isActive != o.isActiveForNewGame) return true;
}
return false;
}
public void createAllContainerLoot() {
for (MapObject o : eventObjects) {
//TODO : Don't forget to create loot on container activation once implemented
if (!o.isActive) continue;
if (o.type == MapObject.MapObjectType.container) {
Loot bag = getBagOrCreateAt(o.position.topLeft);
o.dropList.createRandomLoot(bag, null);
}
if (o.type != MapObject.MapObjectType.container) continue;
createContainerLoot(o);
}
}
public void createContainerLoot(MapObject container) {
Loot bag = getBagOrCreateAt(container.position.topLeft);
container.dropList.createRandomLoot(bag, null);
}
// ====== PARCELABLE ===================================================================

View File

@@ -9,8 +9,6 @@ import com.gpl.rpg.AndorsTrail.model.item.DropListCollection;
import com.gpl.rpg.AndorsTrail.model.map.TMXMapFileParser.*;
import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress;
import com.gpl.rpg.AndorsTrail.model.script.Requirement;
import com.gpl.rpg.AndorsTrail.model.script.Requirement.RequirementType;
import com.gpl.rpg.AndorsTrail.resource.parsers.ResourceParserUtils;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileCache;
import com.gpl.rpg.AndorsTrail.util.*;
@@ -56,6 +54,7 @@ public final class TMXMapTranslator {
for (TMXObject object : group.objects) {
final CoordRect position = getTMXObjectPosition(object, m);
final Coord topLeft = position.topLeft;
boolean isActiveForNewGame = true;
if (object.type == null) {
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA)
@@ -65,7 +64,7 @@ public final class TMXMapTranslator {
for (TMXProperty p : object.properties) {
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) L.log("OPTIMIZE: Map " + m.name + ", sign " + object.name + "@" + topLeft.toString() + " has unrecognized property \"" + p.name + "\".");
}
mapObjects.add(MapObject.createMapSignEvent(position, phraseID, group.name));
mapObjects.add(MapObject.createMapSignEvent(position, phraseID, group.name, isActiveForNewGame));
} else if (object.type.equalsIgnoreCase("mapchange")) {
String map = null;
String place = null;
@@ -74,7 +73,7 @@ public final class TMXMapTranslator {
else if(p.name.equalsIgnoreCase("place")) place = p.value;
else if(AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) L.log("OPTIMIZE: Map " + m.name + ", mapchange " + object.name + "@" + topLeft.toString() + " has unrecognized property \"" + p.name + "\".");
}
mapObjects.add(MapObject.createMapChangeArea(position, object.name, map, place, group.name));
mapObjects.add(MapObject.createMapChangeArea(position, object.name, map, place, group.name, isActiveForNewGame));
} else if (object.type.equalsIgnoreCase("spawn")) {
ArrayList<MonsterType> types = monsterTypes.getMonsterTypesFromSpawnGroup(object.name);
int maxQuantity = 1;
@@ -114,6 +113,7 @@ public final class TMXMapTranslator {
,monsterTypeIDs
,isUnique
,group.name
,isActiveForNewGame
);
spawnAreas.add(area);
} else if (object.type.equalsIgnoreCase("key")) {
@@ -137,13 +137,13 @@ public final class TMXMapTranslator {
L.log("OPTIMIZE: Map " + m.name + ", key " + object.name + "@" + topLeft.toString() + " has unrecognized property \"" + p.name + "\".");
}
}
mapObjects.add(MapObject.createKeyArea(position, phraseID, new Requirement(requireType, requireId, requireValue, requireNegation), group.name));
mapObjects.add(MapObject.createKeyArea(position, phraseID, new Requirement(requireType, requireId, requireValue, requireNegation), group.name, isActiveForNewGame));
} else if (object.type.equals("rest")) {
mapObjects.add(MapObject.createRestArea(position, object.name, group.name));
mapObjects.add(MapObject.createRestArea(position, object.name, group.name, isActiveForNewGame));
} else if (object.type.equals("container")) {
DropList dropList = dropLists.getDropList(object.name);
if (dropList == null) continue;
mapObjects.add(MapObject.createContainerArea(position, dropList, group.name));
mapObjects.add(MapObject.createContainerArea(position, dropList, group.name, isActiveForNewGame));
} else if (object.type.equals("replace")) {
// Do nothing. Will be handled when reading map layers instead.
} else if (object.type.equalsIgnoreCase("script")) {
@@ -166,7 +166,7 @@ public final class TMXMapTranslator {
L.log("OPTIMIZE: Map " + m.name + ", script " + object.name + "@" + topLeft.toString() + " has unrecognized property \"" + p.name + "\".");
}
}
mapObjects.add(MapObject.createScriptArea(position, phraseID, evaluateWhen, group.name));
mapObjects.add(MapObject.createScriptArea(position, phraseID, evaluateWhen, group.name, isActiveForNewGame));
} else if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) {
L.log("OPTIMIZE: Map " + m.name + ", has unrecognized object type \"" + object.type + "\" for name \"" + object.name + "\".");
}