Merge branch 'activate-spawnareas'

This commit is contained in:
Oskar Wiksten
2013-11-02 09:27:11 +01:00
10 changed files with 141 additions and 47 deletions

View File

@@ -1,4 +0,0 @@
gen
bin
.metadata
.git

View File

@@ -12,6 +12,10 @@ import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.model.conversation.*;
import com.gpl.rpg.AndorsTrail.model.item.ItemTypeCollection;
import com.gpl.rpg.AndorsTrail.model.item.Loot;
import com.gpl.rpg.AndorsTrail.model.map.LayeredTileMap;
import com.gpl.rpg.AndorsTrail.model.map.MapObject;
import com.gpl.rpg.AndorsTrail.model.map.MonsterSpawnArea;
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
import com.gpl.rpg.AndorsTrail.model.quest.QuestLogEntry;
import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress;
import com.gpl.rpg.AndorsTrail.model.script.Requirement;
@@ -53,7 +57,19 @@ public final class ConversationController {
final ScriptEffectResult result = new ScriptEffectResult();
for (ScriptEffect effect : phrase.scriptEffects) {
switch (effect.type) {
applyScriptEffect(player, effect, result);
}
if (result.isEmpty()) return null;
player.inventory.add(result.loot);
controllers.actorStatsController.addExperience(result.loot.exp);
return result;
}
private void applyScriptEffect(Player player, ScriptEffect effect, ScriptEffectResult result) {
switch (effect.type) {
case actorCondition:
addActorConditionReward(player, effect.effectID, effect.value, result);
break;
@@ -75,15 +91,59 @@ public final class ConversationController {
case createTimer:
world.model.worldData.createTimer(effect.effectID);
break;
}
case spawnAll:
spawnAll(effect.mapName, effect.effectID);
break;
case removeSpawnArea:
deactivateSpawnArea(effect.mapName, effect.effectID, true);
break;
case deactivateSpawnArea:
deactivateSpawnArea(effect.mapName, effect.effectID, false);
break;
case activateMapChangeArea:
activateMapChangeArea(effect.mapName, effect.effectID);
break;
case deactivateMapChangeArea:
deactivateMapChangeArea(effect.mapName, effect.effectID);
break;
}
}
if (result.isEmpty()) return null;
private void deactivateMapChangeArea(String mapName, String mapObjectID) {
PredefinedMap map = findMapForScriptEffect(mapName);
MapObject o = map.findEventObject(MapObject.MapObjectType.newmap, mapObjectID);
controllers.mapController.deactivateMapObject(o);
}
player.inventory.add(result.loot);
controllers.actorStatsController.addExperience(result.loot.exp);
private PredefinedMap findMapForScriptEffect(String mapName) {
if (mapName == null || mapName.length() == 0) return world.model.currentMap;
return world.maps.findPredefinedMap(mapName);
}
return result;
private void activateMapChangeArea(String mapName, String mapObjectID) {
PredefinedMap map = findMapForScriptEffect(mapName);
MapObject o = map.findEventObject(MapObject.MapObjectType.newmap, mapObjectID);
controllers.mapController.activateMapObject(map, o);
}
private void spawnAll(String mapName, String monsterTypeSpawnGroup) {
PredefinedMap map = findMapForScriptEffect(mapName);
LayeredTileMap tileMap = null;
if (map == world.model.currentMap) {
tileMap = world.model.currentTileMap;
}
for (MonsterSpawnArea area : map.spawnAreas) {
if (!area.monsterTypeSpawnGroup.equals(monsterTypeSpawnGroup)) continue;
controllers.monsterSpawnController.activateSpawnArea(map, tileMap, area, true);
}
}
private void deactivateSpawnArea(String mapName, String monsterTypeSpawnGroup, boolean removeAllMonsters) {
PredefinedMap map = findMapForScriptEffect(mapName);
for (MonsterSpawnArea area : map.spawnAreas) {
if (!area.monsterTypeSpawnGroup.equals(monsterTypeSpawnGroup)) continue;
controllers.monsterSpawnController.deactivateSpawnArea(area, removeAllMonsters);
}
}
private void addAlignmentReward(Player player, String faction, int delta) {

View File

@@ -78,16 +78,18 @@ 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) {
public void activateSpawnArea(PredefinedMap map, LayeredTileMap tileMap, MonsterSpawnArea spawnArea, boolean spawnAllMonsters) {
spawnArea.isSpawning = true;
if (spawnAllMonsters) {
boolean respawnUniqueMonsters = true;
spawnAllInArea(map, tileMap, spawnArea, respawnUniqueMonsters);
}
}
public void deactivateSpawnArea(MonsterSpawnArea spawnArea) {
spawnArea.isActive = false;
spawnArea.removeAllMonsters();
public void deactivateSpawnArea(MonsterSpawnArea spawnArea, boolean removeAllMonsters) {
spawnArea.isSpawning = false;
if (removeAllMonsters) {
spawnArea.removeAllMonsters();
}
}
}

View File

@@ -17,30 +17,33 @@ public final class MonsterSpawnArea {
public final CoordRect area;
public final Range quantity;
private final Range spawnChance;
public final String monsterTypeSpawnGroup;
public final String[] monsterTypeIDs;
public final ArrayList<Monster> monsters = new ArrayList<Monster>();
public final boolean isUnique; // unique == non-respawnable
public final String group;
public boolean isActive;
public final boolean isActiveForNewGame;
public boolean isSpawning;
public final boolean isSpawningForNewGame;
public MonsterSpawnArea(
CoordRect area
, Range quantity
, Range spawnChance
, String monsterTypeSpawnGroup
, String[] monsterTypeIDs
, boolean isUnique
, String group
, boolean isActiveForNewGame
, boolean isSpawningForNewGame
) {
this.area = area;
this.quantity = quantity;
this.spawnChance = spawnChance;
this.monsterTypeSpawnGroup = monsterTypeSpawnGroup;
this.monsterTypeIDs = monsterTypeIDs;
this.isUnique = isUnique;
this.group = group;
this.isActiveForNewGame = isActiveForNewGame;
this.isActive = isActiveForNewGame;
this.isSpawningForNewGame = isSpawningForNewGame;
this.isSpawning = isSpawningForNewGame;
}
public Monster getMonsterAt(final Coord p) { return getMonsterAt(p.x, p.y); }
@@ -88,8 +91,8 @@ public final class MonsterSpawnArea {
}
public boolean isSpawnable(boolean includeUniqueMonsters) {
if (!isSpawning) return false;
if (isUnique && !includeUniqueMonsters) return false;
if (!isActive) return false;
return quantity.current < quantity.max;
}
@@ -110,7 +113,7 @@ public final class MonsterSpawnArea {
public void resetForNewGame() {
removeAllMonsters();
isActive = isActiveForNewGame;
isSpawning = isSpawningForNewGame;
}
@@ -118,29 +121,19 @@ public final class MonsterSpawnArea {
public void readFromParcel(DataInputStream src, WorldContext world, int fileversion) throws IOException {
monsters.clear();
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));
}
isSpawning = isSpawningForNewGame;
if (fileversion >= 41) isSpawning = src.readBoolean();
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.writeBoolean(isActive);
if (isActive) {
dest.writeInt(monsters.size());
for (Monster m : monsters) {
m.writeToParcel(dest, flags);
}
dest.writeBoolean(isSpawning);
dest.writeInt(monsters.size());
for (Monster m : monsters) {
m.writeToParcel(dest, flags);
}
}
}

View File

@@ -70,7 +70,6 @@ public final class PredefinedMap {
public MapObject findEventObject(MapObject.MapObjectType objectType, String name) {
for (MapObject o : eventObjects) {
if (!o.isActive) continue;
if (o.type != objectType) continue;
if (!name.equals(o.id)) continue;
return o;
@@ -259,7 +258,7 @@ public final class PredefinedMap {
if (!groundBags.isEmpty()) return true;
for (MonsterSpawnArea a : spawnAreas) {
if (this.visited && a.isUnique) return true;
if (a.isActive != a.isActiveForNewGame) return true;
if (a.isSpawning != a.isSpawningForNewGame) return true;
}
for (MapObject o : eventObjects) {
if (o.isActive != o.isActiveForNewGame) return true;

View File

@@ -69,9 +69,15 @@ public final class TMXMapTranslator {
String map = null;
String place = null;
for (TMXProperty p : object.properties) {
if(p.name.equalsIgnoreCase("map")) map = p.value;
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 + "\".");
if (p.name.equalsIgnoreCase("map")) {
map = p.value;
} else if (p.name.equalsIgnoreCase("place")) {
place = p.value;
} else if (p.name.equalsIgnoreCase("active")) {
isActiveForNewGame = Boolean.parseBoolean(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, isActiveForNewGame));
} else if (object.type.equalsIgnoreCase("spawn")) {
@@ -89,6 +95,8 @@ public final class TMXMapTranslator {
maxQuantity = Integer.parseInt(p.value);
} else if (p.name.equalsIgnoreCase("spawnchance")) {
spawnChance = Integer.parseInt(p.value);
} else if (p.name.equalsIgnoreCase("active")) {
isActiveForNewGame = Boolean.parseBoolean(p.value);
} else if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) {
L.log("OPTIMIZE: Map " + m.name + ", spawn " + object.name + "@" + topLeft.toString() + " has unrecognized property \"" + p.name + "\".");
}
@@ -110,6 +118,7 @@ public final class TMXMapTranslator {
position
,new Range(maxQuantity, 0)
,new Range(1000, spawnChance)
,object.name
,monsterTypeIDs
,isUnique
,group.name

View File

@@ -9,19 +9,27 @@ public final class ScriptEffect {
, alignmentChange
, giveItem
, createTimer
, spawnAll
, removeSpawnArea
, deactivateSpawnArea
, activateMapChangeArea
, deactivateMapChangeArea
}
public final ScriptEffectType type;
public final String effectID;
public final int value;
public final String mapName;
public ScriptEffect(
ScriptEffectType type
, String effectID
, int value
, String mapName
) {
this.type = type;
this.effectID = effectID;
this.value = value;
this.mapName = mapName;
}
}

View File

@@ -48,6 +48,7 @@ public final class ConversationListParser extends JsonCollectionParserFor<Phrase
ScriptEffect.ScriptEffectType.valueOf(o.getString(JsonFieldNames.PhraseReward.rewardType))
,o.getString(JsonFieldNames.PhraseReward.rewardID)
,o.optInt(JsonFieldNames.PhraseReward.value, 0)
,o.optString(JsonFieldNames.PhraseReward.mapName, null)
);
}
};

View File

@@ -83,6 +83,7 @@ public final class JsonFieldNames {
public static final String rewardType = "rewardType";
public static final String rewardID = "rewardID";
public static final String value = "value";
public static final String mapName = "mapName";
}
public static final class Quest {

View File

@@ -37,8 +37,33 @@
<option value="alignmentChange">Alignment/faction change</option>
<option value="giveItem">Item</option>
<option value="createTimer">Create timer</option>
<option value="spawnAll">Spawn monsters</option>
<option value="removeSpawnArea">Remove monsters</option>
<option value="deactivateSpawnArea">Stop spawning</option>
<option value="activateMapChangeArea">Activate mapchange</option>
<option value="deactivateMapChangeArea">Deactivate mapchange</option>
</select>
</div>
<div ng-show="reward.rewardType=='spawnAll' || reward.rewardType=='removeSpawnArea' || reward.rewardType=='deactivateSpawnArea'">
<div class="fieldWithLabel">
<label for="mapName" >Map name:</label>
<input type="text" size="30" id="mapName" class="field at-input-id" ng-model="reward.mapName" />
</div>
<div class="fieldWithLabel">
<label for="rewardID" >Monster spawngroup:</label>
<input type="text" size="30" id="rewardID" class="field at-input-id" ng-model="reward.rewardID" />
</div>
</div>
<div ng-show="reward.rewardType=='activateMapChangeArea' || reward.rewardType=='deactivateMapChangeArea'">
<div class="fieldWithLabel">
<label for="mapName" >Map name:</label>
<input type="text" size="30" id="mapName" class="field at-input-id" ng-model="reward.mapName" />
</div>
<div class="fieldWithLabel">
<label for="rewardID" >Area name:</label>
<input type="text" size="30" id="rewardID" class="field at-input-id" ng-model="reward.rewardID" />
</div>
</div>
<div ng-show="reward.rewardType=='questProgress'">
<div class="fieldWithLabel">
<label for="rewardID" >Quest ID:</label>