From 1a35359edb096fec10b04b501b7e8699100dbff4 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Wed, 28 Jul 2021 19:55:15 -0400 Subject: [PATCH] v0.9.4: final implementation and polish on ankh behaviour --- .../assets/messages/actors/actors.properties | 6 +- .../assets/messages/items/items.properties | 4 +- .../assets/messages/scenes/scenes.properties | 1 + .../messages/windows/windows.properties | 6 +- .../shatteredpixeldungeon/items/Item.java | 4 +- .../items/LostBackpack.java | 2 + .../items/food/Blandfruit.java | 6 +- .../scenes/GameScene.java | 2 + .../windows/WndResurrect.java | 92 ++++++++++++++++--- 9 files changed, 96 insertions(+), 27 deletions(-) diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index 0b8f92986..295182911 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -214,6 +214,9 @@ actors.buffs.light.desc=Even in the Darkest Dungeon, a steady light at your side actors.buffs.lockedfloor.name=Floor is Locked actors.buffs.lockedfloor.desc=The current floor is locked, and you are unable to leave it!\n\nWhile a floor is locked, you will not gain hunger or take damage from starving. In addition, if you do not work towards defeating this floor's boss, passive regeneration effects will also stop.\n\nAdditionally, if you are revived by an unblessed ankh while the floor is locked, then it will reset.\n\nKill this floor's boss to break the lock. +actors.buffs.lostinventory.name=Lost Inventory +actors.buffs.lostinventory.desc=Your inventory has been lost somewhere in the dungeon! You don't be able to pick up or use most items until you retrieve it. + actors.buffs.magicalsight.name=Magical Sight actors.buffs.magicalsight.desc=Somehow you are able to see with your mind, rather than your eyes.\n\nAll terrain or effects which reduce or block vision are broken while magical sight is active.\n\nTurns of magical sight remaining: %s. @@ -236,9 +239,6 @@ actors.buffs.momentum.momentum_desc=As he moves, the Freerunner builds momentum, actors.buffs.momentum.running_desc=As he moves, the Freerunner builds momentum, which he can spend to start freerunning.\n\nWhile freerunning, the Freerunner moves at double speed and gains bonus evasion based on his level.\n\nTurns remaining: %d. actors.buffs.momentum.resting_desc=As he moves, the Freerunner builds momentum, which he can spend to start freerunning.\n\nThe Freerunner needs time to regain his stamina before building momentum again.\n\nTurns remaining: %d. -actors.buffs.noinventory.name=Lost Inventory -actors.buffs.noinventory.desc=TODO - actors.buffs.ooze.name=Caustic ooze actors.buffs.ooze.heromsg=Caustic ooze eats your flesh. Wash it away! actors.buffs.ooze.ondeath=You melt away... diff --git a/core/src/main/assets/messages/items/items.properties b/core/src/main/assets/messages/items/items.properties index 7c0e278b6..1308c4e47 100644 --- a/core/src/main/assets/messages/items/items.properties +++ b/core/src/main/assets/messages/items/items.properties @@ -1630,7 +1630,7 @@ items.amulet.desc=The Amulet of Yendor is the most powerful artifact known to hu items.ankh.name=ankh items.ankh.ac_bless=BLESS items.ankh.bless=You bless the ankh with magical water. -items.ankh.desc=This ancient symbol of immortality grants the ability to return to life after death. Upon resurrection all non-equipped items are lost. Using a full waterskin, the ankh can be blessed with extra strength. +items.ankh.desc=This ancient symbol of immortality grants the ability to return to life after death. Most equipment will be dropped where you died, but can be reclaimed if you return to it. Using a full waterskin, the ankh can be blessed with extra strength. items.ankh.desc_blessed=This ancient symbol of immortality grants the ability to return to life after death. The ankh has been blessed and is now much stronger. The Ankh will sacrifice itself to save you in a moment of deadly peril. items.arcaneresin.name=arcane resin @@ -1714,7 +1714,7 @@ items.liquidmetal.apply=You use %d liquid metal to repair your thrown weapon. items.liquidmetal.desc=When poured over a thrown weapon, this magical liquid will fill into the cracks and tears from use, restoring the thrown weapon to perfect condition!\n\nA tier 1 weapon requires 10 liquid metal to be fully repaired, a tier 5 weapon requires 30. Each upgrade also doubles the amount of metal needed.\n\nLiquid metal cannot be used to repair the tips on tipped darts. items.lostbackpack.name=lost backpack -items.lostbackpack.desc=TODO +items.lostbackpack.desc=This is your lost inventory. Collect it to reclaim all the items you lost! items.merchantsbeacon.name=merchant's beacon items.merchantsbeacon.ac_use=USE diff --git a/core/src/main/assets/messages/scenes/scenes.properties b/core/src/main/assets/messages/scenes/scenes.properties index 243dc4be6..f44f10cab 100644 --- a/core/src/main/assets/messages/scenes/scenes.properties +++ b/core/src/main/assets/messages/scenes/scenes.properties @@ -26,6 +26,7 @@ scenes.gamescene.spawner_warn=You feel that there's a source of demonic energy a scenes.gamescene.spawner_warn_final=You can feel demonic energy radiating here from the previous floors! scenes.gamescene.warp=The walls warp and shift around you! scenes.gamescene.return=You return to floor %d of the dungeon. +scenes.gamescene.resurrect=You materialize somewhere on floor %d. scenes.gamescene.secret_hint=You're certain that there's a secret room somewhere on this floor. scenes.gamescene.chasm=Your steps echo across the dungeon. scenes.gamescene.water=You hear water splashing around you. diff --git a/core/src/main/assets/messages/windows/windows.properties b/core/src/main/assets/messages/windows/windows.properties index 303b571bf..c124077aa 100644 --- a/core/src/main/assets/messages/windows/windows.properties +++ b/core/src/main/assets/messages/windows/windows.properties @@ -143,9 +143,9 @@ windows.wndranking$statstab.food=Food Eaten windows.wndranking$statstab.alchemy=Potions Cooked windows.wndranking$statstab.ankhs=Ankhs Used -windows.wndresurrect.message=You died, but you were given another chance to win this dungeon. Will you take it? -windows.wndresurrect.yes=Yes, I will fight! -windows.wndresurrect.no=No, I give up +windows.wndresurrect.title=Resurrection +windows.wndresurrect.message=As you perish you can feel your ankh guiding your spirit back toward this world. It's giving you another chance to conquer the dungeon!\n\nYou can bring two of your items with you, but the rest will be left where you perished. Which items will you choose? +windows.wndresurrect.confirm=Preserve these items windows.wndsadghost.rat_title=DEFEATED FETID RAT windows.wndsadghost.gnoll_title=DEFEATED GNOLL TRICKSTER diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Item.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Item.java index ce74b1dd5..720d60372 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Item.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Item.java @@ -132,7 +132,9 @@ public class Item implements Bundlable { } //resets an item's properties, to ensure consistency between runs - public void reset(){} + public void reset(){ + keptThoughLostInvent = false; + } public void doThrow( Hero hero ) { GameScene.selectCell(thrower); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/LostBackpack.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/LostBackpack.java index 081475855..c09c2d909 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/LostBackpack.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/LostBackpack.java @@ -5,6 +5,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LostInventory; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.watabou.noosa.audio.Sample; @@ -35,6 +36,7 @@ public class LostBackpack extends Item { Item.updateQuickslot(); Sample.INSTANCE.play( Assets.Sounds.DEWDROP ); hero.spendAndNext(TIME_TO_PICK_UP); + ((HeroSprite)hero.sprite).updateArmor(); return true; } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/Blandfruit.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/Blandfruit.java index 0f5db68cc..856375c81 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/Blandfruit.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/Blandfruit.java @@ -206,10 +206,10 @@ public class Blandfruit extends Food { @Override public void reset() { - if (potionAttrib != null) + super.reset(); + if (potionAttrib != null) { imbuePotion(potionAttrib); - else - super.reset(); + } } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java index 43b9ba7e3..4850728b8 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java @@ -474,6 +474,8 @@ public class GameScene extends PixelScene { } else if (InterlevelScene.mode == InterlevelScene.Mode.RESET) { GLog.h(Messages.get(this, "warp")); + } else if (InterlevelScene.mode == InterlevelScene.Mode.RESURRECT) { + GLog.h(Messages.get(this, "resurrect"), Dungeon.depth); } else { GLog.h(Messages.get(this, "return"), Dungeon.depth); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndResurrect.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndResurrect.java index e3eff6d18..cc2ea1366 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndResurrect.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndResurrect.java @@ -22,12 +22,13 @@ package com.shatteredpixel.shatteredpixeldungeon.windows; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; -import com.shatteredpixel.shatteredpixeldungeon.Rankings; import com.shatteredpixel.shatteredpixeldungeon.Statistics; -import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.items.Ankh; -import com.shatteredpixel.shatteredpixeldungeon.items.LostBackpack; +import com.shatteredpixel.shatteredpixeldungeon.items.EquipableItem; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; @@ -41,8 +42,17 @@ public class WndResurrect extends Window { private static final int WIDTH = 120; private static final int BTN_HEIGHT = 20; private static final float GAP = 2; - + private static final float BTN_GAP = 10; + + private static final int BTN_SIZE = 36; + public static WndResurrect instance; + + private WndBlacksmith.ItemButton btnItem1; + private WndBlacksmith.ItemButton btnItem2; + private WndBlacksmith.ItemButton btnPressed; + + RedButton btnContinue; public WndResurrect() { @@ -54,39 +64,91 @@ public class WndResurrect extends Window { IconTitle titlebar = new IconTitle(); titlebar.icon( new ItemSprite( ankh.image(), null ) ); - titlebar.label( Messages.titleCase(ankh.name()) ); + titlebar.label( Messages.titleCase(Messages.get(this, "title")) ); titlebar.setRect( 0, 0, WIDTH, 0 ); add( titlebar ); - RenderedTextBlock message = PixelScene.renderTextBlock( "TODO, need to add item selection here. Atm we just revive and all equipped items work", 6 ); + RenderedTextBlock message = PixelScene.renderTextBlock(Messages.get(this, "message"), 6 ); message.maxWidth(WIDTH); message.setPos(0, titlebar.bottom() + GAP); add( message ); + + btnItem1 = new WndBlacksmith.ItemButton() { + @Override + protected void onClick() { + btnPressed = btnItem1; + GameScene.selectItem( itemSelector ); + } + }; + btnItem1.item(Dungeon.hero.belongings.weapon()); + btnItem1.setRect( (WIDTH - BTN_GAP) / 2 - BTN_SIZE, message.bottom() + BTN_GAP, BTN_SIZE, BTN_SIZE ); + add( btnItem1 ); + + btnItem2 = new WndBlacksmith.ItemButton() { + @Override + protected void onClick() { + btnPressed = btnItem2; + GameScene.selectItem( itemSelector ); + } + }; + btnItem2.item(Dungeon.hero.belongings.armor()); + btnItem2.setRect( btnItem1.right() + BTN_GAP, btnItem1.top(), BTN_SIZE, BTN_SIZE ); + add( btnItem2 ); - RedButton btnYes = new RedButton( Messages.get(this, "yes") ) { + btnContinue = new RedButton( Messages.get(this, "confirm") ) { @Override protected void onClick() { hide(); Statistics.ankhsUsed++; - //TODO let the player choose their items, instead of rigid weapon or armor - if (Dungeon.hero.belongings.weapon() != null){ - Dungeon.hero.belongings.weapon().keptThoughLostInvent = true; + if (btnItem1.item != null){ + btnItem1.item.keptThoughLostInvent = true; } - if (Dungeon.hero.belongings.armor() != null){ - Dungeon.hero.belongings.armor().keptThoughLostInvent = true; + if (btnItem2.item != null){ + btnItem2.item.keptThoughLostInvent = true; } InterlevelScene.mode = InterlevelScene.Mode.RESURRECT; Game.switchScene( InterlevelScene.class ); } }; - btnYes.setRect( 0, message.top() + message.height() + GAP, WIDTH, BTN_HEIGHT ); - add( btnYes ); + btnContinue.setRect( 0, btnItem1.bottom() + BTN_GAP, WIDTH, BTN_HEIGHT ); + add( btnContinue ); - resize( WIDTH, (int)btnYes.bottom() ); + resize( WIDTH, (int)btnContinue.bottom() ); } + + protected WndBag.ItemSelector itemSelector = new WndBag.ItemSelector() { + + @Override + public String textPrompt() { + return "TODO"; + } + + @Override + public boolean itemSelectable(Item item) { + //cannot select ankhs or equippable items that aren't equipped + return !(item instanceof Ankh) && + (!(item instanceof EquipableItem) || item.isEquipped(Dungeon.hero) || item instanceof MissileWeapon); + } + + @Override + public void onSelect( Item item ) { + if (item != null && btnPressed.parent != null) { + btnPressed.item( item ); + + if (btnItem1.item == btnItem2.item){ + if (btnPressed == btnItem1){ + btnItem2.item(null); + } else { + btnItem1.item(null); + } + } + + } + } + }; @Override public void destroy() {