Merge pull request #77 from AndorsTrailRelease/master_tmp20241119
Master tmp20241119
@@ -3,8 +3,8 @@
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.gpl.rpg.AndorsTrail"
|
||||
android:versionCode="77"
|
||||
android:versionName="0.8.11"
|
||||
android:versionCode="78"
|
||||
android:versionName="0.8.12"
|
||||
android:installLocation="auto"
|
||||
>
|
||||
|
||||
|
||||
@@ -28,11 +28,11 @@ public final class AndorsTrailApplication extends Application {
|
||||
public static final boolean DEVELOPMENT_FASTSPEED = false;
|
||||
public static final boolean DEVELOPMENT_VALIDATEDATA = false;
|
||||
public static final boolean DEVELOPMENT_DEBUGMESSAGES = false;
|
||||
public static final String CURRENT_VERSION_DISPLAY = "0.8.11";
|
||||
public static final String CURRENT_VERSION_DISPLAY = "0.8.12";
|
||||
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 int DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION = 999;
|
||||
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 77;
|
||||
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 78;
|
||||
|
||||
private final AndorsTrailPreferences preferences = new AndorsTrailPreferences();
|
||||
private WorldContext world = new WorldContext();
|
||||
|
||||
@@ -152,6 +152,12 @@ public final class DebugInterface {
|
||||
public void onClick(View arg0) {
|
||||
showToast(mainActivity, "DEBUG: map=" + world.model.currentMaps.map.name , Toast.LENGTH_SHORT);
|
||||
}
|
||||
})
|
||||
,new DebugButton("tim", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
world.model.worldData.tickWorldTime(10);
|
||||
}
|
||||
})
|
||||
}));
|
||||
|
||||
@@ -313,6 +319,13 @@ public final class DebugInterface {
|
||||
}
|
||||
})
|
||||
|
||||
,new DebugButton("wx", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "wexlow_village", "north", 0, 0);
|
||||
}
|
||||
})
|
||||
|
||||
,new DebugButton("fey", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
@@ -345,14 +358,14 @@ public final class DebugInterface {
|
||||
,new DebugButton("#1", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "waterway11_east", "west", 0, 0);
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "swamp3", "north", 0, 0);
|
||||
}
|
||||
})
|
||||
|
||||
,new DebugButton("#2", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "laerothtomb1", "north", 0, 0);
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "beekeeper1", "south", 0, 0);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -360,7 +373,7 @@ public final class DebugInterface {
|
||||
,new DebugButton("#3", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "mountainlake8", "north", 0, 0);
|
||||
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "guynmart", "west2", 0, 0);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ public final class SkillInfoActivity extends AndorsTrailBaseActivity {
|
||||
case armorProficiencyShield: return res.getString(R.string.skill_longdescription_armor_prof_shield, SkillCollection.PER_SKILLPOINT_INCREASE_SHIELD_PROF_DR);
|
||||
case armorProficiencyUnarmored: return res.getString(R.string.skill_longdescription_armor_prof_unarmored, SkillCollection.PER_SKILLPOINT_INCREASE_UNARMORED_BC);
|
||||
case armorProficiencyLight: return res.getString(R.string.skill_longdescription_armor_prof_light, SkillCollection.PER_SKILLPOINT_INCREASE_LIGHT_ARMOR_BC_PERCENT);
|
||||
case armorProficiencyHeavy: return res.getString(R.string.skill_longdescription_armor_prof_heavy, SkillCollection.PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_BC_PERCENT, SkillCollection.PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_MOVECOST_PERCENT, SkillCollection.PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_ATKCOST_PERCENT);
|
||||
case armorProficiencyHeavy: return res.getString(R.string.skill_longdescription_armor_prof_heavy, SkillCollection.PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_BC_PERCENT, SkillCollection.PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_MOVECOST_PERCENT, SkillCollection.PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_ATKCOST_PERCENT, SkillCollection.PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_USECOST_PERCENT);
|
||||
case fightstyleDualWield: return res.getString(R.string.skill_longdescription_fightstyle_dualwield, SkillCollection.DUALWIELD_EFFICIENCY_LEVEL0, SkillCollection.DUALWIELD_EFFICIENCY_LEVEL1, SkillCollection.DUALWIELD_LEVEL1_OFFHAND_AP_COST_PERCENT, SkillCollection.DUALWIELD_EFFICIENCY_LEVEL2);
|
||||
case fightstyle2hand: return res.getString(R.string.skill_longdescription_fightstyle_2hand, SkillCollection.PER_SKILLPOINT_INCREASE_FIGHTSTYLE_2HAND_DMG_PERCENT);
|
||||
case fightstyleWeaponShield: return res.getString(R.string.skill_longdescription_fightstyle_weapon_shield, SkillCollection.PER_SKILLPOINT_INCREASE_FIGHTSTYLE_WEAPON_AC_PERCENT, SkillCollection.PER_SKILLPOINT_INCREASE_FIGHTSTYLE_SHIELD_BC_PERCENT);
|
||||
|
||||
@@ -76,8 +76,7 @@ public final class ActorStatsController {
|
||||
c.magnitude -= magnitude;
|
||||
actorConditionListeners.onActorConditionMagnitudeChanged(actor, c);
|
||||
} else {
|
||||
actor.conditions.remove(i);
|
||||
actorConditionListeners.onActorConditionRemoved(actor, c);
|
||||
actorConditionsRemove(actor, c, i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -232,9 +231,9 @@ public final class ActorStatsController {
|
||||
public void removeAllTemporaryConditions(final Actor actor) {
|
||||
for(int i = actor.conditions.size() - 1; i >= 0; --i) {
|
||||
ActorCondition c = actor.conditions.get(i);
|
||||
if (!c.isTemporaryEffect()) continue;
|
||||
actor.conditions.remove(i);
|
||||
actorConditionListeners.onActorConditionRemoved(actor, c);
|
||||
if (c.isTemporaryEffect() || c.isDurationForeverUntilSleep()) {
|
||||
actorConditionsRemove(actor, c, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,8 +241,7 @@ public final class ActorStatsController {
|
||||
for(int i = actor.conditions.size() - 1; i >= 0; --i) {
|
||||
ActorCondition c = actor.conditions.get(i);
|
||||
if (!c.conditionType.conditionTypeID.equals(conditionTypeID)) continue;
|
||||
actor.conditions.remove(i);
|
||||
actorConditionListeners.onActorConditionRemoved(actor, c);
|
||||
actorConditionsRemove(actor, c, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,14 +404,14 @@ public final class ActorStatsController {
|
||||
ActorCondition c = actor.conditions.get(i);
|
||||
if (!c.isTemporaryEffect()) continue;
|
||||
if (c.duration <= 1) {
|
||||
actor.conditions.remove(i);
|
||||
actorConditionListeners.onActorConditionRemoved(actor, c);
|
||||
actorConditionsRemove(actor, c, i);
|
||||
removedAnyConditions = true;
|
||||
} else {
|
||||
c.duration -= 1;
|
||||
actorConditionListeners.onActorConditionDurationChanged(actor, c);
|
||||
}
|
||||
}
|
||||
// Immunities
|
||||
for(int i = actor.immunities.size() - 1; i >= 0; --i) {
|
||||
ActorCondition c = actor.immunities.get(i);
|
||||
if (!c.isTemporaryEffect()) continue;
|
||||
@@ -457,6 +455,50 @@ public final class ActorStatsController {
|
||||
}
|
||||
}
|
||||
|
||||
int actorConditionsRemove(Actor actor, ActorCondition c, int i) {
|
||||
int magnitude = 0; //default: No condition from worn items
|
||||
|
||||
if (actor instanceof Player) {
|
||||
Player player = (Player) actor;
|
||||
magnitude = gotConditionFromWornItem(player, c);
|
||||
if (magnitude > 0) { //condition from worn items?
|
||||
c.magnitude = magnitude; // -> readd condition
|
||||
actorConditionListeners.onActorConditionMagnitudeChanged(actor, c);
|
||||
c.duration = ActorCondition.DURATION_FOREVER;
|
||||
actorConditionListeners.onActorConditionDurationChanged(actor, c);
|
||||
}
|
||||
}
|
||||
if (magnitude == 0) {
|
||||
actor.conditions.remove(i);
|
||||
actorConditionListeners.onActorConditionRemoved(actor, c);
|
||||
}
|
||||
|
||||
return magnitude;
|
||||
}
|
||||
|
||||
int gotConditionFromWornItem(Player player, ActorCondition c) {
|
||||
int magnitude = 0; //Default: No worn item with this condition
|
||||
|
||||
for (Inventory.WearSlot slot : Inventory.WearSlot.values()) {
|
||||
ItemType t = player.inventory.getItemTypeInWearSlot(slot);
|
||||
if (t == null) continue;
|
||||
ItemTraits_OnEquip equipEffects = t.effects_equip;
|
||||
if (equipEffects == null) continue;
|
||||
if (equipEffects.addedConditions == null) continue;
|
||||
for (ActorConditionEffect e : equipEffects.addedConditions) {
|
||||
if (e.conditionType.conditionTypeID.equals(c.conditionType.conditionTypeID)) {
|
||||
if (e.magnitude == ActorCondition.MAGNITUDE_REMOVE_ALL) {
|
||||
return 0; //On an item-based immunity the result is always 0
|
||||
}
|
||||
if (magnitude < e.magnitude) {
|
||||
magnitude = e.magnitude;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return magnitude;
|
||||
}
|
||||
|
||||
public void applyUseEffect(Actor source, Actor target, ItemTraits_OnUse effect) {
|
||||
if (effect == null) return;
|
||||
|
||||
|
||||
@@ -250,7 +250,8 @@ public final class CombatController implements VisualEffectCompletedCallback {
|
||||
if (!loot.hasItemsOrGold()) {
|
||||
world.model.currentMaps.map.removeGroundLoot(loot);
|
||||
} else if (world.model.uiSelections.isInCombat) {
|
||||
killedMonsterBags.add(loot);
|
||||
if(!killedMonsterBags.contains(loot))
|
||||
killedMonsterBags.add(loot);
|
||||
}
|
||||
|
||||
combatActionListeners.onPlayerKilledMonster(killedMonster);
|
||||
|
||||
@@ -253,6 +253,7 @@ public final class SkillController {
|
||||
addPercentBlockChance(player, itemType, SkillCollection.PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_BC_PERCENT * skillLevelHeavyArmor, 0);
|
||||
playerTraits.moveCost -= getPercentage(itemType.effects_equip.stats.increaseMoveCost, SkillCollection.PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_MOVECOST_PERCENT * skillLevelHeavyArmor, 0);
|
||||
playerTraits.attackCost -= getPercentage(itemType.effects_equip.stats.increaseAttackCost, SkillCollection.PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_ATKCOST_PERCENT * skillLevelHeavyArmor, 0);
|
||||
playerTraits.useItemCost -= getPercentage(itemType.effects_equip.stats.increaseUseItemCost, SkillCollection.PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_USECOST_PERCENT * skillLevelHeavyArmor, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,23 @@ import com.gpl.rpg.AndorsTrail.util.Coord;
|
||||
import com.gpl.rpg.AndorsTrail.util.CoordRect;
|
||||
import com.gpl.rpg.AndorsTrail.util.Size;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class VisualEffectController {
|
||||
private static final long EFFECT_UPDATE_INTERVAL = 25;
|
||||
private int effectCount = 0;
|
||||
|
||||
private final ControllerContext controllers;
|
||||
private final WorldContext world;
|
||||
private final VisualEffectCollection effectTypes;
|
||||
private final Handler animationHandler = new Handler();
|
||||
private final List<VisualEffectAnimation> activeAnimations = new ArrayList<>();
|
||||
|
||||
public final VisualEffectFrameListeners visualEffectFrameListeners = new VisualEffectFrameListeners();
|
||||
private long getEffectUpdateInterval() {
|
||||
return EFFECT_UPDATE_INTERVAL * controllers.preferences.attackspeed_milliseconds / AndorsTrailPreferences.ATTACKSPEED_DEFAULT_MILLISECONDS;
|
||||
}
|
||||
|
||||
public VisualEffectController(ControllerContext controllers, WorldContext world) {
|
||||
this.controllers = controllers;
|
||||
@@ -38,10 +47,42 @@ public final class VisualEffectController {
|
||||
|
||||
public void startEffect(Coord position, VisualEffectCollection.VisualEffectID effectID, String displayValue, VisualEffectCompletedCallback callback, int callbackValue) {
|
||||
++effectCount;
|
||||
(new VisualEffectAnimation(effectTypes.getVisualEffect(effectID), position, displayValue, callback, callbackValue))
|
||||
.start();
|
||||
VisualEffectAnimation animation = new VisualEffectAnimation(effectTypes.getVisualEffect(effectID), position, displayValue, callback, callbackValue);
|
||||
animation.start();
|
||||
}
|
||||
|
||||
private void startAnimation(VisualEffectAnimation animation) {
|
||||
activeAnimations.add(animation);
|
||||
animation.update();
|
||||
if (activeAnimations.size() == 1) {
|
||||
animationHandler.postDelayed(animationRunnable, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private final Runnable animationRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(!activeAnimations.isEmpty()) {
|
||||
long updateInterval = getEffectUpdateInterval();
|
||||
animationHandler.postDelayed(this, updateInterval);
|
||||
|
||||
for (int i = 0; i < activeAnimations.size(); i++) {
|
||||
VisualEffectAnimation animation = activeAnimations.get(i);
|
||||
animation.durationPassed += updateInterval;
|
||||
animation.updateFrame();
|
||||
animation.update();
|
||||
if (controllers.preferences.attackspeed_milliseconds <= 0 || animation.currentFrame >= animation.effect.lastFrame) {
|
||||
animation.onCompleted();
|
||||
activeAnimations.remove(i);
|
||||
effectCount--;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
visualEffectFrameListeners.onNewAnimationFrames(activeAnimations);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private VisualEffectCollection.VisualEffectID enqueuedEffectID = null;
|
||||
private int enqueuedEffectValue = 0;
|
||||
public void enqueueEffect(VisualEffectCollection.VisualEffectID effectID, int displayValue) {
|
||||
@@ -65,10 +106,9 @@ public final class VisualEffectController {
|
||||
.start();
|
||||
}
|
||||
|
||||
public final class SpriteMoveAnimation extends Handler implements Runnable {
|
||||
|
||||
// private static final int millisecondsPerFrame=25;
|
||||
|
||||
public final class SpriteMoveAnimation implements Runnable {
|
||||
private final Handler handler = new Handler();
|
||||
|
||||
private final VisualEffectCompletedCallback callback;
|
||||
private final int callbackValue;
|
||||
|
||||
@@ -82,11 +122,6 @@ public final class VisualEffectController {
|
||||
@Override
|
||||
public void run() {
|
||||
onCompleted();
|
||||
// update();
|
||||
// if (System.currentTimeMillis() - actor.vfxStartTime >= duration) {
|
||||
// } else {
|
||||
// postDelayed(this, millisecondsPerFrame);
|
||||
// }
|
||||
}
|
||||
|
||||
public SpriteMoveAnimation(Coord origin, Coord destination, int duration, Actor actor, PredefinedMap map, VisualEffectCompletedCallback callback, int callbackValue) {
|
||||
@@ -99,11 +134,6 @@ public final class VisualEffectController {
|
||||
this.destination = destination;
|
||||
|
||||
}
|
||||
|
||||
// private void update() {
|
||||
//
|
||||
// visualEffectFrameListeners.onNewSpriteMoveFrame(this);
|
||||
// }
|
||||
|
||||
private void onCompleted() {
|
||||
--effectCount;
|
||||
@@ -111,7 +141,6 @@ public final class VisualEffectController {
|
||||
if (callback != null) callback.onVisualEffectCompleted(callbackValue);
|
||||
visualEffectFrameListeners.onSpriteMoveCompleted(this);
|
||||
}
|
||||
|
||||
|
||||
public void start() {
|
||||
actor.hasVFXRunning = true;
|
||||
@@ -120,12 +149,9 @@ public final class VisualEffectController {
|
||||
visualEffectFrameListeners.onSpriteMoveStarted(this);
|
||||
if (duration == 0 || !controllers.preferences.enableUiAnimations) onCompleted();
|
||||
else {
|
||||
postDelayed(this, duration);
|
||||
handler.postDelayed(this, duration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static final Paint textPaint = new Paint();
|
||||
@@ -134,41 +160,42 @@ public final class VisualEffectController {
|
||||
textPaint.setAlpha(255);
|
||||
textPaint.setTextAlign(Align.CENTER);
|
||||
}
|
||||
|
||||
public final class VisualEffectAnimation extends Handler implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentFrame >= effect.lastFrame) {
|
||||
onCompleted();
|
||||
} else {
|
||||
postDelayed(this, effect.millisecondPerFrame * controllers.preferences.attackspeed_milliseconds / AndorsTrailPreferences.ATTACKSPEED_DEFAULT_MILLISECONDS);
|
||||
update();
|
||||
public final class VisualEffectAnimation {
|
||||
public int tileID;
|
||||
public int textYOffset;
|
||||
public long durationPassed = 0;
|
||||
|
||||
private void updateFrame() {
|
||||
long frameDuration = (long) effect.millisecondPerFrame * controllers.preferences.attackspeed_milliseconds / AndorsTrailPreferences.ATTACKSPEED_DEFAULT_MILLISECONDS;
|
||||
while (frameDuration > 0 && durationPassed > frameDuration) {
|
||||
currentFrame++;
|
||||
durationPassed -= frameDuration;
|
||||
}
|
||||
}
|
||||
|
||||
private void update() {
|
||||
++currentFrame;
|
||||
int frame = currentFrame;
|
||||
|
||||
int tileID = effect.frameIconIDs[frame];
|
||||
int textYOffset = -2 * (frame);
|
||||
if (frame >= beginFadeAtFrame && displayText != null) {
|
||||
textPaint.setAlpha(255 * (effect.lastFrame - frame) / (effect.lastFrame - beginFadeAtFrame));
|
||||
if (currentFrame >= effect.lastFrame) {
|
||||
return;
|
||||
}
|
||||
|
||||
tileID = effect.frameIconIDs[currentFrame];
|
||||
textYOffset = -2 * (currentFrame);
|
||||
|
||||
if (currentFrame >= beginFadeAtFrame && displayText != null) {
|
||||
textPaint.setAlpha(255 * (effect.lastFrame - currentFrame) / (effect.lastFrame - beginFadeAtFrame));
|
||||
}
|
||||
|
||||
area.topLeft.y = position.y - 1;
|
||||
visualEffectFrameListeners.onNewAnimationFrame(this, tileID, textYOffset);
|
||||
}
|
||||
|
||||
private void onCompleted() {
|
||||
--effectCount;
|
||||
visualEffectFrameListeners.onAnimationCompleted(this);
|
||||
if (callback != null) callback.onVisualEffectCompleted(callbackValue);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (!controllers.preferences.enableUiAnimations) onCompleted();
|
||||
else postDelayed(this, 0);
|
||||
else startAnimation(this);
|
||||
}
|
||||
|
||||
private int currentFrame = 0;
|
||||
@@ -197,7 +224,7 @@ public final class VisualEffectController {
|
||||
this.area = new CoordRect(new Coord(position.x - (widthNeededInTiles / 2), position.y - 1), new Size(widthNeededInTiles, 2));
|
||||
this.beginFadeAtFrame = effect.lastFrame / 2;
|
||||
}
|
||||
|
||||
|
||||
public Paint getTextPaint(){
|
||||
return textPaint;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.LayeredTileMap;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.MapLayer;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.TMXMapTranslator;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment.NamedWorldMapArea;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment.WorldMapSegmentMap;
|
||||
@@ -314,4 +315,32 @@ public final class WorldMapController {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void populateWorldMap(Context context, WorldContext world, Resources res) throws IOException {
|
||||
ensureWorldmapDirectoryExists(context);
|
||||
File dir = getWorldmapDirectory(context);
|
||||
|
||||
File idFile = new File(dir, world.model.player.id);
|
||||
if (idFile.exists()) return;
|
||||
idFile.createNewFile();
|
||||
|
||||
for (PredefinedMap map : world.maps.getAllMaps()) {
|
||||
if (!map.visited) continue;
|
||||
|
||||
String worldMapSegmentName = world.maps.getWorldMapSegmentNameForMap(map.name);
|
||||
if (worldMapSegmentName == null) continue;
|
||||
|
||||
boolean mapFileExists = fileForMapExists(context, map);
|
||||
File worldMapFile = getCombinedWorldMapFile(context, worldMapSegmentName);
|
||||
if (mapFileExists && worldMapFile.exists()) continue;
|
||||
|
||||
LayeredTileMap mapTiles = TMXMapTranslator.readLayeredTileMap(res, world.tileManager.tileCache, map);
|
||||
mapTiles.changeColorFilter(map.currentColorFilter);
|
||||
TileCollection cachedTiles = world.tileManager.loadTilesFor(map, mapTiles, world, res);
|
||||
|
||||
MapRenderer renderer = new MapRenderer(world, map, mapTiles, cachedTiles);
|
||||
updateCachedBitmap(context, map, renderer);
|
||||
updateWorldMapSegment(context, res, world, worldMapSegmentName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@ import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.SpriteMoveAnima
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.util.CoordRect;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface VisualEffectFrameListener {
|
||||
void onNewAnimationFrame(VisualEffectAnimation animation, int tileID, int textYOffset);
|
||||
void onNewAnimationFrames(List<VisualEffectAnimation> effects);
|
||||
void onAnimationCompleted(VisualEffectAnimation animation);
|
||||
void onSpriteMoveStarted(SpriteMoveAnimation animation);
|
||||
void onNewSpriteMoveFrame(SpriteMoveAnimation animation);
|
||||
|
||||
@@ -5,10 +5,12 @@ import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAni
|
||||
import com.gpl.rpg.AndorsTrail.util.CoordRect;
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class VisualEffectFrameListeners extends ListOfListeners<VisualEffectFrameListener> implements VisualEffectFrameListener {
|
||||
|
||||
private final Function3<VisualEffectFrameListener, VisualEffectAnimation, Integer, Integer> onNewAnimationFrame = new Function3<VisualEffectFrameListener, VisualEffectAnimation, Integer, Integer>() {
|
||||
@Override public void call(VisualEffectFrameListener listener, VisualEffectAnimation animation, Integer tileID, Integer textYOffset) { listener.onNewAnimationFrame(animation, tileID, textYOffset); }
|
||||
private final Function1<VisualEffectFrameListener, List<VisualEffectAnimation>> onNewAnimationFrames = new Function1<VisualEffectFrameListener, List<VisualEffectAnimation>>() {
|
||||
@Override public void call(VisualEffectFrameListener listener, List<VisualEffectAnimation> effects) { listener.onNewAnimationFrames(effects); }
|
||||
};
|
||||
|
||||
private final Function1<VisualEffectFrameListener, VisualEffectAnimation> onAnimationCompleted = new Function1<VisualEffectFrameListener, VisualEffectAnimation>() {
|
||||
@@ -30,10 +32,10 @@ public final class VisualEffectFrameListeners extends ListOfListeners<VisualEffe
|
||||
private final Function1<VisualEffectFrameListener, CoordRect> onAsyncAreaUpdate = new Function1<VisualEffectFrameListener, CoordRect>() {
|
||||
@Override public void call(VisualEffectFrameListener listener, CoordRect area) { listener.onAsyncAreaUpdate(area); }
|
||||
};
|
||||
|
||||
|
||||
@Override
|
||||
public void onNewAnimationFrame(VisualEffectAnimation animation, int tileID, int textYOffset) {
|
||||
callAllListeners(this.onNewAnimationFrame, animation, tileID, textYOffset);
|
||||
public void onNewAnimationFrames(List<VisualEffectAnimation> effects) {
|
||||
callAllListeners(this.onNewAnimationFrames, effects);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
public final class ActorCondition {
|
||||
public static final int MAGNITUDE_REMOVE_ALL = -99;
|
||||
public static final int DURATION_FOREVER = 999;
|
||||
public static final int DURATION_FOREVER_UNTIL_SLEEP = 998;
|
||||
public static final int DURATION_NONE = 0;
|
||||
|
||||
public final ActorConditionType conditionType;
|
||||
@@ -27,7 +28,12 @@ public final class ActorCondition {
|
||||
|
||||
public boolean isTemporaryEffect() { return isTemporaryEffect(duration); }
|
||||
public static boolean isTemporaryEffect(int duration) {
|
||||
return duration != DURATION_FOREVER;
|
||||
return ( duration != DURATION_FOREVER && duration != DURATION_FOREVER_UNTIL_SLEEP );
|
||||
}
|
||||
|
||||
public boolean isDurationForeverUntilSleep() { return isDurationForeverUntilSleep(duration); }
|
||||
public static boolean isDurationForeverUntilSleep(int duration) {
|
||||
return ( duration == DURATION_FOREVER_UNTIL_SLEEP );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@ public final class SkillCollection {
|
||||
public static final int PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_BC_PERCENT = 20;
|
||||
public static final int PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_MOVECOST_PERCENT = 25;
|
||||
public static final int PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_ATKCOST_PERCENT = 25;
|
||||
public static final int PER_SKILLPOINT_INCREASE_HEAVY_ARMOR_USECOST_PERCENT = 25;
|
||||
public static final int PER_SKILLPOINT_INCREASE_FIGHTSTYLE_2HAND_DMG_PERCENT = 30;
|
||||
public static final int PER_SKILLPOINT_INCREASE_SPECIALIZATION_2HAND_DMG_PERCENT = 50;
|
||||
public static final int PER_SKILLPOINT_INCREASE_SPECIALIZATION_2HAND_AC_PERCENT = 20;
|
||||
|
||||
@@ -256,9 +256,11 @@ public final class ResourceLoader {
|
||||
final Size sz2x2 = new Size(2, 2);
|
||||
final Size sz2x3 = new Size(2, 3);
|
||||
final Size sz3x1 = new Size(3, 1);
|
||||
final Size sz4x1 = new Size(4, 1);
|
||||
final Size sz5x1 = new Size(5, 1);
|
||||
final Size sz6x1 = new Size(6, 1);
|
||||
final Size sz7x1 = new Size(7, 1);
|
||||
final Size sz7x4 = new Size(7, 4);
|
||||
final Size sz8x3 = new Size(8, 3);
|
||||
final Size sz16x8 = new Size(16, 8);
|
||||
final Size sz20x12 = new Size(20, 12);
|
||||
@@ -321,7 +323,7 @@ public final class ResourceLoader {
|
||||
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_dogs, "monsters_dogs", sz7x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_dogs, "monsters_dogs", sz7x4, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_eye1, "monsters_eye1", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_eye2, "monsters_eye2", sz1x1, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.monsters_eye3, "monsters_eye3", sz1x1, sz1x1, mTileSize);
|
||||
@@ -383,10 +385,11 @@ public final class ResourceLoader {
|
||||
/*INSERT_NPCS_TILESETS_HERE*/
|
||||
|
||||
loader.prepareTileset(R.drawable.map_bed_1, "map_bed_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_boats_1, "map_boats_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_boats_1, "map_boats_1", new Size(16, 9), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_border_1, "map_border_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_bridge_1, "map_bridge_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_bridge_2, "map_bridge_2", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_brightport, "map_brightport", new Size(16, 7), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_broken_1, "map_broken_1", mapTileSize, sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_cavewall_1, "map_cavewall_1", new Size(18, 6), sz1x1, mTileSize);
|
||||
loader.prepareTileset(R.drawable.map_cavewall_2, "map_cavewall_2", new Size(18, 6), sz1x1, mTileSize);
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.xmlpull.v1.XmlPullParserException;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.XmlResourceParser;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.MapCollection;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment.NamedWorldMapArea;
|
||||
@@ -24,11 +25,13 @@ public final class WorldMapParser {
|
||||
}
|
||||
|
||||
private static void read(XmlResourceParser xrp, final MapCollection maps, final TranslationLoader translationLoader) {
|
||||
String s = "";
|
||||
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) L.log("WorldMapParser:");
|
||||
try {
|
||||
int eventType;
|
||||
while ((eventType = xrp.next()) != XmlResourceParser.END_DOCUMENT) {
|
||||
if (eventType == XmlResourceParser.START_TAG) {
|
||||
String s = xrp.getName();
|
||||
s = xrp.getName();
|
||||
if (s.equals("segment")) {
|
||||
WorldMapSegment segment = parseSegment(xrp, maps, translationLoader);
|
||||
maps.worldMapSegments.put(segment.name, segment);
|
||||
@@ -37,7 +40,7 @@ public final class WorldMapParser {
|
||||
}
|
||||
xrp.close();
|
||||
} catch (Exception e) {
|
||||
L.log("Error reading worldmap: " + e.toString());
|
||||
L.log("Error reading worldmap: " + s + " " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +49,13 @@ public final class WorldMapParser {
|
||||
final WorldMapSegment segment = new WorldMapSegment(segmentName);
|
||||
|
||||
final ArrayList<Pair<String, String>> mapsInNamedAreas = new ArrayList<Pair<String,String>>();
|
||||
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) L.log("segment: " + segmentName);
|
||||
XmlResourceParserUtils.readCurrentTagUntilEnd(xrp, new XmlResourceParserUtils.TagHandler() {
|
||||
@Override
|
||||
public void handleTag(XmlResourceParser xrp, String tagName) throws XmlPullParserException, IOException {
|
||||
if (tagName.equals("map")) {
|
||||
String mapName = xrp.getAttributeValue(null, "id");
|
||||
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) L.log(" map: " + mapName);
|
||||
if (maps.findPredefinedMap(mapName) == null) return;
|
||||
Coord mapPosition = new Coord(
|
||||
xrp.getAttributeIntValue(null, "x", -1),
|
||||
@@ -65,6 +70,7 @@ public final class WorldMapParser {
|
||||
String id = xrp.getAttributeValue(null, "id");
|
||||
String name = translationLoader.translateWorldmapLocation(xrp.getAttributeValue(null, "name"));
|
||||
String type = xrp.getAttributeValue(null, "type");
|
||||
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) L.log(" namedarea: id=" + id + " name=" + name + " type=" + type);
|
||||
segment.namedAreas.put(id, new NamedWorldMapArea(id, name, type));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,14 +76,17 @@ public final class TileCache {
|
||||
ResourceFileTile tile = resourceTiles[tileID];
|
||||
if(tile == null && AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES){
|
||||
L.log("could not find resourceTiles for id: " + tileID);
|
||||
L.log("iconIDs: " + iconIDs);
|
||||
}
|
||||
SparseArray<ResourceFileTile> tiles = tilesToLoadPerSourceFile.get(tile.tileset);
|
||||
if (tiles == null) {
|
||||
tiles = new SparseArray<TileCache.ResourceFileTile>();
|
||||
tilesToLoadPerSourceFile.put(tile.tileset, tiles);
|
||||
if(tile != null || AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA){
|
||||
SparseArray<ResourceFileTile> tiles = tilesToLoadPerSourceFile.get(tile.tileset);
|
||||
if (tiles == null) {
|
||||
tiles = new SparseArray<TileCache.ResourceFileTile>();
|
||||
tilesToLoadPerSourceFile.put(tile.tileset, tiles);
|
||||
}
|
||||
tiles.put(tileID, tile);
|
||||
maxTileID = Math.max(maxTileID, tileID);
|
||||
}
|
||||
tiles.put(tileID, tile);
|
||||
maxTileID = Math.max(maxTileID, tileID);
|
||||
}
|
||||
|
||||
boolean hasLoadedTiles = false;
|
||||
|
||||
@@ -27,6 +27,7 @@ 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.controller.WorldMapController;
|
||||
import com.gpl.rpg.AndorsTrail.model.ModelContainer;
|
||||
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
|
||||
import com.gpl.rpg.AndorsTrail.util.AndroidStorage;
|
||||
@@ -104,7 +105,7 @@ public final class Savegames {
|
||||
}
|
||||
|
||||
FileInputStream fos = getInputFile(androidContext, slot);
|
||||
LoadSavegameResult result = loadWorld(androidContext.getResources(), world, controllers, fos, fh);
|
||||
LoadSavegameResult result = loadWorld(androidContext.getResources(), world, controllers, androidContext, fos, fh);
|
||||
fos.close();
|
||||
if (result == LoadSavegameResult.success && slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
|
||||
// save to the quicksave slot before deleting the file
|
||||
@@ -223,7 +224,7 @@ public final class Savegames {
|
||||
dest.close();
|
||||
}
|
||||
|
||||
public static LoadSavegameResult loadWorld(Resources res, WorldContext world, ControllerContext controllers, InputStream inState, FileHeader fh) throws IOException {
|
||||
public static LoadSavegameResult loadWorld(Resources res, WorldContext world, ControllerContext controllers, Context androidContext, 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)
|
||||
@@ -231,6 +232,7 @@ public final class Savegames {
|
||||
|
||||
world.maps.readFromParcel(src, world, controllers, header.fileversion);
|
||||
world.model = new ModelContainer(src, world, controllers, header.fileversion);
|
||||
WorldMapController.populateWorldMap(androidContext, world, controllers.getResources());
|
||||
src.close();
|
||||
|
||||
if (header.fileversion < 45) {
|
||||
|
||||
@@ -30,6 +30,18 @@ public final class CoordRect {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static CoordRect union(CoordRect r1, CoordRect r2) {
|
||||
int left = Math.min(r1.topLeft.x, r2.topLeft.x);
|
||||
int top = Math.min(r1.topLeft.y, r2.topLeft.y);
|
||||
int right = Math.max(r1.topLeft.x + r1.size.width, r2.topLeft.x + r2.size.width);
|
||||
int bottom = Math.max(r1.topLeft.y + r1.size.height, r2.topLeft.y + r2.size.height);
|
||||
|
||||
int width = right - left;
|
||||
int height = bottom - top;
|
||||
|
||||
return new CoordRect(new Coord(left, top), new Size(width, height));
|
||||
}
|
||||
|
||||
/*
|
||||
public static boolean contains(final int x, final int y, final Size size, final Coord p) {
|
||||
if (p.x < x) return false;
|
||||
|
||||
@@ -292,6 +292,8 @@ public final class DisplayActiveActorConditionIcons implements ActorConditionLis
|
||||
}
|
||||
if (condition.duration == ActorCondition.DURATION_FOREVER || condition.duration == ActorCondition.DURATION_NONE) {
|
||||
duration = "\u221e";
|
||||
} else if (condition.duration == ActorCondition.DURATION_FOREVER_UNTIL_SLEEP) {
|
||||
duration = "";
|
||||
} else {
|
||||
duration = Integer.toString(condition.duration);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.gpl.rpg.AndorsTrail.view;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences;
|
||||
@@ -158,8 +159,8 @@ public final class MainView extends SurfaceView
|
||||
// this.surfaceSize = new Size(w, h);
|
||||
this.surfaceSize = new Size((int) (getWidth() / scale), (int) (getHeight() / scale));
|
||||
this.screenSizeTileCount = new Size(
|
||||
(int) Math.floor(getWidth() / scaledTileSize)
|
||||
,(int) Math.floor(getHeight() / scaledTileSize)
|
||||
getWidth() / scaledTileSize
|
||||
,getHeight() / scaledTileSize
|
||||
);
|
||||
|
||||
if (sh.getSurfaceFrame().right != surfaceSize.width || sh.getSurfaceFrame().bottom != surfaceSize.height) {
|
||||
@@ -226,28 +227,28 @@ public final class MainView extends SurfaceView
|
||||
if (scrolling && why != RedrawAllDebugReason.MapScrolling) return;
|
||||
if (!scrolling && movingSprites > 0 && why != RedrawAllDebugReason.SpriteMoved) return;
|
||||
}
|
||||
redrawArea_(mapViewArea, null, 0, 0);
|
||||
redrawArea_(mapViewArea, null);
|
||||
}
|
||||
private void redrawTile(final Coord p, RedrawTileDebugReason why) {
|
||||
if (scrolling) return;
|
||||
p1x1.topLeft.set(p);
|
||||
redrawArea_(p1x1, null, 0, 0);
|
||||
redrawArea_(p1x1, null);
|
||||
}
|
||||
private void redrawArea(final CoordRect area, RedrawAreaDebugReason why) {
|
||||
if (scrolling) return;
|
||||
redrawArea_(area, null, 0, 0);
|
||||
redrawArea_(area, null);
|
||||
}
|
||||
private void redrawArea_(CoordRect area, final VisualEffectAnimation effect, int tileID, int textYOffset) {
|
||||
private void redrawArea_(CoordRect area, final List<VisualEffectAnimation> effects) {
|
||||
if (!hasSurface) return;
|
||||
|
||||
|
||||
|
||||
if (!currentMap.intersects(area)) return;
|
||||
if (!mapViewArea.intersects(area)) return;
|
||||
|
||||
if (shouldRedrawEverything()) {
|
||||
area = mapViewArea;
|
||||
}
|
||||
|
||||
|
||||
calculateRedrawRect(area);
|
||||
redrawRect.intersect(redrawClip);
|
||||
Canvas c = null;
|
||||
@@ -263,7 +264,7 @@ public final class MainView extends SurfaceView
|
||||
if (area == mapViewArea) {
|
||||
area = adaptAreaToScrolling(area);
|
||||
}
|
||||
|
||||
|
||||
synchronized (holder) { synchronized (tiles) {
|
||||
int xScroll = 0;
|
||||
int yScroll = 0;
|
||||
@@ -275,32 +276,25 @@ public final class MainView extends SurfaceView
|
||||
}
|
||||
c.clipRect(redrawClip);
|
||||
c.translate(screenOffset.x + xScroll, screenOffset.y + yScroll);
|
||||
// c.scale(scale, scale);
|
||||
doDrawRect(c, area);
|
||||
if (effect != null) {
|
||||
drawFromMapPosition(c, area, effect.position, tileID);
|
||||
if (effect.displayText != null) {
|
||||
drawEffectText(c, area, effect, textYOffset, effect.getTextPaint());
|
||||
}
|
||||
}
|
||||
|
||||
// c.drawRect(new Rect(
|
||||
// (area.topLeft.x - mapViewArea.topLeft.x) * tileSize,
|
||||
// (area.topLeft.y - mapViewArea.topLeft.y) * tileSize,
|
||||
// (area.topLeft.x - mapViewArea.topLeft.x + area.size.width) * tileSize - 1,
|
||||
// (area.topLeft.y - mapViewArea.topLeft.y + area.size.height) * tileSize - 1),
|
||||
// redrawHighlight);
|
||||
// if (touchedTile != null) c.drawRect(new Rect(
|
||||
// (touchedTile.x - mapViewArea.topLeft.x) * tileSize,
|
||||
// (touchedTile.y - mapViewArea.topLeft.y) * tileSize,
|
||||
// (touchedTile.x - mapViewArea.topLeft.x + 1) * tileSize - 1,
|
||||
// (touchedTile.y - mapViewArea.topLeft.y + 1) * tileSize - 1),
|
||||
// touchHighlight);
|
||||
renderEffects(c, effects);
|
||||
} }
|
||||
} finally {
|
||||
if (c != null) holder.unlockCanvasAndPost(c);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderEffects(Canvas canvas ,List<VisualEffectAnimation> effects) {
|
||||
if(effects == null) return;
|
||||
for (VisualEffectAnimation effect : effects) {
|
||||
int tileID = effect.tileID;
|
||||
int textYOffset = effect.textYOffset;
|
||||
drawFromMapPosition(canvas, effect.area, effect.position, tileID);
|
||||
if (effect.displayText != null) {
|
||||
drawEffectText(canvas, effect.area, effect, textYOffset, effect.getTextPaint());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRedrawRectWholeScreen(Rect redrawRect) {
|
||||
// if (redrawRect.width() < mapViewArea.size.width * scaledTileSize) return false;
|
||||
@@ -317,11 +311,21 @@ public final class MainView extends SurfaceView
|
||||
return true;
|
||||
}
|
||||
private final Rect redrawRect = new Rect();
|
||||
private void redrawAreaWithEffect(final VisualEffectAnimation effect, int tileID, int textYOffset) {
|
||||
CoordRect area = effect.area;
|
||||
// if (shouldRedrawEverythingForVisualEffect()) area = mapViewArea;
|
||||
redrawArea_(area, effect, tileID, textYOffset);
|
||||
private void redrawAreaWithEffect(List<VisualEffectAnimation> effects) {
|
||||
CoordRect area = null;
|
||||
for (int i = 0; i < effects.size(); i++) {
|
||||
VisualEffectAnimation effect = effects.get(i);
|
||||
if (area == null) {
|
||||
area = effect.area;
|
||||
} else {
|
||||
area = CoordRect.union(area, effect.area);
|
||||
}
|
||||
}
|
||||
if (area != null) {
|
||||
redrawArea_(area, effects);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearCanvas() {
|
||||
if (!hasSurface) return;
|
||||
Canvas c = null;
|
||||
@@ -794,8 +798,8 @@ public final class MainView extends SurfaceView
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewAnimationFrame(VisualEffectAnimation animation, int tileID, int textYOffset) {
|
||||
redrawAreaWithEffect(animation, tileID, textYOffset);
|
||||
public void onNewAnimationFrames(List<VisualEffectAnimation> effects) {
|
||||
redrawAreaWithEffect(effects);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,107 @@
|
||||
I put both (release notes + forum announcement) into this source, so it will be easier to maintain them parallel:
|
||||
|
||||
|
||||
APK 78 (0.8.12) Towards Feygard
|
||||
|
||||
Release notes
|
||||
=============
|
||||
APK 78 (0.8.12) "Towards Feygard" or "Of kobolds, fae, witch and troll"
|
||||
|
||||
Release notes
|
||||
=============
|
||||
* 38 new maps mostly around the Guynmart castle area
|
||||
* 5 new quests:
|
||||
"It's Knot Funny" (from Wesley)
|
||||
"Fog in the woods"
|
||||
"Sobby's Trail"
|
||||
"Echoes of Enchantment"
|
||||
"A Feygard delicacy"
|
||||
* Missing Gylew fixed
|
||||
* Missing world map thumbnails are now automatically recreated when loading a savegame (thx to Jasp!).
|
||||
* Removal of unnecessary duplicate spritesheets (thx to OMGeeky).
|
||||
* Fix of flickering animations during combat
|
||||
* Fix of the glitch that made it possible to remove a condition of some items
|
||||
* Many minor map fixes, typos and other little things
|
||||
* Translations
|
||||
---- shortened for Google:
|
||||
* 38 new maps mostly around the Guynmart castle area
|
||||
* 5 new quests:
|
||||
"It's Knot Funny" (from Wesley)
|
||||
"Fog in the woods"
|
||||
"Sobby's Trail"
|
||||
"Echoes of Enchantment"
|
||||
"A Feygard delicacy"
|
||||
* Missing world map thumbnails are now automatically recreated
|
||||
* Fix of flickering animations during combat
|
||||
* Fix of the glitch that made it possible to remove a condition of some items
|
||||
* Minor map fixes, translations
|
||||
|
||||
|
||||
Forum announcement //2024-10-14
|
||||
==================
|
||||
Hello fellow adventurers,
|
||||
|
||||
you won't reach Feygard, but you'll be able to travel quite a bit on the way there. And encounter some unusual creatures:
|
||||
|
||||
Already near Fallhaven you will meet small cheeky Lytwings. They are driving Arensia from Fallhaven crazy.
|
||||
Wesley surprised us with this quest. I would like to emphasize the excellent quality of the development, we were able to adopt it practically without corrections or rework. Thank you, Wesley :)
|
||||
|
||||
You will finally solve the mystery of the fog in the northeast and make an interesting acquaintance in the process.
|
||||
|
||||
What does a boy have to do with kobolds?
|
||||
|
||||
And you will discover an abandoned village and its secret, and get another sweet quest as reward.
|
||||
|
||||
|
||||
[list]38 new maps mostly around the Guynmart castle area[/list]
|
||||
[list]5 new quests:
|
||||
[list]"It's Knot Funny"
|
||||
- A few lytwings are driving Arensia from Fallhaven crazy. (Wesley)[/list]
|
||||
[list]"Fog in the woods"
|
||||
- The great Duleian road is now accessible further northwest.[/list]
|
||||
[list]"Sobby's Trail"
|
||||
- Some things exist twice ...[/list]
|
||||
[list]"Echoes of Enchantment"
|
||||
- A strange village and its secret.[/list]
|
||||
[list]"A Feygard delicacy"
|
||||
- Antison is trying by all means to make Feygard attractive to you... [/list]
|
||||
[/list]
|
||||
[list]Gylew missing - fixed: If you don't find Gylew at his usual place (and before doing his quest), then seek in the bushes north west of his camp.[/list]
|
||||
[list]If for any reason some world maps are incomplete or missing at all, it is no longer necessary to visit these locations individually. Missing world map thumbnails are now automatically recreated when loading a savegame. Thanks to Jasp who had created this useful additions already years ago, it got into the game now.[/list]
|
||||
[list]Many maps had contained duplicate spritesheets unnecessarily. You didn't notice it, but it enlarged the APK size. OMGeeky has built a tool, so that we could merge these duplicates.
|
||||
(If you happen to find missing tiles in any map, please tell us!)[/list]
|
||||
[list]Fix of flickering animations during combat[/list]
|
||||
[list]Fix of the glitch that made it possible to remove a condition of some items[/list]
|
||||
[list]Many other minor map fixes, typos and other little things[/list]
|
||||
[list]And at last thanks to all translators for their work - we have included the current translations.[/list]
|
||||
|
||||
|
||||
Now here is is the link on our server: [url]https://andorstrail.com/static/AndorsTrail_v0.8.12.apk[/url]
|
||||
Google Play, F-Droid and Itch will follow soon.
|
||||
|
||||
Note: The first start might take long, maybe even minutes. Be patient, world map files are generated. This is only on first start.
|
||||
|
||||
And now: Happy playing! :D
|
||||
--------------
|
||||
Are you now eager to dive into the story?
|
||||
As usual, we have prepared a beta for you. Try it out, enjoy the new quests! And pay attention to inconsistencies, errors or other opportunities for improvement.
|
||||
Please post your comments here in this thread or on Discord in the Beta testing channel.
|
||||
This helps us to create a release version in good quality again.
|
||||
|
||||
A separate beta APK will be created so that you are independent of your productive game. Your saved games will remain untouched there.
|
||||
Tip: You can export a saved game and import it into the beta (but never the other way around).
|
||||
|
||||
|
||||
Here is is the link on our server: [url]https://andorstrail.com/static/AndorsTrail_v0.8.12_beta.apk[/url]
|
||||
And don’t forget to give us feedback about mistakes, what is good and what you don’t like.
|
||||
|
||||
Happy playing!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
APK 77 (0.8.11) Lake Laeroth
|
||||
|
||||
Release notes
|
||||
|
||||
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 156 KiB |
BIN
AndorsTrail/res/drawable/map_brightport.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 192 KiB After Width: | Height: | Size: 195 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 19 KiB |
51
AndorsTrail/res/raw/actorconditions_feygard_1.json
Normal file
@@ -0,0 +1,51 @@
|
||||
[
|
||||
{
|
||||
"id":"sweet_tooth",
|
||||
"iconID":"actorconditions_japozero:42",
|
||||
"name":"Sweet tooth",
|
||||
"category":"physical",
|
||||
"abilityEffect":{
|
||||
"increaseBlockChance":-20
|
||||
}
|
||||
},
|
||||
{
|
||||
"id":"minor_increased_defense",
|
||||
"iconID":"actorconditions_1:107",
|
||||
"name":"Minor increased defense",
|
||||
"category":"physical",
|
||||
"isPositive":1,
|
||||
"abilityEffect":{
|
||||
"increaseAttackChance":-10,
|
||||
"increaseMaxHP":0,
|
||||
"increaseBlockChance":7,
|
||||
"increaseDamageResistance":1
|
||||
}
|
||||
},
|
||||
{
|
||||
"id":"elytharabless_heal",
|
||||
"iconID":"actorconditions_1:35",
|
||||
"name":"Elythara's refreshment",
|
||||
"category":"spiritual",
|
||||
"isPositive":1,
|
||||
"roundEffect":{
|
||||
"visualEffectID":"blueSwirl",
|
||||
"increaseCurrentHP":{
|
||||
"min":1,
|
||||
"max":1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id":"soaked_vision",
|
||||
"iconID":"actorconditions_1:27",
|
||||
"name":"Soaked vision",
|
||||
"category":"physical",
|
||||
"abilityEffect":{
|
||||
"increaseAttackChance":-20,
|
||||
"increaseMoveCost":1,
|
||||
"increaseUseItemCost":1,
|
||||
"increaseReequipCost":1,
|
||||
"increaseAttackCost":1
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -3418,7 +3418,7 @@
|
||||
"nextPhraseID":"brv_woodcraftsman_1"
|
||||
},
|
||||
{
|
||||
"text":"Hello. The woodcutter in Loneford said that you can make me fences for a sheperd. Is that true?",
|
||||
"text":"Hello. The woodcutter in Loneford said that you can make me fences for a shepherd. Is that true?",
|
||||
"nextPhraseID":"brv_woodcraftsman_fence1",
|
||||
"requires":[
|
||||
{
|
||||
|
||||
@@ -500,6 +500,10 @@
|
||||
{
|
||||
"text":"No, I will go my own way. Your stupid Shadow is nothing but talk and fancy words.",
|
||||
"nextPhraseID":"buceth_decline"
|
||||
},
|
||||
{
|
||||
"text":"(Lie) I am ready to follow the Shadow.",
|
||||
"nextPhraseID":"buceth_27"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -518,6 +522,10 @@
|
||||
{
|
||||
"text":"No, I will go my own way. Your stupid Shadow is nothing but talk and fancy words.",
|
||||
"nextPhraseID":"buceth_decline"
|
||||
},
|
||||
{
|
||||
"text":"(Lie) I am ready to follow the Shadow.",
|
||||
"nextPhraseID":"buceth_27"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1961,7 +1961,7 @@
|
||||
"message":"All right, $playername. Of course I know you well. I am Burhczyd afgz Dtaloumiye.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Burhczyd? You - a knight of the Elythom?",
|
||||
"text":"Burhczyd? You - a Knight of Elythom?",
|
||||
"nextPhraseID":"burhczydx_10a_5"
|
||||
}
|
||||
]
|
||||
@@ -1978,7 +1978,7 @@
|
||||
},
|
||||
{
|
||||
"id":"burhczydx_10a_6",
|
||||
"message":"You know, once I feasted with the Lord Commander of the Elythom. A very pleasant man.",
|
||||
"message":"You know, once I feasted with the Lord Commander of the Order of Elythom. A very pleasant man.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"N",
|
||||
@@ -2087,7 +2087,7 @@
|
||||
},
|
||||
{
|
||||
"id":"burhczydx_11a_4",
|
||||
"message":"Oh that. I got bored playing Elythom. I then spread the word that I was walking around disguised as Elythom.",
|
||||
"message":"Oh that. I got bored playing Knight of the Elythom. I then spread the word that I was walking around dressed as one.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"N",
|
||||
|
||||
@@ -135,6 +135,17 @@
|
||||
"text":"Have you seen my brother Andor?",
|
||||
"nextPhraseID":"rigmor_1"
|
||||
},
|
||||
{
|
||||
"text":"Can you tell me about the lytwings?",
|
||||
"nextPhraseID":"rigmor_lytwing_1",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questLatestProgress",
|
||||
"requireID":"fallhaven_lytwings",
|
||||
"value":1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"I really need to go.",
|
||||
"nextPhraseID":"rigmor_leave_select"
|
||||
@@ -196,5 +207,139 @@
|
||||
"nextPhraseID":"S"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"fallhaven_clothes_0",
|
||||
"replies":[
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"fallhaven_clothes",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":69
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"fallhaven_clothes_10",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":66
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"fallhaven_clothes_40",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":68
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"fallhaven_clothes"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"fallhaven_clothes_10",
|
||||
"message":"Hey! What are you doing here? How did you get in?",
|
||||
"switchToNPC":"tailor",
|
||||
"replies":[
|
||||
{
|
||||
"text":"By the door. Why?",
|
||||
"nextPhraseID":"fallhaven_clothes_20"
|
||||
}
|
||||
],
|
||||
"rewards":[
|
||||
{
|
||||
"rewardType":"questProgress",
|
||||
"rewardID":"feygard_nondisplayed",
|
||||
"value":68
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"fallhaven_clothes_20",
|
||||
"message":"Nonsense. I would have noticed.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"fallhaven_clothes_30"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"fallhaven_clothes_30",
|
||||
"message":"Leave immediatly, or I'll call the guards!",
|
||||
"switchToNPC":"tailor",
|
||||
"replies":[
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"fallhaven_clothes_32"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"fallhaven_clothes_32",
|
||||
"message":"And don't dare to enter my house again!"
|
||||
},
|
||||
{
|
||||
"id":"fallhaven_clothes_40",
|
||||
"message":"I know your face. How dare you to come back?",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Are you sure you don't mix me with my brother?",
|
||||
"nextPhraseID":"fallhaven_clothes_42"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"fallhaven_clothes_42",
|
||||
"message":"Andor? I know that boy all too well.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Let me see your wares.",
|
||||
"nextPhraseID":"fallhaven_clothes_44",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"wear",
|
||||
"requireID":"jewel_fallhaven",
|
||||
"value":1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Let me see your wares.",
|
||||
"nextPhraseID":"S",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"wear",
|
||||
"requireID":"jewel_fallhaven",
|
||||
"value":1,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"fallhaven_clothes_44",
|
||||
"message":"You wear the stolen valuable necklace and dare lie to my face?",
|
||||
"replies":[
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"fallhaven_clothes_30"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -11,8 +11,132 @@
|
||||
"requireType":"questProgress",
|
||||
"requireID":"bucus",
|
||||
"value":20
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"bucus",
|
||||
"value":100,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"May I ask you a question? Do you know a way to climb over the graveyard fence to the south?",
|
||||
"nextPhraseID":"athamyr_coup_10",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"bucus",
|
||||
"value":100
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":60,
|
||||
"negate":true
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":69,
|
||||
"negate":true
|
||||
},
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"jewel_fallhaven",
|
||||
"value":1,
|
||||
"negate":true
|
||||
},
|
||||
{
|
||||
"requireType":"wear",
|
||||
"requireID":"jewel_fallhaven",
|
||||
"value":1,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"What about the ladder?",
|
||||
"nextPhraseID":"athamyr_coup_24a",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":60
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":61,
|
||||
"negate":true
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":69,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"I will go and find your ladder.",
|
||||
"nextPhraseID":"X",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":71
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":69,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"I tried the ladder, but the window is locked.",
|
||||
"nextPhraseID":"athamyr_coup_30",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":62
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":63,
|
||||
"negate":true
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":69,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"The ladder is gone and the window shut.",
|
||||
"nextPhraseID":"athamyr_coup_40",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":63
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_nondisplayed",
|
||||
"value":69
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"The catacombs were interesting.",
|
||||
"nextPhraseID":"athamyr_complete_12"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -28,7 +152,7 @@
|
||||
},
|
||||
{
|
||||
"id":"athamyr_2",
|
||||
"message":"But I'm the only one that both has the permission and the bravery to go down there.",
|
||||
"message":"But I'm the only one that has both the permission and the bravery to go down there.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"How can I get permission to go down there?",
|
||||
@@ -119,5 +243,322 @@
|
||||
"value":40
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_complete_12",
|
||||
"message":"I hope you behaved well there."
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_10",
|
||||
"message":"No, there is no way over the fence.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"athamyr_coup_11"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_11",
|
||||
"message":"Why do you ask?",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Oh, nothing.",
|
||||
"nextPhraseID":"athamyr_coup_12"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_12",
|
||||
"message":"You can tell me.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Well, behind the fence is the shop of the tailor.",
|
||||
"nextPhraseID":"athamyr_coup_14"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_14",
|
||||
"message":"That's right.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"And there is always a window open.",
|
||||
"nextPhraseID":"athamyr_coup_16"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_16",
|
||||
"message":"Ah, I understand. You want to surprise your friend, the tailor.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Eh, yes. Exactly.",
|
||||
"nextPhraseID":"athamyr_coup_18"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_18",
|
||||
"message":"Then I have a better idea. I am your man.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Great! I will thank you with a delicious piece of cooked meat.",
|
||||
"nextPhraseID":"athamyr_coup_20"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_20",
|
||||
"message":"Ten.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"What?",
|
||||
"nextPhraseID":"athamyr_coup_22"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_22",
|
||||
"message":"Make it ten. Ten cooked meat.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Are you crazy?",
|
||||
"nextPhraseID":"athamyr_coup_23"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_23",
|
||||
"message":"I have to smuggle a ladder into the basement of the church, which is very risky for me.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"athamyr_coup_24"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_24",
|
||||
"message":"Then you can climb through a window and reach a path right to the back of the tailor's house.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"OK. I have ten deliciously cooked pieces of meat now.",
|
||||
"nextPhraseID":"athamyr_coup_26",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"meat_cooked",
|
||||
"value":10
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"I will go for it now.",
|
||||
"nextPhraseID":"X",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"meat_cooked",
|
||||
"value":10,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Forget it.",
|
||||
"nextPhraseID":"X"
|
||||
}
|
||||
],
|
||||
"rewards":[
|
||||
{
|
||||
"rewardType":"questProgress",
|
||||
"rewardID":"feygard_nondisplayed",
|
||||
"value":60
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_24a",
|
||||
"message":"What about the cooked meat?",
|
||||
"replies":[
|
||||
{
|
||||
"text":"I have ten deliciously cooked pieces of meat now.",
|
||||
"nextPhraseID":"athamyr_coup_26",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"meat_cooked",
|
||||
"value":10
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"I will go for it now.",
|
||||
"nextPhraseID":"X",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"meat_cooked",
|
||||
"value":10,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_26",
|
||||
"message":"Ohh ...",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Here, take it.",
|
||||
"nextPhraseID":"athamyr_coup_28",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"inventoryRemove",
|
||||
"requireID":"meat_cooked",
|
||||
"value":10
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_28",
|
||||
"message":"I knew you would do that, my friend. So I have already hidden the ladder in the basement near the window.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Thank you.",
|
||||
"nextPhraseID":"X"
|
||||
}
|
||||
],
|
||||
"rewards":[
|
||||
{
|
||||
"rewardType":"questProgress",
|
||||
"rewardID":"feygard_nondisplayed",
|
||||
"value":61
|
||||
},
|
||||
{
|
||||
"rewardType":"questProgress",
|
||||
"rewardID":"feygard_nondisplayed",
|
||||
"value":71
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_30",
|
||||
"message":"Oh, is that so? Hmm.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Yes. And you know it perfectly well.",
|
||||
"nextPhraseID":"athamyr_coup_32"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_32",
|
||||
"message":"Well, maybe I could risk borrowing the key and unlocking the window.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Maybe? What does that mean?!",
|
||||
"nextPhraseID":"athamyr_coup_34"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_34",
|
||||
"message":"Bring twenty more pieces of cooked meat. Yes, twenty should do. That's worth my risk of ending up as bonemeal.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"I have bought the twenty cooked pieces of cooked meat.",
|
||||
"nextPhraseID":"athamyr_coup_36",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"meat_cooked",
|
||||
"value":20
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"I will go for it now.",
|
||||
"nextPhraseID":"X",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"meat_cooked",
|
||||
"value":20,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Forget it.",
|
||||
"nextPhraseID":"X"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_36",
|
||||
"message":"Ohh, that smells delicious! You are a true friend.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Here take it. And don't forget to unlock the window.",
|
||||
"nextPhraseID":"athamyr_coup_38",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"inventoryRemove",
|
||||
"requireID":"meat_cooked",
|
||||
"value":20
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_38",
|
||||
"message":"The window is already unlocked.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Thank you.",
|
||||
"nextPhraseID":"X"
|
||||
},
|
||||
{
|
||||
"text":"I hope for your sake that was all.",
|
||||
"nextPhraseID":"X"
|
||||
}
|
||||
],
|
||||
"rewards":[
|
||||
{
|
||||
"rewardType":"questProgress",
|
||||
"rewardID":"feygard_nondisplayed",
|
||||
"value":63
|
||||
},
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"feygard_nondisplayed",
|
||||
"value":72
|
||||
},
|
||||
{
|
||||
"rewardType":"questProgress",
|
||||
"rewardID":"feygard_nondisplayed",
|
||||
"value":73
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_40",
|
||||
"message":"Yes. I tidied up a bit again.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Could you ...",
|
||||
"nextPhraseID":"athamyr_coup_42"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"athamyr_coup_42",
|
||||
"message":"... unlock the window again for you? No, I have enough cooked meat for a long time."
|
||||
}
|
||||
]
|
||||
@@ -21,6 +21,17 @@
|
||||
"value":20
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Do you have strawberries?",
|
||||
"nextPhraseID":"bela_lytwing_strawberries",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questLatestProgress",
|
||||
"requireID":"fallhaven_lytwings",
|
||||
"value":11
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
7925
AndorsTrail/res/raw/conversationlist_feygard_1.json
Normal file
@@ -211,7 +211,7 @@
|
||||
"nextPhraseID":"ff_captain_4"
|
||||
},
|
||||
{
|
||||
"text":"So when you say \"peace\", you really mean \"law enforement\"?",
|
||||
"text":"So when you say \"peace\", you really mean \"law enforcement\"?",
|
||||
"nextPhraseID":"ff_captain_beer_10",
|
||||
"requires":[
|
||||
{
|
||||
|
||||
@@ -1499,6 +1499,26 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nextPhraseID":"gael_soup",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"soup_forest",
|
||||
"value":1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nextPhraseID":"gael_soup",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"gloriosa_mushroom_soup",
|
||||
"value":1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nextPhraseID":"gael_20",
|
||||
"requires":[
|
||||
@@ -1706,6 +1726,28 @@
|
||||
"value":10
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Here, I have 10 nice pieces of lamb meat for you. Maybe not as good as snake though.",
|
||||
"nextPhraseID":"gael_20_7",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"inventoryRemove",
|
||||
"requireID":"lamb_meat_raw",
|
||||
"value":10
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Here, I have 8 nice pieces of snake meat for you.",
|
||||
"nextPhraseID":"gael_20_7",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"inventoryRemove",
|
||||
"requireID":"snake_meat",
|
||||
"value":8
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -339,19 +339,84 @@
|
||||
},
|
||||
{
|
||||
"id":"arensia",
|
||||
"message":"Hello, dear.",
|
||||
"replies":[
|
||||
{
|
||||
"nextPhraseID":"arensia_done",
|
||||
"text":"I have a letter for you.",
|
||||
"nextPhraseID":"arensia_letter",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"postman",
|
||||
"value":20
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"gorwath_letter",
|
||||
"value":1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nextPhraseID":"arensia_1"
|
||||
"text":"Hello. I am wondering if you could help me?",
|
||||
"nextPhraseID":"arensia_witch_10",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questLatestProgress",
|
||||
"requireID":"wicked_witch",
|
||||
"value":10
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"You seem tired. Is everything alright?",
|
||||
"nextPhraseID":"arensia_lytwing_select",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"fallhaven_lytwings",
|
||||
"value":1,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"About the lytwings ...",
|
||||
"nextPhraseID":"arensia_lytwing_select",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"fallhaven_lytwings",
|
||||
"value":1
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"fallhaven_lytwings",
|
||||
"value":102,
|
||||
"negate":true
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"fallhaven_lytwings",
|
||||
"value":103,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Have the lytwings honored their word?",
|
||||
"nextPhraseID":"arensia_lytwing_34",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"fallhaven_lytwings",
|
||||
"value":100
|
||||
},
|
||||
{
|
||||
"requireType":"wear",
|
||||
"requireID":"ring_of_promise",
|
||||
"value":1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Hello.",
|
||||
"nextPhraseID":"arensia_done"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1219,6 +1219,11 @@
|
||||
"rewardType":"changeMapFilter",
|
||||
"rewardID":"invert",
|
||||
"mapName":"guynmart_wood_6"
|
||||
},
|
||||
{
|
||||
"rewardType":"changeMapFilter",
|
||||
"rewardID":"invert",
|
||||
"mapName":"beekeeper2"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1239,6 +1244,11 @@
|
||||
"rewardType":"changeMapFilter",
|
||||
"rewardID":"none",
|
||||
"mapName":"guynmart_wood_6"
|
||||
},
|
||||
{
|
||||
"rewardType":"changeMapFilter",
|
||||
"rewardID":"none",
|
||||
"mapName":"beekeeper2"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1349,6 +1359,21 @@
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":42
|
||||
},
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":43
|
||||
},
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":44
|
||||
},
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":45
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1369,12 +1394,27 @@
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":43
|
||||
},
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":44
|
||||
},
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":45
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"guynmart_s_hill3",
|
||||
"rewards":[
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":41
|
||||
},
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
@@ -1389,12 +1429,27 @@
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":44
|
||||
},
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":45
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"guynmart_s_hill4",
|
||||
"rewards":[
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":41
|
||||
},
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":42
|
||||
},
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
@@ -1415,6 +1470,21 @@
|
||||
{
|
||||
"id":"guynmart_s_hill5",
|
||||
"rewards":[
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":41
|
||||
},
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":42
|
||||
},
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
"value":43
|
||||
},
|
||||
{
|
||||
"rewardType":"removeQuestProgress",
|
||||
"rewardID":"guynmart_nondisplay",
|
||||
@@ -1464,5 +1534,21 @@
|
||||
"mapName":"fields5"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"guynmart_sign_fog_10a_0",
|
||||
"replies":[
|
||||
{
|
||||
"nextPhraseID":"guynmart_sign_fog_10a",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_fog",
|
||||
"value":1,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -78,12 +78,47 @@
|
||||
{
|
||||
"text":"Oh? Is it the fog that is the problem?",
|
||||
"nextPhraseID":"guynmart_roadguard_20"
|
||||
},
|
||||
{
|
||||
"text":"Why?",
|
||||
"nextPhraseID":"guynmart_roadguard_12",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_fog",
|
||||
"value":1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Why?",
|
||||
"nextPhraseID":"guynmart_roadguard_12",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"fogmonster",
|
||||
"value":80
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"guynmart_roadguard_20",
|
||||
"message":"Yes. Several men already got lost and never reappeared. There is no way through."
|
||||
"message":"Yes. Several men already got lost and never reappeared. There is no way through.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"But ... which fog?",
|
||||
"nextPhraseID":"guynmart_roadguard_30",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"feygard_fog",
|
||||
"value":1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"guynmart_farmer_10",
|
||||
|
||||
@@ -39,6 +39,27 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Hey. I found the Korhald tomb and it had two items that I think might interest you.",
|
||||
"nextPhraseID":"gylew_korhald_cop_0",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questLatestProgress",
|
||||
"requireID":"odd_coin_collector",
|
||||
"value":66
|
||||
},
|
||||
{
|
||||
"requireType":"wear",
|
||||
"requireID":"shield_of_brave",
|
||||
"value":1
|
||||
},
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"hero_coin",
|
||||
"value":1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Inside the Korhald tomb, I found a locked chest. Do you know where I can find its key?",
|
||||
"nextPhraseID":"odd_coin_collector_ask_about_locked_chest",
|
||||
@@ -77,6 +98,22 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"I found these glowing coins in a pit beneath the well in Wexlow Village. They seem magical.",
|
||||
"nextPhraseID":"coin_collector_troll_coins",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"odd_coin_collector",
|
||||
"value":100
|
||||
},
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"mysterious_coin",
|
||||
"value":3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"We have no more business to discuss. I'll see you later.",
|
||||
"nextPhraseID":"X",
|
||||
@@ -88,6 +125,22 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"I found these glowing coins in a pit beneath the well in Wexlow Village. They seem magical.",
|
||||
"nextPhraseID":"coin_collector_troll_coins",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"odd_coin_collector",
|
||||
"value":105
|
||||
},
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"mysterious_coin",
|
||||
"value":3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"I was glad to help fulfill you and your father's dream, but I need to go now.",
|
||||
"nextPhraseID":"X",
|
||||
@@ -136,5 +189,31 @@
|
||||
{
|
||||
"id":"gylew_henchman",
|
||||
"message":"Hey, I'm trying to admire the view here. Get out of my way."
|
||||
},
|
||||
{
|
||||
"id":"gylew_bugfix_spawn",
|
||||
"replies":[
|
||||
{
|
||||
"nextPhraseID":"gylew_bugfix_spawn_10",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"killedMonster",
|
||||
"requireID":"gylew",
|
||||
"value":1,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"gylew_bugfix_spawn_10",
|
||||
"rewards":[
|
||||
{
|
||||
"rewardType":"spawnAll",
|
||||
"rewardID":"gylew",
|
||||
"mapName":"waterway5"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -188,6 +188,12 @@
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"gold",
|
||||
"value":10
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"odd_coin_collector",
|
||||
"value":13,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -202,6 +208,17 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Yes, I know this already.",
|
||||
"nextPhraseID":"gylew7",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"odd_coin_collector",
|
||||
"value":11
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"I am so not interested.",
|
||||
"nextPhraseID":"gylew7",
|
||||
@@ -325,6 +342,12 @@
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"gold",
|
||||
"value":10
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"odd_coin_collector",
|
||||
"value":13,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -359,7 +382,7 @@
|
||||
"message":"That was foolish of you. This is very valuable and you just gave it to me.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"N",
|
||||
"text":"Well, what can I say? You caught me me wanting to be charitable.",
|
||||
"nextPhraseID":"gylew8",
|
||||
"requires":[
|
||||
{
|
||||
@@ -377,6 +400,12 @@
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"gold",
|
||||
"value":10
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"odd_coin_collector",
|
||||
"value":13,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -965,7 +994,7 @@
|
||||
},
|
||||
{
|
||||
"id":"forenza_island_100",
|
||||
"message":"I was only allowed to go after mother instisted to father that I go too.",
|
||||
"message":"I was only allowed to go after mother insisted to father that I go too.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"What happened to skipping the details?",
|
||||
@@ -1143,6 +1172,27 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Hey. I found the Korhald tomb and it had two items that I think might interest you.",
|
||||
"nextPhraseID":"forenza_korhald_cop_0",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questLatestProgress",
|
||||
"requireID":"odd_coin_collector",
|
||||
"value":65
|
||||
},
|
||||
{
|
||||
"requireType":"wear",
|
||||
"requireID":"shield_of_brave",
|
||||
"value":1
|
||||
},
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"hero_coin",
|
||||
"value":1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Inside the Korhald tomb, I found a locked chest. Do you know where I can find its key?",
|
||||
"nextPhraseID":"odd_coin_collector_ask_about_locked_chest",
|
||||
@@ -1192,6 +1242,22 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"I found these glowing coins in a pit beneath the well in Wexlow Village. They seem magical.",
|
||||
"nextPhraseID":"coin_collector_troll_coins",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"odd_coin_collector",
|
||||
"value":110
|
||||
},
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"mysterious_coin",
|
||||
"value":3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"We have no more business to discuss. I'll see you later.",
|
||||
"nextPhraseID":"X",
|
||||
@@ -1204,7 +1270,23 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"I hope that having these coins will enable you to make peace with your father. Take care.",
|
||||
"text":"I found these glowing coins in a pit beneath the well in Wexlow Village. They seem magical.",
|
||||
"nextPhraseID":"coin_collector_troll_coins",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"odd_coin_collector",
|
||||
"value":115
|
||||
},
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"mysterious_coin",
|
||||
"value":3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"I hope that these coins will enable you to make peace with your father. Take care.",
|
||||
"nextPhraseID":"X",
|
||||
"requires":[
|
||||
{
|
||||
@@ -1215,7 +1297,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"[Lie]I have these bronze and silver coins that I \"acquired\" in a game of chance. I would like to know if you are interested in them.",
|
||||
"text":"[Lie] I have these bronze and silver coins that I \"acquired\" in a game of chance. I would like to know if you are interested in them.",
|
||||
"nextPhraseID":"coin_collector_thief_coins_10",
|
||||
"requires":[
|
||||
{
|
||||
@@ -1397,7 +1479,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Yes and I already gave it to you.",
|
||||
"text":"Yes and I already gave them to you.",
|
||||
"nextPhraseID":"gylew_korhald_25",
|
||||
"requires":[
|
||||
{
|
||||
@@ -1440,7 +1522,7 @@
|
||||
},
|
||||
{
|
||||
"id":"gylew_korhald_20",
|
||||
"message":"Great! Let me have it.",
|
||||
"message":"Great! Let me have them.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Here you go.",
|
||||
@@ -2155,7 +2237,7 @@
|
||||
},
|
||||
{
|
||||
"id":"laeroth_tower_south",
|
||||
"message":"Looking to the south, you see the lakeshore you walked along. There is also a tower in the distance. You wonder if at one time the that tower and this one sent signals to each other."
|
||||
"message":"Looking to the south, you see the lakeshore you walked along. There is also a tower in the distance. You wonder if at one time that tower and this one sent signals to each other."
|
||||
},
|
||||
{
|
||||
"id":"laeroth_tower_west",
|
||||
@@ -2251,7 +2333,7 @@
|
||||
},
|
||||
{
|
||||
"id":"forenza_korhald_cop_20",
|
||||
"message":"Well, for obvious reasons. Didn't you notice that the shield has the Korhald family crest engraved on its front side? This clearly belonged to Korhald himself. You should keep this item as i could aid you in your adventures.",
|
||||
"message":"Well, for obvious reasons. Didn't you notice that the shield has the Korhald family crest engraved on its front side? This clearly belonged to Korhald himself. You should keep this item as it could aid you in your adventures.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"N",
|
||||
@@ -2303,7 +2385,7 @@
|
||||
},
|
||||
{
|
||||
"id":"forenza_korhald_cop_35",
|
||||
"message":"Oh, how very generous of you to just hand it over for free. I'll tell you what once you find your way to Brightport, seek out my family. They will help you reward you for all of your generosity and hard work.",
|
||||
"message":"Oh, how very generous of you to just hand it over for free. I'll tell you what, once you find your way to Brightport, seek out my family. They will reward you for all of your generosity and hard work.",
|
||||
"rewards":[
|
||||
{
|
||||
"rewardType":"questProgress",
|
||||
@@ -4244,7 +4326,7 @@
|
||||
},
|
||||
{
|
||||
"id":"jewelry_box_1",
|
||||
"message":"This looks interesting. Could be a jewelry box. I has \"A\" inscribed on it. It is locked though, and too heavy to move to the tomb.",
|
||||
"message":"This looks interesting. Could be a jewelry box. It has \"A\" inscribed on it. It is locked though, and too heavy to move to the tomb.",
|
||||
"rewards":[
|
||||
{
|
||||
"rewardType":"questProgress",
|
||||
@@ -5092,7 +5174,7 @@
|
||||
},
|
||||
{
|
||||
"id":"brute_fisherman_8",
|
||||
"message":"You just came this path. Do you know why it's been used so little lately?",
|
||||
"message":"You just came using this path. Do you know why it's been used so little lately?",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Well, yes, I think so.",
|
||||
@@ -5472,7 +5554,7 @@
|
||||
},
|
||||
{
|
||||
"id":"brute_creator_sign_2",
|
||||
"message":"Praise is the portal to the presence of Alythara"
|
||||
"message":"Praise is the portal to the presence of Elythara"
|
||||
},
|
||||
{
|
||||
"id":"brute_creator_sign_3",
|
||||
@@ -9807,7 +9889,7 @@
|
||||
},
|
||||
{
|
||||
"id":"lae_centaur9_12",
|
||||
"message":"There is a foul creature that lurks in the cave to the east. It resembles a human but is far more savage.",
|
||||
"message":"There is a foul creature that lurks in the cave to the west. It resembles a human but is far more savage.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"N",
|
||||
@@ -10336,7 +10418,7 @@
|
||||
"message":"You did? Oh, yes, I remember now.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Your a crazy old man.",
|
||||
"text":"You're a crazy old man.",
|
||||
"nextPhraseID":"gylew_korhald_27"
|
||||
}
|
||||
]
|
||||
@@ -10578,7 +10660,7 @@
|
||||
},
|
||||
{
|
||||
"id":"coin_collector_thief_coins_50",
|
||||
"message":"[The collector pauses, his gaze lingering on the coins.] These pieces are not merely currency; they are artifacts of a hidden past,\na glimpse into the umderground world where alliances were forged in secrecy. I'd be willing to make you an offer for these intriguing\ntokens of history, should you be interested in parting with them.",
|
||||
"message":"[The collector pauses, his gaze lingering on the coins.] These pieces are not merely currency; they are artifacts of a hidden past,\na glimpse into the underground world where alliances were forged in secrecy. I'd be willing to make you an offer for these intriguing\ntokens of history, should you be interested in parting with them.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"So you want to buy them all?",
|
||||
@@ -12023,7 +12105,7 @@
|
||||
},
|
||||
{
|
||||
"id":"lae_torturer_11e",
|
||||
"message":"Sure. We only want want the thruth. Nothing more. It is a very prestigious work.",
|
||||
"message":"Sure. We only want the truth. Nothing more. It is a very prestigious work.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"If you say so.",
|
||||
@@ -12124,7 +12206,7 @@
|
||||
},
|
||||
{
|
||||
"id":"lae_torturer_30",
|
||||
"message":"Okay, then let's get started. This is a very important job, you know?",
|
||||
"message":"OK, then let's get started. This is a very important job, you know?",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Why?",
|
||||
|
||||
1676
AndorsTrail/res/raw/conversationlist_lytwings.json
Normal file
@@ -262,6 +262,30 @@
|
||||
"message":"Please move along. There's nothing to see here.",
|
||||
"switchToNPC":"thief_seraphina",
|
||||
"replies":[
|
||||
{
|
||||
"text":"I've been wondering, do you have anything to sell?",
|
||||
"nextPhraseID":"thief_seraphina_helmet_1",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"sutdover_hidden",
|
||||
"value":3,
|
||||
"negate":true
|
||||
},
|
||||
{
|
||||
"requireType":"inventoryKeep",
|
||||
"requireID":"armored_helmet",
|
||||
"value":1,
|
||||
"negate":true
|
||||
},
|
||||
{
|
||||
"requireType":"wear",
|
||||
"requireID":"armored_helmet",
|
||||
"value":1,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"Yes, ma'am.",
|
||||
"nextPhraseID":"X"
|
||||
@@ -2657,7 +2681,7 @@
|
||||
},
|
||||
{
|
||||
"id":"captive_girl_55",
|
||||
"message":"Well, I am not eactly sure about that as the witch would make it. Damn! I hate that smell. Damn! I love that taste however.",
|
||||
"message":"Well, I am not exactly sure about that as the witch would make it. Damn! I hate that smell. Damn! I love that taste however.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Can you help me out a little bit? Do you know anything about them?",
|
||||
@@ -3468,106 +3492,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"captive_girl_selector",
|
||||
"replies":[
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"captive_girl_10",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"wicked_witch",
|
||||
"value":90,
|
||||
"negate":true
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"wicked_witch",
|
||||
"value":95,
|
||||
"negate":true
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"wicked_witch",
|
||||
"value":96,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"captive_girl_50",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questLatestProgress",
|
||||
"requireID":"wicked_witch",
|
||||
"value":90
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"captive_girl_75",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"wicked_witch",
|
||||
"value":95
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"captive_girl_31"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"captive_girl_65",
|
||||
"message":"Ah, YES. I remember her saying that an \"undead\" friend of her's east of here taught her how to make them.",
|
||||
"replies":[
|
||||
{
|
||||
"text":"OK. Stay here. I will be back with more of them.",
|
||||
"nextPhraseID":"X"
|
||||
}
|
||||
],
|
||||
"rewards":[
|
||||
{
|
||||
"rewardType":"questProgress",
|
||||
"rewardID":"wicked_witch",
|
||||
"value":90
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"wicked_witch_reveal_girl_selector",
|
||||
"replies":[
|
||||
{
|
||||
"text":"N",
|
||||
"nextPhraseID":"wicked_witch_reveal_girl_spawn",
|
||||
"requires":[
|
||||
{
|
||||
"requireType":"timerElapsed",
|
||||
"requireID":"wicked_witch_despawn_timer",
|
||||
"value":72
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"wicked_witch",
|
||||
"value":96,
|
||||
"negate":true
|
||||
},
|
||||
{
|
||||
"requireType":"questProgress",
|
||||
"requireID":"wicked_witch",
|
||||
"value":95,
|
||||
"negate":true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"fix_stn_skeletons_10",
|
||||
"message":"What a beautiful view from here.",
|
||||
|
||||
@@ -8649,6 +8649,9 @@
|
||||
"value":9000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nextPhraseID":"gal_chk_h2"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
},
|
||||
{
|
||||
"id":"sign_road2",
|
||||
"message":"East: Nor City\nWest: Vilegard"
|
||||
"message":"North: Leofric's Honey Haven\nEast: Nor City\nWest: Vilegard"
|
||||
}
|
||||
]
|
||||
@@ -11819,7 +11819,8 @@
|
||||
"message":"No, unfortunately not. Maybe try my colleague in Fallhaven?",
|
||||
"replies":[
|
||||
{
|
||||
"text":"Sigh - well, thanks."
|
||||
"text":"Sigh - well, thanks.",
|
||||
"nextPhraseID":"X"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||