v2.2.0: early impl for blacksmith quest granting

This commit is contained in:
Evan Debenham
2023-08-07 18:56:50 -04:00
parent f81fc2b1ed
commit 987053121d
4 changed files with 173 additions and 54 deletions

View File

@@ -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.

View File

@@ -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;

View File

@@ -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;
}
}
}

View File

@@ -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<String> actions( Hero hero ) {
ArrayList<String> 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;
}
}