diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index 1047181f1..cc3d7f029 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -964,6 +964,15 @@ actors.mobs.npcs.blacksmith.un_ided=I need to know what I'm working with, identi actors.mobs.npcs.blacksmith.cursed=I don't work with cursed items! actors.mobs.npcs.blacksmith.degraded=It's junk, the quality is too poor! actors.mobs.npcs.blacksmith.cant_reforge=I can't reforge these items! +actors.mobs.npcs.blacksmith.intro_quest_1=QUEST_1_INTRO +actors.mobs.npcs.blacksmith.intro_quest_2=QUEST_2_INTRO +actors.mobs.npcs.blacksmith.intro_quest_3=QUEST_3_INTRO +actors.mobs.npcs.blacksmith.reminder=REMINDER +actors.mobs.npcs.blacksmith.entrance_blocked=The way down is blocked. +actors.mobs.npcs.blacksmith.cant_enter_old=That area is not accessible on this run. Play a new game to try the new quest! +actors.mobs.npcs.blacksmith.exit_warn=I'm not lettin' you back in, so if you're comin' out, make sure you're all done! +actors.mobs.npcs.blacksmith.exit_yes=I'm Done +actors.mobs.npcs.blacksmith.exit_no=Not Yet actors.mobs.npcs.blacksmith.def_verb=blocked actors.mobs.npcs.blacksmith.desc=This troll blacksmith looks like all trolls look: he is tall and lean, and his skin resembles stone in both color and texture. The troll blacksmith is tinkering with unproportionally small tools. diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java index dfa3b9c08..1327c81ef 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java @@ -70,6 +70,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Monk; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Snake; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.CheckedCell; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; @@ -148,6 +149,7 @@ import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.SurfaceScene; +import com.shatteredpixel.shatteredpixeldungeon.sprites.BlacksmithSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; @@ -1253,6 +1255,8 @@ public class Hero extends Char { PixelScene.shake(1, 1f); ready(); return false; + + //TODO, these checks are getting cumbersome, perhaps move them into Level? } else if (!Dungeon.level.locked && transition != null && transition.inside(pos)) { if (transition.type == LevelTransition.Type.SURFACE){ @@ -1300,6 +1304,41 @@ public class Hero extends Char { }); ready(); + } else if (transition.type == LevelTransition.Type.BRANCH_EXIT + && Dungeon.depth >= 11 && Dungeon.depth <= 14 + && (!Blacksmith.Quest.given() || Blacksmith.Quest.oldQuestMineBlocked() || Blacksmith.Quest.completed())) { + + if (Blacksmith.Quest.oldQuestMineBlocked()){ + GLog.w(Messages.get(Blacksmith.class, "cant_enter_old")); + } else { + GLog.w(Messages.get(Blacksmith.class, "entrance_blocked")); + } + ready(); + + } else if (transition.type == LevelTransition.Type.BRANCH_ENTRANCE + && Dungeon.depth >= 11 && Dungeon.depth <= 14 + && !Blacksmith.Quest.completed()) { + + Game.runOnRenderThread(new Callback() { + @Override + public void call() { + GameScene.show( new WndOptions( new BlacksmithSprite(), + Messages.titleCase(Messages.get(Blacksmith.class, "name")), + Messages.get(Blacksmith.class, "exit_warn"), + Messages.get(Blacksmith.class, "exit_yes"), + Messages.get(Blacksmith.class, "exit_no")){ + @Override + protected void onSelect(int index) { + if (index == 0){ + Blacksmith.Quest.complete(); + actTransition(action); + } + } + } ); + } + }); + ready(); + } else { curAction = null; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java index a8ca0c568..8b4f0b101 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java @@ -65,9 +65,10 @@ public class Blacksmith extends NPC { protected boolean act() { if (Dungeon.hero.buff(AscensionChallenge.class) != null){ die(null); + Notes.remove( Notes.Landmark.TROLL ); return true; } - if (Dungeon.level.visited[pos] && !Quest.reforged){ + if (Dungeon.level.visited[pos]){ Notes.add( Notes.Landmark.TROLL ); } return super.act(); @@ -83,13 +84,29 @@ public class Blacksmith extends NPC { } if (!Quest.given) { - + + final String text; + //pre-v2.2.0 saves + switch (Quest.type ){ + case 0: default: + text = Quest.alternative ? Messages.get(Blacksmith.this, "blood_1") : Messages.get(Blacksmith.this, "gold_1"); + break; + case 1: + text = Messages.get(Blacksmith.this, "intro_quest_1"); + break; + case 2: + text = Messages.get(Blacksmith.this, "intro_quest_2"); + break; + case 3: + text = Messages.get(Blacksmith.this, "intro_quest_3"); + break; + } + Game.runOnRenderThread(new Callback() { @Override public void call() { - GameScene.show( new WndQuest( Blacksmith.this, - Quest.alternative ? Messages.get(Blacksmith.this, "blood_1") : Messages.get(Blacksmith.this, "gold_1") ) { - + GameScene.show(new WndQuest(Blacksmith.this, text) { + @Override public void onBackPressed() { super.onBackPressed(); @@ -111,47 +128,54 @@ public class Blacksmith extends NPC { }); } else if (!Quest.completed) { - if (Quest.alternative) { - - Pickaxe pick = Dungeon.hero.belongings.getItem( Pickaxe.class ); - if (pick == null) { - tell( Messages.get(this, "lost_pick") ); - } else if (!pick.bloodStained) { - tell( Messages.get(this, "blood_2") ); - } else { - if (pick.isEquipped( Dungeon.hero )) { - pick.cursed = false; //so that it can always be removed - pick.doUnequip( Dungeon.hero, false ); + + if (Quest.type == 0) { + if (Quest.alternative) { + + Pickaxe pick = Dungeon.hero.belongings.getItem(Pickaxe.class); + if (pick == null) { + tell(Messages.get(this, "lost_pick")); + } else if (!pick.bloodStained) { + tell(Messages.get(this, "blood_2")); + } else { + if (pick.isEquipped(Dungeon.hero)) { + pick.cursed = false; //so that it can always be removed + pick.doUnequip(Dungeon.hero, false); + } + pick.detach(Dungeon.hero.belongings.backpack); + tell(Messages.get(this, "completed")); + + Quest.completed = true; + Quest.reforged = false; + Statistics.questScores[2] = 3000; } - pick.detach( Dungeon.hero.belongings.backpack ); - tell( Messages.get(this, "completed") ); - - Quest.completed = true; - Quest.reforged = false; - Statistics.questScores[2] = 3000; + + } else { + + Pickaxe pick = Dungeon.hero.belongings.getItem(Pickaxe.class); + DarkGold gold = Dungeon.hero.belongings.getItem(DarkGold.class); + if (pick == null) { + tell(Messages.get(this, "lost_pick")); + } else if (gold == null || gold.quantity() < 15) { + tell(Messages.get(this, "gold_2")); + } else { + if (pick.isEquipped(Dungeon.hero)) { + pick.doUnequip(Dungeon.hero, false); + } + pick.detach(Dungeon.hero.belongings.backpack); + gold.detachAll(Dungeon.hero.belongings.backpack); + tell(Messages.get(this, "completed")); + + Quest.completed = true; + Quest.reforged = false; + Statistics.questScores[2] = 3000; + } + } - } else { - - Pickaxe pick = Dungeon.hero.belongings.getItem( Pickaxe.class ); - DarkGold gold = Dungeon.hero.belongings.getItem( DarkGold.class ); - if (pick == null) { - tell( Messages.get(this, "lost_pick") ); - } else if (gold == null || gold.quantity() < 15) { - tell( Messages.get(this, "gold_2") ); - } else { - if (pick.isEquipped( Dungeon.hero )) { - pick.doUnequip( Dungeon.hero, false ); - } - pick.detach( Dungeon.hero.belongings.backpack ); - gold.detachAll( Dungeon.hero.belongings.backpack ); - tell( Messages.get(this, "completed") ); - - Quest.completed = true; - Quest.reforged = false; - Statistics.questScores[2] = 3000; - } - + + tell(Messages.get(this, "reminder")); + } } else if (!Quest.reforged) { @@ -253,8 +277,6 @@ public class Blacksmith extends NPC { Item.updateQuickslot(); Quest.reforged = true; - - Notes.remove( Notes.Landmark.TROLL ); } @Override @@ -278,27 +300,39 @@ public class Blacksmith extends NPC { } public static class Quest { - + + // 0 = old blacksmith quest (pre-2.2.0) + // 1 = TBA + // 2 = TBA + // 3 = TBA + private static int type; + private static boolean spawned; - - private static boolean alternative; private static boolean given; private static boolean completed; + + //pre-v2.2.0 + private static boolean alternative; //false for mining gold, true for bat blood private static boolean reforged; public static void reset() { + type = 0; + spawned = false; given = false; + completed = false; reforged = false; } private static final String NODE = "blacksmith"; - + + private static final String TYPE = "type"; private static final String SPAWNED = "spawned"; - private static final String ALTERNATIVE = "alternative"; private static final String GIVEN = "given"; private static final String COMPLETED = "completed"; + + private static final String ALTERNATIVE = "alternative"; private static final String REFORGED = "reforged"; public static void storeInBundle( Bundle bundle ) { @@ -308,6 +342,7 @@ public class Blacksmith extends NPC { node.put( SPAWNED, spawned ); if (spawned) { + node.put( TYPE, type ); node.put( ALTERNATIVE, alternative ); node.put( GIVEN, given ); node.put( COMPLETED, completed ); @@ -322,6 +357,7 @@ public class Blacksmith extends NPC { Bundle node = bundle.getBundle( NODE ); if (!node.isNull() && (spawned = node.getBoolean( SPAWNED ))) { + type = node.getInt(TYPE); alternative = node.getBoolean( ALTERNATIVE ); given = node.getBoolean( GIVEN ); completed = node.getBoolean( COMPLETED ); @@ -336,12 +372,41 @@ public class Blacksmith extends NPC { rooms.add(new BlacksmithRoom()); spawned = true; - alternative = Random.Int( 2 ) == 0; + + type = 1+Random.Int(3); + alternative = false; given = false; } return rooms; } + + public static boolean given(){ + return given; + } + + public static boolean completed(){ + return given && completed; + } + + public static void complete(){ + completed = true; + reforged = false; + Statistics.questScores[2] = 3000; //TODO actual scoring logic + } + + //if the blacksmith is generated pre-v2.2.0, and the player never spawned a mining test floor + public static boolean oldQuestMineBlocked(){ + return type == 0 && !Dungeon.levelHasBeenGenerated(Dungeon.depth, 1); + } + + public static boolean oldBloodQuest(){ + return type == 0 && alternative; + } + + public static boolean oldMiningQuest(){ + return type == 0 && !alternative; + } } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/Pickaxe.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/Pickaxe.java index e79c39074..2ad9f317d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/Pickaxe.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/Pickaxe.java @@ -36,6 +36,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Crab; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Scorpio; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Spinner; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Swarm; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon; @@ -54,6 +55,7 @@ import com.watabou.utils.PathFinder; import java.util.ArrayList; +//various code in here supports old blacksmith quest logic from before v2.2.0 public class Pickaxe extends MeleeWeapon { public static final String AC_MINE = "MINE"; @@ -83,7 +85,9 @@ public class Pickaxe extends MeleeWeapon { @Override public ArrayList actions( Hero hero ) { ArrayList actions = super.actions( hero ); - actions.add( AC_MINE ); + if (Blacksmith.Quest.oldMiningQuest()) { + actions.add(AC_MINE); + } return actions; } @@ -140,7 +144,7 @@ public class Pickaxe extends MeleeWeapon { @Override public int proc( Char attacker, Char defender, int damage ) { - if (!bloodStained && defender instanceof Bat) { + if (Blacksmith.Quest.oldBloodQuest() && !bloodStained && defender instanceof Bat) { Actor.add(new Actor() { { @@ -166,8 +170,10 @@ public class Pickaxe extends MeleeWeapon { public String defaultAction() { if (Dungeon.hero.heroClass == HeroClass.DUELIST && isEquipped(Dungeon.hero)){ return AC_ABILITY; - } else { + } else if (Blacksmith.Quest.oldMiningQuest()) { return AC_MINE; + } else { + return defaultAction; } }