Merge branch 'key_area_use_requirements'

This commit is contained in:
Oskar Wiksten
2013-10-03 08:26:26 +02:00
15 changed files with 264 additions and 77 deletions

View File

@@ -4,5 +4,6 @@
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@@ -123,5 +123,63 @@
{
"id": "debugrequireskey",
"message": "This tile requires a quest progress."
}
},
{
"id": "debugrequires10gold",
"replies": [
{
"text": "Too bad.",
"nextPhraseID": "X"
},
{
"text": "Well, gimme 10 gold then !",
"nextPhraseID": "debugrequires10gold_1"
}
],
"message": "This tile costs 10 gold !"
},
{
"id": "debugrequires10gold_1",
"replies": [
{
"requires": [
{
"requireType": "consumedMore",
"requireID": "gold",
"value": 100
}
],
"nextPhraseID": "debugrequires10gold_3"
},
{
"nextPhraseID": "debugrequires10gold_2"
}
]
},
{
"id": "debugrequires10gold_2",
"rewards": [
{
"rewardType": "dropList",
"rewardID": "debugrequires10gold_droplist"
}
],
"replies": [
{
"text": "When I come to debugmap, I always feel like a star.",
"nextPhraseID": "X"
}
],
"message": "Okay. But only because it's you M. Coder."
},
{
"id": "debugrequires10gold_3",
"replies": [
{
"text": "Damn.",
"nextPhraseID": "X"
}
],
"message": "Sorry. You already spent 100 gold..."
}
]

View File

@@ -161,5 +161,18 @@
"chance": 100
}
]
}
},
{
"id": "debugrequires10gold_droplist",
"items": [
{
"quantity": {
"min": 10,
"max": 10
},
"itemID": "gold",
"chance": 100
}
]
}
]

View File

@@ -1,125 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map SYSTEM "http://mapeditor.org/dtd/1.0/map.dtd">
<map version="1.0" orientation="orthogonal" width="10" height="10" tilewidth="32" tileheight="32">
<tileset firstgid="1" name="map_bed_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_bed_1.png"/>
<image source="../drawable/map_bed_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="129" name="map_border_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_border_1.png"/>
<image source="../drawable/map_border_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="257" name="map_bridge_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_bridge_1.png"/>
<image source="../drawable/map_bridge_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="385" name="map_broken_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_broken_1.png"/>
<image source="../drawable/map_broken_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="513" name="map_cavewall_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_cavewall_1.png"/>
<image source="../drawable/map_cavewall_1.png" width="576" height="192"/>
</tileset>
<tileset firstgid="621" name="map_cavewall_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_cavewall_2.png"/>
<image source="../drawable/map_cavewall_2.png" width="576" height="192"/>
</tileset>
<tileset firstgid="729" name="map_cavewall_3" tilewidth="32" tileheight="32">
<image source="../drawable/map_cavewall_3.png"/>
<image source="../drawable/map_cavewall_3.png" width="576" height="192"/>
</tileset>
<tileset firstgid="837" name="map_chair_table_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_chair_table_1.png"/>
<image source="../drawable/map_chair_table_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="965" name="map_crate_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_crate_1.png"/>
<image source="../drawable/map_crate_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1093" name="map_cupboard_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_cupboard_1.png"/>
<image source="../drawable/map_cupboard_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1221" name="map_curtain_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_curtain_1.png"/>
<image source="../drawable/map_curtain_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1349" name="map_entrance_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_entrance_1.png"/>
<image source="../drawable/map_entrance_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1477" name="map_fence_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_fence_1.png"/>
<image source="../drawable/map_fence_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1605" name="map_fence_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_fence_2.png"/>
<image source="../drawable/map_fence_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1733" name="map_ground_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_1.png"/>
<image source="../drawable/map_ground_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1861" name="map_ground_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_2.png"/>
<image source="../drawable/map_ground_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1989" name="map_ground_3" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_3.png"/>
<image source="../drawable/map_ground_3.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2117" name="map_ground_4" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_4.png"/>
<image source="../drawable/map_ground_4.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2245" name="map_ground_5" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_5.png"/>
<image source="../drawable/map_ground_5.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2373" name="map_ground_6" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_6.png"/>
<image source="../drawable/map_ground_6.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2501" name="map_ground_7" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_7.png"/>
<image source="../drawable/map_ground_7.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2629" name="map_ground_8" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_8.png"/>
<image source="../drawable/map_ground_8.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2757" name="map_indoor_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_indoor_1.png"/>
<image source="../drawable/map_indoor_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2885" name="map_kitchen_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_kitchen_1.png"/>
<image source="../drawable/map_kitchen_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3013" name="map_outdoor_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_outdoor_1.png"/>
<image source="../drawable/map_outdoor_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3141" name="map_pillar_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_pillar_1.png"/>
<image source="../drawable/map_pillar_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3269" name="map_plant_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_plant_1.png"/>
<image source="../drawable/map_plant_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3397" name="map_rock_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_rock_1.png"/>
<image source="../drawable/map_rock_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3525" name="map_roof_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_roof_1.png"/>
<image source="../drawable/map_roof_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3653" name="map_roof_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_roof_2.png"/>
<image source="../drawable/map_roof_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3781" name="map_shop_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_shop_1.png"/>
<image source="../drawable/map_shop_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3909" name="map_sign_ladder_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_sign_ladder_1.png"/>
<image source="../drawable/map_sign_ladder_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4037" name="map_table_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_table_1.png"/>
<image source="../drawable/map_table_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4165" name="map_trail_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_trail_1.png"/>
<image source="../drawable/map_trail_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4293" name="map_tree_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_tree_1.png"/>
<image source="../drawable/map_tree_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4421" name="map_wall_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_wall_1.png"/>
<image source="../drawable/map_wall_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4549" name="map_wall_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_wall_2.png"/>
<image source="../drawable/map_wall_2.png" width="480" height="256"/>
</tileset>
<tileset firstgid="4669" name="map_wall_3" tilewidth="32" tileheight="32">
<image source="../drawable/map_wall_3.png"/>
<image source="../drawable/map_wall_3.png" width="480" height="256"/>
</tileset>
<tileset firstgid="4789" name="map_window_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_window_1.png"/>
<image source="../drawable/map_window_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4917" name="map_window_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_window_2.png"/>
<image source="../drawable/map_window_2.png" width="512" height="256"/>
</tileset>
<layer name="Ground" width="10" height="10">
<data encoding="base64" compression="zlib">
@@ -144,14 +143,20 @@
<objectgroup name="Object Layer 1" width="10" height="10">
<object name="debugsign" type="sign" x="192" y="96" width="32" height="32"/>
<object name="start" type="rest" x="96" y="64" width="32" height="32"/>
<object name="no_quest:10" type="key" x="32" y="128" width="32" height="32">
<object name="Unopenable key area" type="key" x="32" y="128" width="32" height="32">
<properties>
<property name="phrase" value="debugrequireskey"/>
<property name="requireId" value="no_quest"/>
<property name="requireType" value="questProgress"/>
<property name="requireValue" value="10"/>
</properties>
</object>
<object name="debugquest:100" type="key" x="0" y="128" width="32" height="32">
<object name="Openable by quest" type="key" x="0" y="128" width="32" height="32">
<properties>
<property name="phrase" value="debugrequireskey"/>
<property name="requireId" value="debugquest"/>
<property name="requireType" value="questProgress"/>
<property name="requireValue" value="100"/>
</properties>
</object>
<object name="place2" type="mapchange" x="192" y="256" width="32" height="32">
@@ -167,6 +172,14 @@
</properties>
</object>
<object name="startitems" type="container" x="192" y="0" width="32" height="32"/>
<object name="Toll both. 10 gold." type="key" x="96" y="0" width="32" height="32">
<properties>
<property name="phrase" value="debugrequires10gold"/>
<property name="requireId" value="gold"/>
<property name="requireType" value="inventoryRemove"/>
<property name="requireValue" value="10"/>
</properties>
</object>
</objectgroup>
<objectgroup name="Spawn" width="10" height="10">
<object name="insect" type="spawn" x="96" y="128" width="192" height="160">

View File

@@ -4,6 +4,7 @@ import android.content.res.Resources;
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.GameStatistics;
import com.gpl.rpg.AndorsTrail.model.ability.*;
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
@@ -13,6 +14,7 @@ import com.gpl.rpg.AndorsTrail.model.item.ItemTypeCollection;
import com.gpl.rpg.AndorsTrail.model.item.Loot;
import com.gpl.rpg.AndorsTrail.model.quest.QuestLogEntry;
import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress;
import com.gpl.rpg.AndorsTrail.model.script.Requirement;
import com.gpl.rpg.AndorsTrail.util.ConstRange;
import com.gpl.rpg.AndorsTrail.util.L;
@@ -127,17 +129,11 @@ public final class ConversationController {
result.actorConditions.add(e);
}
private static void applyReplyEffect(final Player player, final Reply reply) {
private static void applyReplyEffect(final WorldContext world, final Reply reply) {
if (!reply.hasRequirements()) return;
for (Requirement requirement : reply.requires) {
if (requirement.requireType == Requirement.RequirementType.inventoryRemove) {
if (ItemTypeCollection.isGoldItemType(requirement.requireID)) {
player.inventory.gold -= requirement.value;
} else {
player.inventory.removeItem(requirement.requireID, requirement.value);
}
}
requirementFulfilled(world, requirement);
}
}
@@ -145,18 +141,21 @@ public final class ConversationController {
if (!reply.hasRequirements()) return true;
for (Requirement requirement : reply.requires) {
if (!playerSatisfiesRequirement(world, requirement)) return false;
if (!canFulfillRequirement(world, requirement)) return false;
}
return true;
}
private static boolean playerSatisfiesRequirement(final WorldContext world, final Requirement requirement) {
public static boolean canFulfillRequirement(WorldContext world, Requirement requirement) {
Player player = world.model.player;
GameStatistics stats = world.model.statistics;
switch (requirement.requireType) {
case questProgress:
return player.hasExactQuestProgress(requirement.requireID, requirement.value);
case questLatestProgress:
return player.isLatestQuestProgress(requirement.requireID, requirement.value);
case wear:
return player.inventory.isWearing(requirement.requireID);
return player.inventory.isWearing(requirement.requireID, requirement.value);
case inventoryKeep:
case inventoryRemove:
if (ItemTypeCollection.isGoldItemType(requirement.requireID)) {
@@ -167,14 +166,33 @@ public final class ConversationController {
case skillLevel:
return player.getSkillLevel(SkillCollection.SkillID.valueOf(requirement.requireID)) >= requirement.value;
case killedMonster:
return world.model.statistics.getNumberOfKillsForMonsterType(requirement.requireID) >= requirement.value;
return stats.getNumberOfKillsForMonsterType(requirement.requireID) >= requirement.value;
case timerElapsed:
return world.model.worldData.hasTimerElapsed(requirement.requireID, requirement.value);
case usedItem:
return stats.getNumberOfTimesItemHasBeenUsed(requirement.requireID) >= requirement.value;
case spentGold:
return stats.getSpentGold() >= requirement.value;
case consumedBonemeals:
return stats.getNumberOfUsedBonemealPotions() >= requirement.value;
default:
return true;
}
}
public static void requirementFulfilled(WorldContext world, Requirement requirement) {
Player p = world.model.player;
switch (requirement.requireType) {
case inventoryRemove:
if (ItemTypeCollection.isGoldItemType(requirement.requireID)) {
p.inventory.gold -= requirement.value;
world.model.statistics.addGoldSpent(requirement.value);
} else {
p.inventory.removeItem(requirement.requireID, requirement.value);
}
}
}
private static String getDisplayMessage(Phrase phrase, Player player) { return replacePlayerName(phrase.message, player); }
private static String getDisplayMessage(Reply reply, Player player) { return replacePlayerName(reply.text, player); }
private static String replacePlayerName(String s, Player player) {
@@ -203,7 +221,7 @@ public final class ConversationController {
public String getCurrentPhraseID() { return phraseID; }
public void playerSelectedReply(final Resources res, Reply r) {
applyReplyEffect(player, r);
applyReplyEffect(world, r);
proceedToPhrase(res, r.nextPhrase, true, true);
}
@@ -260,7 +278,7 @@ public final class ConversationController {
if (currentPhrase.message == null) {
for (Reply r : currentPhrase.replies) {
if (!canSelectReply(world, r)) continue;
applyReplyEffect(player, r);
applyReplyEffect(world, r);
proceedToPhrase(res, r.nextPhrase, giveRewards, displayPhraseMessage);
return;
}

View File

@@ -144,7 +144,10 @@ public final class MapController {
}
public boolean canEnterKeyArea(MapObject area) {
if (world.model.player.hasExactQuestProgress(area.requireQuestProgress)) return true;
if (ConversationController.canFulfillRequirement(world, area.enteringRequirement)) {
ConversationController.requirementFulfilled(world, area.enteringRequirement);
return true;
}
worldEventListeners.onPlayerSteppedOnKeyArea(area);
return false;
}

View File

@@ -118,6 +118,11 @@ public final class GameStatistics {
return result;
}
public int getNumberOfTimesItemHasBeenUsed(String itemId) {
if (!usedItems.containsKey(itemId)) return 0;
return usedItems.get(itemId);
}
public int getNumberOfKilledMonsters() {
int result = 0;
for (int v : killedMonsters.values()) result += v;

View File

@@ -140,6 +140,14 @@ public final class Player extends Actor {
public boolean hasAnyQuestProgress(String questID) {
return questProgress.containsKey(questID);
}
public boolean isLatestQuestProgress(String questID, int progress) {
if (!questProgress.containsKey(questID)) return false;
if (!questProgress.get(questID).contains(progress)) return false;
for (int i : questProgress.get(questID)) {
if (i > progress) return false;
}
return true;
}
public boolean addQuestProgress(QuestProgress progress) {
if (hasExactQuestProgress(progress.questID, progress.progress)) return false;
if (!questProgress.containsKey(progress.questID)) questProgress.put(progress.questID, new HashSet<Integer>());

View File

@@ -1,5 +1,7 @@
package com.gpl.rpg.AndorsTrail.model.conversation;
import com.gpl.rpg.AndorsTrail.model.script.Requirement;
public final class Reply {
public final String text;
public final String nextPhrase;

View File

@@ -64,6 +64,15 @@ public final class Inventory extends ItemContainer {
return false;
}
public boolean isWearing(String itemTypeID, int minNumber) {
if (minNumber == 0) return isWearing(itemTypeID);
for(int i = 0; i < NUM_WORN_SLOTS; ++i) {
if (wear[i] == null) continue;
if (wear[i].id.equals(itemTypeID)) minNumber--;
}
return minNumber <= 0;
}
public static boolean isArmorSlot(WearSlot slot) {
if (slot == null) return false;
switch (slot) {

View File

@@ -1,7 +1,7 @@
package com.gpl.rpg.AndorsTrail.model.map;
import com.gpl.rpg.AndorsTrail.model.item.DropList;
import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress;
import com.gpl.rpg.AndorsTrail.model.script.Requirement;
import com.gpl.rpg.AndorsTrail.util.CoordRect;
public final class MapObject {
@@ -26,7 +26,7 @@ public final class MapObject {
public final String id; //placeName on this map or phraseID
public final String map;
public final String place;
public final QuestProgress requireQuestProgress;
public final Requirement enteringRequirement;
public final DropList dropList;
public final MapObjectEvaluationType evaluateWhen;
@@ -36,7 +36,7 @@ public final class MapObject {
, final String id
, final String map
, final String place
, final QuestProgress requireQuestProgress
, final Requirement enteringRequirement
, final DropList dropList
, final MapObjectEvaluationType evaluateWhen
) {
@@ -45,7 +45,7 @@ public final class MapObject {
this.id = id;
this.map = map;
this.place = place;
this.requireQuestProgress = requireQuestProgress;
this.enteringRequirement = enteringRequirement;
this.dropList = dropList;
this.evaluateWhen = evaluateWhen;
}
@@ -59,8 +59,8 @@ public final class MapObject {
public static MapObject createRestArea(final CoordRect position, final String placeId) {
return new MapObject(position, MapObjectType.rest, placeId, null, null, null, null, MapObjectEvaluationType.whenEntering);
}
public static MapObject createKeyArea(final CoordRect position, final String phraseID, final QuestProgress requireQuestStage) {
return new MapObject(position, MapObjectType.keyarea, phraseID, null, null, requireQuestStage, null, MapObjectEvaluationType.whenEntering);
public static MapObject createKeyArea(final CoordRect position, final String phraseID, final Requirement enteringRequirement) {
return new MapObject(position, MapObjectType.keyarea, phraseID, null, null, enteringRequirement, null, MapObjectEvaluationType.whenEntering);
}
public static MapObject createContainerArea(final CoordRect position, final DropList dropList) {
return new MapObject(position, MapObjectType.container, null, null, null, null, dropList, MapObjectEvaluationType.whenEntering);

View File

@@ -8,6 +8,9 @@ import com.gpl.rpg.AndorsTrail.model.item.DropList;
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.*;
@@ -113,23 +116,24 @@ public final class TMXMapTranslator {
);
spawnAreas.add(area);
} else if (object.type.equalsIgnoreCase("key")) {
QuestProgress requireQuestStage = QuestProgress.parseQuestProgress(object.name);
if (requireQuestStage == null) {
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) {
L.log("OPTIMIZE: Map " + m.name + " contains key area at " + topLeft.toString() + " that cannot be parsed as a quest stage.");
}
continue;
}
Requirement.RequirementType requireType = Requirement.RequirementType.questProgress;
String requireId = null;
int requireValue = 1;
String phraseID = "";
for (TMXProperty p : object.properties) {
if (p.name.equalsIgnoreCase("phrase")) {
phraseID = p.value;
} else if (p.name.equalsIgnoreCase("requireType")) {
requireType = Requirement.RequirementType.valueOf(p.value);
} else if (p.name.equalsIgnoreCase("requireId")) {
requireId = p.value;
} else if (p.name.equalsIgnoreCase("requireValue")) {
requireValue = Integer.parseInt(p.value);
} else if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) {
L.log("OPTIMIZE: Map " + m.name + ", key " + object.name + "@" + topLeft.toString() + " has unrecognized property \"" + p.name + "\".");
}
}
mapObjects.add(MapObject.createKeyArea(position, phraseID, requireQuestStage));
mapObjects.add(MapObject.createKeyArea(position, phraseID, new Requirement(requireType, requireId, requireValue)));
} else if (object.type.equals("rest")) {
mapObjects.add(MapObject.createRestArea(position, object.name));
} else if (object.type.equals("container")) {

View File

@@ -1,14 +1,18 @@
package com.gpl.rpg.AndorsTrail.model.conversation;
package com.gpl.rpg.AndorsTrail.model.script;
public final class Requirement {
public static enum RequirementType {
questProgress
,questLatestProgress // Highest quest stage reached must match.
,inventoryRemove // Player must have item(s) in inventory. Items will be removed when selecting reply.
,inventoryKeep // Player must have item(s) in inventory. Items will NOT be removed when selecting reply.
,wear // Player must be wearing item(s). Items will NOT be removed when selecting reply.
,skillLevel // Player needs to have a specific skill equal to or above a certain level
,killedMonster
,timerElapsed
,usedItem
,spentGold
,consumedBonemeals
}
public final RequirementType requireType;
@@ -20,4 +24,13 @@ public final class Requirement {
this.requireID = requireID;
this.value = value;
}
public String toString() {
StringBuffer buf = new StringBuffer(requireType.toString());
buf.append("--");
buf.append(requireID);
buf.append("--");
buf.append(value);
return buf.toString();
}
}

View File

@@ -3,8 +3,8 @@ package com.gpl.rpg.AndorsTrail.resource.parsers;
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
import com.gpl.rpg.AndorsTrail.model.conversation.Phrase;
import com.gpl.rpg.AndorsTrail.model.conversation.Reply;
import com.gpl.rpg.AndorsTrail.model.conversation.Requirement;
import com.gpl.rpg.AndorsTrail.model.conversation.Reward;
import com.gpl.rpg.AndorsTrail.model.script.Requirement;
import com.gpl.rpg.AndorsTrail.resource.TranslationLoader;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonArrayParserFor;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor;

View File

@@ -186,12 +186,16 @@
<label for="requireType">Require:</label>
<select class="field" id="requireType" ng-model="require.requireType">
<option value="questProgress">Quest progress</option>
<option value="questLatestProgress">Exact quest progress</option>
<option value="inventoryRemove">Inventory &amp; item will be removed</option>
<option value="inventoryKeep">Inventory</option>
<option value="wear">Worn equipment</option>
<option value="skillLevel">Skill level</option>
<option value="killedMonster">Killed monster</option>
<option value="timerElapsed">Timer elapsed</option>
<option value="usedItem">Used items (greater or equals)</option>
<option value="spentGold">Gold spent (greater or equals)/option>
<option value="consumedBonemeals">Bonemeals consumed (greater or equals)</option>
</select>
</div>
<div ng-show="require.requireType=='questProgress'">
@@ -204,6 +208,16 @@
<input type="text" size="3" id="requirevalue" class="field at-input-quantity" ng-model="require.value" />
</div>
</div>
<div ng-show="require.requireType=='questLatestProgress'">
<div class="fieldWithLabel">
<label for="requireID" >Quest ID:</label>
<input type="text" size="30" id="requireID" class="field at-input-id" ng-model="require.requireID" />
</div>
<div class="fieldWithLabel">
<label for="requirevalue">Stage:</label>
<input type="text" size="3" id="requirevalue" class="field at-input-quantity" ng-model="require.value" />
</div>
</div>
<div ng-show="require.requireType=='inventoryRemove'">
<div class="fieldWithLabel">
<label for="requireID" >Item ID:</label>
@@ -229,6 +243,10 @@
<label for="requireID" >Item ID:</label>
<input type="text" size="30" id="requireID" class="field at-input-id" ng-model="require.requireID" />
</div>
<div class="fieldWithLabel">
<label for="requirevalue">Quantity (optional):</label>
<input type="text" size="3" id="requirevalue" class="field at-input-quantity" ng-model="require.value" />
</div>
</div>
<div ng-show="require.requireType=='skillLevel'">
<div class="fieldWithLabel">
@@ -260,6 +278,28 @@
<input type="text" size="3" id="requirevalue" class="field at-input-quantity" ng-model="require.value" />
</div>
</div>
<div ng-show="require.requireType=='usedItem'">
<div class="fieldWithLabel">
<label for="requireID" >Item ID:</label>
<input type="text" size="30" id="requireID" class="field at-input-id" ng-model="require.requireID" />
</div>
<div class="fieldWithLabel">
<label for="requirevalue">Quantity:</label>
<input type="text" size="3" id="requirevalue" class="field at-input-quantity" ng-model="require.value" />
</div>
</div>
<div ng-show="require.requireType=='spentGold'">
<div class="fieldWithLabel">
<label for="requirevalue">Quantity:</label>
<input type="text" size="3" id="requirevalue" class="field at-input-quantity" ng-model="require.value" />
</div>
</div>
<div ng-show="require.requireType=='consumedBonemeals'">
<div class="fieldWithLabel">
<label for="requirevalue">Quantity:</label>
<input type="text" size="3" id="requirevalue" class="field at-input-quantity" ng-model="require.value" />
</div>
</div>
<button ng-click="removeRequirement(reply, require)" class="btn pull-right" title="Remove requirement"><i class="icon-trash"></i> Remove requirement</button>
<div class="clearfix"></div>
</div>