v0.9.4: implemented arcane resin

This commit is contained in:
Evan Debenham 2021-07-20 14:43:02 -04:00
parent 849c25d3e5
commit f97abe0ff2
7 changed files with 214 additions and 13 deletions

View File

@ -1140,6 +1140,8 @@ items.wands.wand.fizzles=Your wand fizzles; it must not have enough charge.
items.wands.wand.no_magic=Your wand fizzles; you cannot use wands while magic immune.
items.wands.wand.self_target=You can't target yourself!
items.wands.wand.identify=You are now familiar enough with your wand to identify it.
items.wands.wand.resin_one=This wand has gained _1 level_ from arcane resin.
items.wands.wand.resin_many=This wand has gained _%d levels_ from arcane resin.
items.wands.wand.cursed=This wand is cursed, making its magic chaotic and random.
items.wands.wand.not_cursed=This wand is free of malevolent magic.
items.wands.wand.curse_discover=This %s is cursed!
@ -1629,6 +1631,13 @@ 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_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
items.arcaneresin.ac_apply=APPLY
items.arcaneresin.level_too_high=That wand is too powerful for resin to improve.
items.arcaneresin.not_enough=You don't have enough resin for that!
items.arcaneresin.apply=You coat your wand with resin, increasing its power!
items.arcaneresin.desc=This fine powder shimmers between shades of purple and white. It can act as an amplifier to magical energies, increasing the level of wands when it is applied to them!\n\nUpgrading a wand costs 1, 2, or 3 resin depending on the wand's initial level. Resin can upgrade wands to a maximum of +3.\n\nResin upgrades are overridden by scrolls of upgrade and similar items, and do not apply when imbuing a wand into the Mage's staff.
items.brokenseal.name=broken seal
items.brokenseal.ac_affix=AFFIX
items.brokenseal.prompt=Select an armor

View File

@ -187,12 +187,16 @@ public class WaterOfTransmutation extends WellWater {
n.level( 0 );
int level = w.level();
if (w.curseInfusionBonus) level--;
level -= n.resinBonus;
n.upgrade( level );
n.levelKnown = w.levelKnown;
n.cursedKnown = w.cursedKnown;
n.cursed = w.cursed;
n.curseInfusionBonus = w.curseInfusionBonus;
n.resinBonus = w.resinBonus;
n.updateLevel();
return n;
}

View File

@ -0,0 +1,154 @@
package com.shatteredpixel.shatteredpixeldungeon.items;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.MagicalHolster;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
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.WndBag;
import com.watabou.noosa.audio.Sample;
import java.util.ArrayList;
public class ArcaneResin extends Item {
{
image = ItemSpriteSheet.ARCANE_RESIN;
stackable = true;
defaultAction = AC_APPLY;
bones = true;
}
private static final String AC_APPLY = "APPLY";
@Override
public ArrayList<String> actions(Hero hero ) {
ArrayList<String> actions = super.actions( hero );
actions.add( AC_APPLY );
return actions;
}
@Override
public void execute( Hero hero, String action ) {
super.execute( hero, action );
if (action.equals(AC_APPLY)) {
curUser = hero;
GameScene.selectItem( itemSelector );
}
}
@Override
public boolean isUpgradable() {
return false;
}
@Override
public boolean isIdentified() {
return true;
}
@Override
public int value() {
return 30*quantity();
}
private final WndBag.ItemSelector itemSelector = new WndBag.ItemSelector() {
@Override
public String textPrompt() {
return Messages.get(LiquidMetal.class, "prompt");
}
@Override
public Class<?extends Bag> preferredBag(){
return MagicalHolster.class;
}
@Override
public boolean itemSelectable(Item item) {
return item instanceof Wand && item.isIdentified();
}
@Override
public void onSelect( Item item ) {
if (item != null && item instanceof Wand) {
Wand w = (Wand)item;
if (w.level() >= 3){
GLog.w(Messages.get(ArcaneResin.class, "level_too_high"));
return;
}
int resinToUse = w.level()+1;
if (quantity() < resinToUse){
GLog.w(Messages.get(ArcaneResin.class, "not_enough"));
} else {
if (resinToUse < quantity()){
quantity(quantity()-resinToUse);
} else {
detachAll(Dungeon.hero.belongings.backpack);
}
w.resinBonus++;
w.curCharges++;
w.updateLevel();
Item.updateQuickslot();
curUser.sprite.operate(curUser.pos);
Sample.INSTANCE.play(Assets.Sounds.TELEPORT);
curUser.sprite.emitter().start( Speck.factory( Speck.UP ), 0.2f, 3 );
curUser.spendAndNext(Actor.TICK);
GLog.p(Messages.get(ArcaneResin.class, "apply"));
}
}
}
};
public static class Recipe extends com.shatteredpixel.shatteredpixeldungeon.items.Recipe {
@Override
public boolean testIngredients(ArrayList<Item> ingredients) {
return ingredients.size() == 1 && ingredients.get(0) instanceof Wand && ingredients.get(0).isIdentified();
}
@Override
public int cost(ArrayList<Item> ingredients) {
return 5;
}
@Override
public Item brew(ArrayList<Item> ingredients) {
Item result = sampleOutput(ingredients);
ingredients.get(0).quantity(0);
return result;
}
@Override
public Item sampleOutput(ArrayList<Item> ingredients) {
Wand w = (Wand)ingredients.get(0);
int level = w.level() - w.resinBonus;
return new ArcaneResin().quantity(2*(level+1));
}
}
}

View File

@ -172,6 +172,7 @@ public abstract class Recipe {
private static Recipe[] oneIngredientRecipes = new Recipe[]{
new AlchemistsToolkit.upgradeKit(),
new Scroll.ScrollToStone(),
new ArcaneResin.Recipe(),
new StewedMeat.oneMeat()
};
@ -248,8 +249,9 @@ public abstract class Recipe {
public static boolean usableInRecipe(Item item){
return !item.cursed
&& (!(item instanceof EquipableItem) || (item instanceof AlchemistsToolkit && item.isIdentified()) || item instanceof MissileWeapon)
&& !(item instanceof Wand);
&& (!(item instanceof EquipableItem)
|| (item instanceof AlchemistsToolkit && item.isIdentified())
|| item instanceof MissileWeapon);
}
}

View File

@ -221,12 +221,16 @@ public class ScrollOfTransmutation extends InventoryScroll {
n.level( 0 );
int level = w.level();
if (w.curseInfusionBonus) level--;
level -= n.resinBonus;
n.upgrade( level );
n.levelKnown = w.levelKnown;
n.cursedKnown = w.cursedKnown;
n.cursed = w.cursed;
n.curseInfusionBonus = w.curseInfusionBonus;
n.resinBonus = w.resinBonus;
n.updateLevel();
return n;
}

View File

@ -50,6 +50,8 @@ import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
@ -75,7 +77,8 @@ public abstract class Wand extends Item {
private boolean curChargeKnown = false;
public boolean curseInfusionBonus = false;
public int resinBonus = 0;
private static final int USES_TO_ID = 10;
private float usesLeftToID = USES_TO_ID;
private float availableUsesToID = USES_TO_ID/2f;
@ -236,6 +239,12 @@ public abstract class Wand extends Item {
desc += "\n\n" + statsDesc();
if (resinBonus == 1){
desc += "\n\n" + Messages.get(Wand.class, "resin_one");
} else if (resinBonus > 1){
desc += "\n\n" + Messages.get(Wand.class, "resin_many", resinBonus);
}
if (cursed && cursedKnown) {
desc += "\n\n" + Messages.get(Wand.class, "cursed");
} else if (!isIdentified() && cursedKnown){
@ -273,7 +282,7 @@ public abstract class Wand extends Item {
curseInfusionBonus = false;
updateLevel();
}
return super.level() + (curseInfusionBonus ? 1 : 0);
return super.level() + resinBonus + (curseInfusionBonus ? 1 : 0);
}
@Override
@ -285,6 +294,10 @@ public abstract class Wand extends Item {
cursed = false;
}
if (resinBonus > 0){
resinBonus--;
}
updateLevel();
curCharges = Math.min( curCharges + 1, maxCharges );
updateQuickslot();
@ -425,7 +438,14 @@ public abstract class Wand extends Item {
return this;
}
@Override
public ItemSprite.Glowing glowing() {
if (resinBonus == 0) return null;
return new ItemSprite.Glowing(0xFFFFFF, 1f/(float)resinBonus);
}
@Override
public int value() {
int price = 75;
@ -445,13 +465,14 @@ public abstract class Wand extends Item {
return price;
}
private static final String USES_LEFT_TO_ID = "uses_left_to_id";
private static final String AVAILABLE_USES = "available_uses";
private static final String USES_LEFT_TO_ID = "uses_left_to_id";
private static final String AVAILABLE_USES = "available_uses";
private static final String CUR_CHARGES = "curCharges";
private static final String CUR_CHARGE_KNOWN = "curChargeKnown";
private static final String PARTIALCHARGE = "partialCharge";
private static final String CURSE_INFUSION_BONUS = "curse_infusion_bonus";
private static final String CURSE_INFUSION_BONUS= "curse_infusion_bonus";
private static final String RESIN_BONUS = "resin_bonus";
@Override
public void storeInBundle( Bundle bundle ) {
super.storeInBundle( bundle );
@ -460,7 +481,8 @@ public abstract class Wand extends Item {
bundle.put( CUR_CHARGES, curCharges );
bundle.put( CUR_CHARGE_KNOWN, curChargeKnown );
bundle.put( PARTIALCHARGE , partialCharge );
bundle.put(CURSE_INFUSION_BONUS, curseInfusionBonus );
bundle.put( CURSE_INFUSION_BONUS, curseInfusionBonus );
bundle.put( RESIN_BONUS, resinBonus );
}
@Override
@ -473,6 +495,7 @@ public abstract class Wand extends Item {
curChargeKnown = bundle.getBoolean( CUR_CHARGE_KNOWN );
partialCharge = bundle.getFloat( PARTIALCHARGE );
curseInfusionBonus = bundle.getBoolean(CURSE_INFUSION_BONUS);
resinBonus = bundle.getInt(RESIN_BONUS);
}
@Override

View File

@ -224,6 +224,9 @@ public class MagesStaff extends MeleeWeapon {
this.wand = null;
wand.resinBonus = 0;
wand.updateLevel();
//syncs the level of the two items.
int targetLevel = Math.max(this.level() - (curseInfusionBonus ? 1 : 0), wand.level());
@ -401,9 +404,11 @@ public class MagesStaff extends MeleeWeapon {
applyWand((Wand)item);
} else {
int newLevel;
if (item.level() >= level()){
if (level() > 0) newLevel = item.level() + 1;
else newLevel = item.level();
int itemLevel = item.level();
itemLevel -= ((Wand)item).resinBonus;
if (itemLevel >= level()){
if (level() > 0) newLevel = itemLevel + 1;
else newLevel = itemLevel;
} else {
newLevel = level();
}