v2.5.0: added a new window for confirming upgrades (some stats missing)

This commit is contained in:
Evan Debenham
2024-06-21 12:00:42 -04:00
parent 351a74c567
commit 40e7a4093f
16 changed files with 580 additions and 41 deletions

View File

@@ -1019,7 +1019,7 @@ items.scrolls.scroll.no_magic=You can't read a scroll while magic immune.
items.scrolls.scroll.cursed=Your cursed spellbook prevents you from invoking this scroll's magic! A scroll of remove curse might be strong enough to still work though...
items.scrolls.scroll$placeholder.name=scroll
items.scrolls.inventoryscroll.warning=Do you really want to cancel this scroll usage? It will be consumed anyway.
items.scrolls.inventoryscroll.warning=Do you really want to cancel this scroll usage? The scroll wasn't previously identified, so it will be consumed anyway.
items.scrolls.inventoryscroll.yes=Yes, I'm positive
items.scrolls.inventoryscroll.no=No, I changed my mind

View File

@@ -346,6 +346,28 @@ windows.wndtradeitem.sell=Sell for %dg
windows.wndtradeitem.sell_1=Sell 1 for %dg
windows.wndtradeitem.sell_all=Sell all for %dg
windows.wndupgrade.title=Upgrade an Item
windows.wndupgrade.desc=Upgrading an item permanently boosts its power:
windows.wndupgrade.unided=You don't know the properties of this unidentified item, its un-upgraded state is shown here.
windows.wndupgrade.cursed=Upgrading this item also has a 33% chance to cleanse its curse.
windows.wndupgrade.cursed_weaken=Upgrading this item will also weaken its curse, and has a 33% chance to cleanse the curse entirely.
windows.wndupgrade.curse_infusion=If the curse is cleansed, the item will no longer benefit from curse infusion!
windows.wndupgrade.enchant=Upgrading this item also has a %d%% chance to destroy its enchantment!
windows.wndupgrade.glyph=Upgrading this item also has a %d%% chance to destroy its glyph!
windows.wndupgrade.harden=Upgrading this item also has a %d%% chance to break its hardening!
windows.wndupgrade.resin=This wand has been enhanced with arcane resin, normal upgrades will override resin upgrades!
windows.wndupgrade.damage=Damage
windows.wndupgrade.blocking=Blocking
windows.wndupgrade.weight=Weight
windows.wndupgrade.durability=Durability
windows.wndupgrade.zap_damage=Zap Damage
windows.wndupgrade.corrosion_damage=Corrosion Damage
windows.wndupgrade.ward_damage=Ward Damage
windows.wndupgrade.charges=Max Charges
windows.wndupgrade.ring_boost=Ring Boost
windows.wndupgrade.upgrade=Upgrade
windows.wndupgrade.cancel=Cancel
windows.wndwandmaker.dust=Oh, I see you have the dust! Don't worry about the wraiths, I can deal with them. As I promised, you can choose one of my high quality wands.
windows.wndwandmaker.ember=Oh, I see you have the embers! I do hope the fire elemental wasn't too much trouble. As I promised, you can choose one of my high quality wands.
windows.wndwandmaker.berry=Oh, I see you have the berry! I do hope the rotberry plant didn't trouble you too much. As I promised, you can choose one of my high quality wands.

View File

@@ -588,17 +588,17 @@ public class Armor extends EquipableItem {
}
public int STRReq(){
int req = STRReq(level());
return STRReq(level());
}
public int STRReq(int lvl){
int req = STRReq(tier, lvl);
if (masteryPotionBonus){
req -= 2;
}
return req;
}
public int STRReq(int lvl){
return STRReq(tier, lvl);
}
protected static int STRReq(int tier, int lvl){
lvl = Math.max(0, lvl);

View File

@@ -115,9 +115,12 @@ public abstract class InventoryScroll extends Scroll {
curItem = detach(curUser.belongings.backpack);
}
((InventoryScroll)curItem).onItemSelected( item );
((InventoryScroll)curItem).readAnimation();
Sample.INSTANCE.play( Assets.Sounds.READ );
//SoU still does these things, but after the upgrade window
if (!(curItem instanceof ScrollOfUpgrade)) {
((InventoryScroll) curItem).readAnimation();
Sample.INSTANCE.play(Assets.Sounds.READ);
}
} else if (identifiedByUse && !((Scroll)curItem).anonymous) {

View File

@@ -183,7 +183,7 @@ public abstract class Scroll extends Item {
public abstract void doRead();
protected void readAnimation() {
public void readAnimation() {
Invisibility.dispel();
curUser.spend( TIME_TO_READ );
curUser.busy();

View File

@@ -36,8 +36,10 @@ import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndUpgrade;
public class ScrollOfUpgrade extends InventoryScroll {
@@ -58,6 +60,11 @@ public class ScrollOfUpgrade extends InventoryScroll {
@Override
protected void onItemSelected( Item item ) {
GameScene.show(new WndUpgrade(this, item, identifiedByUse));
}
public Item upgradeItem( Item item ){
upgrade( curUser );
Degrade.detach( curUser, Degrade.class );
@@ -71,7 +78,7 @@ public class ScrollOfUpgrade extends InventoryScroll {
boolean hadCursedEnchant = w.hasCurseEnchant();
boolean hadGoodEnchant = w.hasGoodEnchant();
w.upgrade();
item = w.upgrade();
if (w.cursedKnown && hadCursedEnchant && !w.hasCurseEnchant()){
removeCurse( Dungeon.hero );
@@ -91,7 +98,7 @@ public class ScrollOfUpgrade extends InventoryScroll {
boolean hadCursedGlyph = a.hasCurseGlyph();
boolean hadGoodGlyph = a.hasGoodGlyph();
a.upgrade();
item = a.upgrade();
if (a.cursedKnown && hadCursedGlyph && !a.hasCurseGlyph()){
removeCurse( Dungeon.hero );
@@ -107,22 +114,24 @@ public class ScrollOfUpgrade extends InventoryScroll {
} else if (item instanceof Wand || item instanceof Ring) {
boolean wasCursed = item.cursed;
item.upgrade();
item = item.upgrade();
if (item.cursedKnown && wasCursed && !item.cursed){
removeCurse( Dungeon.hero );
}
} else {
item.upgrade();
item = item.upgrade();
}
Badges.validateItemLevelAquired( item );
Statistics.upgradesUsed++;
Badges.validateMageUnlock();
Catalog.countUse(item.getClass());
Catalog.countUse(getClass());
Catalog.countUse(ScrollOfUpgrade.class);
return item;
}
public static void upgrade( Hero hero ) {

View File

@@ -84,16 +84,19 @@ public abstract class InventorySpell extends Spell {
curItem = detach(curUser.belongings.backpack);
((InventorySpell)curItem).onItemSelected( item );
curUser.spend( 1f );
curUser.busy();
(curUser.sprite).operate( curUser.pos );
Sample.INSTANCE.play( Assets.Sounds.READ );
Invisibility.dispel();
//Magical Infusion still does these things, but after the upgrade window
if (!(curItem instanceof MagicalInfusion)) {
curUser.spend(1f);
curUser.busy();
(curUser.sprite).operate(curUser.pos);
Catalog.countUse(curItem.getClass());
if (Random.Float() < ((Spell)curItem).talentChance){
Talent.onScrollUsed(curUser, curUser.pos, ((Spell)curItem).talentFactor);
Sample.INSTANCE.play(Assets.Sounds.READ);
Invisibility.dispel();
Catalog.countUse(curItem.getClass());
if (Random.Float() < ((Spell) curItem).talentChance) {
Talent.onScrollUsed(curUser, curUser.pos, ((Spell) curItem).talentFactor);
}
}
}

View File

@@ -21,9 +21,12 @@
package com.shatteredpixel.shatteredpixeldungeon.items.spells;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Degrade;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
@@ -31,8 +34,12 @@ import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndUpgrade;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Random;
public class MagicalInfusion extends InventorySpell {
@@ -52,22 +59,41 @@ public class MagicalInfusion extends InventorySpell {
@Override
protected void onItemSelected( Item item ) {
GameScene.show(new WndUpgrade(this, item, false));
}
public void useAnimation(){
curUser.spend(1f);
curUser.busy();
(curUser.sprite).operate(curUser.pos);
Sample.INSTANCE.play(Assets.Sounds.READ);
Invisibility.dispel();
Catalog.countUse(curItem.getClass());
if (Random.Float() < ((Spell) curItem).talentChance) {
Talent.onScrollUsed(curUser, curUser.pos, ((Spell) curItem).talentFactor);
}
}
public Item upgradeItem( Item item ){
ScrollOfUpgrade.upgrade(curUser);
Degrade.detach( curUser, Degrade.class );
if (item instanceof Weapon && ((Weapon) item).enchantment != null) {
((Weapon) item).upgrade(true);
item = ((Weapon) item).upgrade(true);
} else if (item instanceof Armor && ((Armor) item).glyph != null) {
((Armor) item).upgrade(true);
item = ((Armor) item).upgrade(true);
} else {
boolean wasCursed = item.cursed;
boolean wasCurseInfused = item instanceof Wand && ((Wand) item).curseInfusionBonus;
item.upgrade();
item = item.upgrade();
if (wasCursed) item.cursed = true;
if (wasCurseInfused) ((Wand) item).curseInfusionBonus = true;
}
GLog.p( Messages.get(this, "infuse") );
Badges.validateItemLevelAquired(item);
@@ -75,6 +101,8 @@ public class MagicalInfusion extends InventorySpell {
Catalog.countUse(getClass());
Statistics.upgradesUsed++;
return item;
}
@Override

View File

@@ -377,7 +377,7 @@ public abstract class Wand extends Item {
curCharges = Math.min( curCharges, maxCharges );
}
protected int initialCharges() {
public int initialCharges() {
return 2;
}

View File

@@ -87,8 +87,8 @@ public class WandOfMagicMissile extends DamageWand {
}
}
protected int initialCharges() {
public int initialCharges() {
return 3;
}

View File

@@ -261,11 +261,7 @@ abstract public class Weapon extends KindOfWeapon {
}
public int STRReq(){
int req = STRReq(level());
if (masteryPotionBonus){
req -= 2;
}
return req;
return STRReq(level());
}
public abstract int STRReq(int lvl);

View File

@@ -52,7 +52,11 @@ public class Greataxe extends MeleeWeapon {
@Override
public int STRReq(int lvl) {
return STRReq(tier+1, lvl); //20 base strength req, up from 18
int req = STRReq(tier+1, lvl); //20 base strength req, up from 18
if (masteryPotionBonus){
req -= 2;
}
return req;
}
@Override

View File

@@ -42,7 +42,16 @@ public class Greatshield extends MeleeWeapon {
@Override
public int defenseFactor( Char owner ) {
return 6+2*buffedLvl(); //6 extra defence, plus 2 per level
return DRMax();
}
public int DRMax(){
return DRMax(buffedLvl());
}
//6 extra defence, plus 2 per level
public int DRMax(int lvl){
return 6 + 2*lvl;
}
public String statsInfo(){

View File

@@ -263,7 +263,11 @@ public class MeleeWeapon extends Weapon {
}
public int STRReq(int lvl){
return STRReq(tier, lvl);
int req = STRReq(tier, lvl);
if (masteryPotionBonus){
req -= 2;
}
return req;
}
private static boolean evaluatingTwinUpgrades = false;

View File

@@ -51,7 +51,16 @@ public class RoundShield extends MeleeWeapon {
@Override
public int defenseFactor( Char owner ) {
return 4+buffedLvl(); //4 extra defence, plus 1 per level
return DRMax();
}
public int DRMax(){
return DRMax(buffedLvl());
}
//4 extra defence, plus 1 per level
public int DRMax(int lvl){
return 4 + lvl;
}
public String statsInfo(){

View File

@@ -0,0 +1,452 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2024 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.windows;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.InventoryScroll;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.MagicalInfusion;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.DamageWand;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfCorrosion;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfWarding;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Greatshield;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.RoundShield;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
import com.shatteredpixel.shatteredpixeldungeon.messages.Languages;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.ItemSlot;
import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
import com.watabou.noosa.BitmapText;
import com.watabou.noosa.ColorBlock;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Reflection;
public class WndUpgrade extends Window {
private static final int WIDTH = 120;
private static final float COL_1 = WIDTH/4f;
private static final float COL_2 = 5*WIDTH/8f;
private static final float COL_3 = 7*WIDTH/8f;
protected static final int GAP = 2;
private boolean force;
private RedButton btnUpgrade;
private RedButton btnCancel;
public WndUpgrade( Item upgrader, Item toUpgrade, boolean force){
this.force = force;
IconTitle title = new IconTitle( new ItemSprite(upgrader), Messages.get(this, "title") );
title.setRect(0, 0, WIDTH, 0);
add(title);
RenderedTextBlock message = PixelScene.renderTextBlock( 6 );
message.text( Messages.get(this, "desc"), WIDTH);
message.setPos(0, title.bottom()+GAP);
add(message);
// *** Computing current and next level to display ***
int levelFrom = toUpgrade.isIdentified() ? toUpgrade.level() : 0;
int levelTo = levelFrom + 1;
if (toUpgrade instanceof Wand && ((Wand) toUpgrade).resinBonus > 0){
levelTo--;
}
boolean curseInfused = (toUpgrade instanceof Weapon && ((Weapon) toUpgrade).curseInfusionBonus)
|| (toUpgrade instanceof Armor && ((Armor) toUpgrade).curseInfusionBonus)
|| (toUpgrade instanceof Wand && ((Wand) toUpgrade).curseInfusionBonus);
if (curseInfused){
if (toUpgrade.trueLevel()/6 < (toUpgrade.trueLevel()+1)/6){
//new level bracket for curse infusion bonus
levelTo++;
}
}
// *** Sprites, showing item at current level and with +1 ***
ItemSprite i1 = new ItemSprite();
add(i1);
i1.view(toUpgrade);
i1.x = COL_2 - i1.width()/2f;
i1.y = message.bottom() + GAP + (16-i1.height())/2f;
PixelScene.align(i1);
add(i1);
ItemSprite i2 = new ItemSprite();
add(i2);
i2.view(toUpgrade);
i2.x = COL_3 - i2.width()/2f;
i2.y = i1.y;
PixelScene.align(i2);
add(i2);
BitmapText t1 = new BitmapText(PixelScene.pixelFont);
BitmapText t2 = new BitmapText(PixelScene.pixelFont);
if (toUpgrade.isIdentified()){
if (levelFrom > 0){
t1.text("+" + levelFrom);
} else {
t1.text("");
}
t1.hardlight(ItemSlot.UPGRADED);
t2.text("+" + levelTo);
t2.hardlight(ItemSlot.UPGRADED);
if (curseInfused){
t1.hardlight(ItemSlot.CURSE_INFUSED);
t2.hardlight(ItemSlot.CURSE_INFUSED);
}
} else {
t1.text("?");
t1.hardlight(0.6f, 0.3f, 0.6f);
t2.text("+1?");
t2.hardlight(0.6f, 0.3f, 0.6f);
}
t1.measure();
t1.x = COL_2 + 8 - t1.width();
t1.y = message.bottom() + GAP + 16 - t1.baseLine();
add(t1);
t2.measure();
t2.x = COL_3 + 8 - t2.width();
t2.y = message.bottom() + GAP + 16 - t2.baseLine();
add(t2);
float bottom = i1.y + 16 + GAP;
final String LINE = Messages.lang() == Languages.CHINESE ? "~" : "-";
// *** Various lines for stats, highlighting differences between current level and +1 ***
//physical damage
if (toUpgrade instanceof Weapon){
bottom = fillFields(Messages.get(this, "damage"),
((Weapon) toUpgrade).min(levelFrom) + LINE + ((Weapon) toUpgrade).max(levelFrom),
((Weapon) toUpgrade).min(levelTo) + LINE + ((Weapon) toUpgrade).max(levelTo),
bottom);
}
//blocking (armor and shields)
if (toUpgrade instanceof Armor){
bottom = fillFields(Messages.get(this, "blocking"),
((Armor) toUpgrade).DRMin(levelFrom) + LINE + ((Armor) toUpgrade).DRMax(levelFrom),
((Armor) toUpgrade).DRMin(levelTo) + LINE + ((Armor) toUpgrade).DRMax(levelTo),
bottom);
} else if (toUpgrade instanceof RoundShield){
bottom = fillFields(Messages.get(this, "blocking"),
0 + LINE + ((RoundShield) toUpgrade).DRMax(levelFrom),
0 + LINE + ((RoundShield) toUpgrade).DRMax(levelTo),
bottom);
} else if (toUpgrade instanceof Greatshield){
bottom = fillFields(Messages.get(this, "blocking"),
0 + LINE + ((Greatshield) toUpgrade).DRMax(levelFrom),
0 + LINE + ((Greatshield) toUpgrade).DRMax(levelTo),
bottom);
}
//weight (i.e. strength requirement)
if (toUpgrade instanceof Weapon){
bottom = fillFields(Messages.get(this, "weight"),
Integer.toString((((Weapon) toUpgrade).STRReq(levelFrom))),
Integer.toString((((Weapon) toUpgrade).STRReq(levelTo))),
bottom);
} else if (toUpgrade instanceof Armor) {
bottom = fillFields(Messages.get(this, "weight"),
Integer.toString((((Armor) toUpgrade).STRReq(levelFrom))),
Integer.toString((((Armor) toUpgrade).STRReq(levelTo))),
bottom);
}
//durability
if (toUpgrade instanceof MissileWeapon){
//missile weapons are always IDed currently, so we always use true level
int uses1 = (int)Math.ceil(100f/((MissileWeapon) toUpgrade).durabilityPerUse());
int uses2 = (int)Math.ceil(300f/((MissileWeapon) toUpgrade).durabilityPerUse());
bottom = fillFields(Messages.get(this, "durability"),
uses1 >= 100 ? "" : Integer.toString(uses1),
uses2 >= 100 ? "" : Integer.toString(uses2),
bottom);
}
//we use a separate reference for wand properties so that mage's staff can include them
Item wand = toUpgrade;
if (toUpgrade instanceof MagesStaff && ((MagesStaff) toUpgrade).wandClass() != null){
wand = Reflection.newInstance(((MagesStaff) toUpgrade).wandClass());
}
//direct damage and damage-adjacent effects
if (wand instanceof DamageWand) {
bottom = fillFields(Messages.get(this, "zap_damage"),
((DamageWand) wand).min(levelFrom) + LINE + ((DamageWand) wand).max(levelFrom),
((DamageWand) wand).min(levelTo) + LINE + ((DamageWand) wand).max(levelTo),
bottom);
} else if (wand instanceof WandOfCorrosion){
//TODO externalize!
bottom = fillFields(Messages.get(this, "corrosion_damage"),
Integer.toString(2+levelFrom),
Integer.toString(2+levelTo),
bottom);
} else if (wand instanceof WandOfWarding){
//TODO externalize!
bottom = fillFields(Messages.get(this, "ward_damage"),
(2 + levelFrom) + LINE + (8 + 4*levelFrom),
(2 + levelTo) + LINE + (8 + 4*levelTo),
bottom);
}
//TODO various extra wand effects
//disintegration range?
//corrosion AOE?
//blast wave knockback?
//rock guardian powers?
//frost chill duration?
//prismatic light blinding/lighting?
//warding max energy
//transfusion stats? and also de-emphasize damage?
//corruption power?
//regrowth power?
//max charges
if (wand instanceof Wand){
int chargeboost = levelFrom + (toUpgrade instanceof MagesStaff ? 1 : 0);
bottom = fillFields(Messages.get(this, "charges"),
Integer.toString(Math.min(10, ((Wand) wand).initialCharges() + chargeboost)),
Integer.toString(Math.min(10, ((Wand) wand).initialCharges() + chargeboost + 1)),
bottom);
}
//TODO ring stats
if (toUpgrade instanceof Ring){
}
//visual separators for each column
ColorBlock sep = new ColorBlock(1, 1, 0xFF222222);
sep.size(1, bottom - message.bottom());
sep.x = WIDTH/2f;
sep.y = message.bottom();
add(sep);
sep = new ColorBlock(1, 1, 0xFF222222);
sep.size(1, bottom - message.bottom());
sep.x = 3*WIDTH/4f;
sep.y = message.bottom();
add(sep);
// *** Various extra info texts that can appear underneath stats ***
//warning relating to identification
if (!toUpgrade.isIdentified()){
bottom = addMessage(Messages.get(this, "unided"), CharSprite.WARNING, bottom);
}
// various messages relating to enchantments and curses
if (!(upgrader instanceof MagicalInfusion)) {
if ((toUpgrade instanceof Weapon && ((Weapon) toUpgrade).hasGoodEnchant())
|| (toUpgrade instanceof Armor && ((Armor) toUpgrade).hasGoodGlyph())) {
int lossChance;
if ((toUpgrade instanceof Weapon && ((Weapon) toUpgrade).enchantHardened)
|| (toUpgrade instanceof Armor && ((Armor) toUpgrade).glyphHardened)) {
lossChance = Math.min(100, 10 * (int) Math.pow(2, levelFrom - 6));
} else {
lossChance = Math.min(100, 10 * (int) Math.pow(2, levelFrom - 4));
}
if (lossChance >= 10) {
String warn;
if (toUpgrade instanceof Weapon) {
if (((Weapon) toUpgrade).enchantHardened) {
warn = Messages.get(this, "harden", lossChance);
} else {
warn = Messages.get(this, "enchant", lossChance);
}
} else {
if (((Armor) toUpgrade).glyphHardened) {
warn = Messages.get(this, "harden", lossChance);
} else {
warn = Messages.get(this, "glyph", lossChance);
}
}
bottom = addMessage(warn, CharSprite.WARNING, bottom);
}
}
if ((toUpgrade.cursed
|| (toUpgrade instanceof Weapon && ((Weapon) toUpgrade).hasCurseEnchant())
|| (toUpgrade instanceof Armor && ((Armor) toUpgrade).hasCurseGlyph()))
&& toUpgrade.cursedKnown) {
if (toUpgrade.cursed && (toUpgrade instanceof Weapon && ((Weapon) toUpgrade).hasCurseEnchant())
|| (toUpgrade instanceof Armor && ((Armor) toUpgrade).hasCurseGlyph())){
bottom = addMessage(Messages.get(this, "cursed_weaken"), CharSprite.POSITIVE, bottom);
} else {
bottom = addMessage(Messages.get(this, "cursed"), CharSprite.POSITIVE, bottom);
}
if (curseInfused) {
bottom = addMessage(Messages.get(this, "curse_infusion"), CharSprite.WARNING, bottom);
}
}
}
//warning relating to arcane resin
if (toUpgrade instanceof Wand && ((Wand) toUpgrade).resinBonus > 0){
bottom = addMessage(Messages.get(this, "resin"), CharSprite.WARNING, bottom);
}
// *** Buttons for confirming/cancelling ***
btnUpgrade = new RedButton(Messages.get(this, "upgrade")){
@Override
protected void onClick() {
super.onClick();
ScrollOfUpgrade.upgrade(Dungeon.hero);
Item upgraded = toUpgrade;
if (upgrader instanceof ScrollOfUpgrade){
((ScrollOfUpgrade) upgrader).readAnimation();
upgraded = ((ScrollOfUpgrade) upgrader).upgradeItem(toUpgrade);
Sample.INSTANCE.play( Assets.Sounds.READ );
} else if (upgrader instanceof MagicalInfusion){
((MagicalInfusion) upgrader).useAnimation();
upgraded = ((MagicalInfusion) upgrader).upgradeItem(toUpgrade);
}
Item moreUpgradeItem = Dungeon.hero.belongings.getItem(upgrader.getClass());
hide();
if (moreUpgradeItem != null && toUpgrade.isIdentified()){
moreUpgradeItem = moreUpgradeItem.detach(Dungeon.hero.belongings.backpack);
GameScene.show(new WndUpgrade(moreUpgradeItem, upgraded, false));
}
}
};
btnUpgrade.setRect(0, bottom+2*GAP, WIDTH/2f, 16);
add(btnUpgrade);
btnCancel = new RedButton(Messages.get(this, "cancel")){
@Override
protected void onClick() {
super.onClick();
if (!force) {
upgrader.collect();
hide();
} else {
GameScene.show( new WndOptions(new ItemSprite(upgrader),
Messages.titleCase(upgrader.name()),
Messages.get(InventoryScroll.class, "warning"),
Messages.get(InventoryScroll.class, "yes"),
Messages.get(InventoryScroll.class, "no") ) {
@Override
protected void onSelect( int index ) {
if (index == 0){
WndUpgrade.this.hide();
}
}
public void onBackPressed() {}
} );
}
}
};
btnCancel.setRect(btnUpgrade.right()+1, bottom+2*GAP, WIDTH/2f, 16);
add(btnCancel);
btnUpgrade.enable(Dungeon.hero.ready);
bottom = (int)btnCancel.bottom();
resize(WIDTH, (int)bottom);
}
@Override
public synchronized void update() {
super.update();
if (!btnUpgrade.active && Dungeon.hero.ready){
btnUpgrade.enable(true);
}
}
@Override
public void onBackPressed() {
//don't let this window be closed if
if (!force) super.onBackPressed();
}
private float fillFields(String title, String msg1, String msg2, float bottom){
RenderedTextBlock ttl = PixelScene.renderTextBlock( title , 6);
ttl.setPos(COL_1 - ttl.width() / 2f, bottom + GAP);
PixelScene.align(ttl);
add(ttl);
RenderedTextBlock m1 = PixelScene.renderTextBlock(msg1, 6);
m1.setPos(COL_2 - m1.width() / 2f, ttl.top());
PixelScene.align(m1);
add(m1);
RenderedTextBlock m2 = PixelScene.renderTextBlock(msg2, 6);
m2.setPos(COL_3 - m2.width() / 2f, ttl.top());
PixelScene.align(m2);
add(m2);
return m2.bottom() + GAP + 1;
}
private float addMessage(String text, int color, float bottom){
RenderedTextBlock message = PixelScene.renderTextBlock(6);
message.text(text, WIDTH);
message.setPos(0, bottom + GAP);
message.hardlight(color);
add(message);
return message.bottom();
}
}