v0.9.4: implemented liquid metal and added a sprite for arcane resin
This commit is contained in:
parent
e9e32835a7
commit
849c25d3e5
|
@ -1695,6 +1695,13 @@ items.kingscrown.upgraded=The crown glows brightly and then disintegrates as you
|
|||
items.kingscrown.ratgraded=Rat King's paws glow brightly as your armor transforms!
|
||||
items.kingscrown.desc=The crown of the last dwarven king, it glows with tremendous magical energy.\n\nWhen worn, the crown's magic will flow into the armor you're currently wearing, transforming it into a _unique epic armor with special abilities._ The new armor will keep all the properties of the original armor.
|
||||
|
||||
items.liquidmetal.name=liquid metal
|
||||
items.liquidmetal.ac_apply=APPLY
|
||||
items.liquidmetal.prompt=Select a thrown weapon
|
||||
items.liquidmetal.already_fixed=That thrown weapon is already in perfect condition!
|
||||
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.merchantsbeacon.name=merchant's beacon
|
||||
items.merchantsbeacon.ac_use=USE
|
||||
items.merchantsbeacon.desc=This odd piece of dwarven technology allows you to communicate from great distances.\n\nAfter being activated, this beacon will let you sell items to Pixel Mart from anywhere in the dungeon.\n\nHowever, the magic within the beacon will only last for one session, so use it wisely.
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
@ -0,0 +1,192 @@
|
|||
package com.shatteredpixel.shatteredpixeldungeon.items;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Splash;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.bags.MagicalHolster;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.darts.TippedDart;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||
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;
|
||||
|
||||
//these aren't considered potions internally as most potion effects shouldn't apply to them
|
||||
//mainly due to their high quantity
|
||||
public class LiquidMetal extends Item {
|
||||
|
||||
{
|
||||
image = ItemSpriteSheet.LIQUID_METAL;
|
||||
|
||||
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
|
||||
protected void onThrow( int cell ) {
|
||||
if (Dungeon.level.map[cell] == Terrain.WELL || Dungeon.level.pit[cell]) {
|
||||
|
||||
super.onThrow( cell );
|
||||
|
||||
} else {
|
||||
|
||||
Dungeon.level.pressCell( cell );
|
||||
if (Dungeon.level.heroFOV[cell]) {
|
||||
GLog.i( Messages.get(Potion.class, "shatter") );
|
||||
Sample.INSTANCE.play( Assets.Sounds.SHATTER );
|
||||
Splash.at( cell, 0xBFBFBF, 5 );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpgradable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdentified() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int value() {
|
||||
return Math.max(1, quantity/2);
|
||||
}
|
||||
|
||||
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 MissileWeapon && !(item instanceof TippedDart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelect( Item item ) {
|
||||
if (item != null && item instanceof MissileWeapon) {
|
||||
MissileWeapon m = (MissileWeapon)item;
|
||||
|
||||
int maxToUse = 5*(m.tier+1);
|
||||
maxToUse *= Math.pow(2, m.level());
|
||||
|
||||
float durabilityPerUse = 100 / (float)maxToUse;
|
||||
|
||||
//we remove a tiny amount here to account for rounding errors
|
||||
float percentDurabilityLeft = 0.999f - (m.durabilityLeft()/100f);
|
||||
maxToUse = (int)Math.ceil(maxToUse*percentDurabilityLeft);
|
||||
if (maxToUse == 0){
|
||||
GLog.w(Messages.get(LiquidMetal.class, "already_fixed"));
|
||||
return;
|
||||
} else if (maxToUse < quantity()) {
|
||||
m.repair(maxToUse*durabilityPerUse);
|
||||
quantity(quantity()-maxToUse);
|
||||
GLog.i(Messages.get(LiquidMetal.class, "apply", maxToUse));
|
||||
|
||||
} else {
|
||||
m.repair(quantity()*durabilityPerUse);
|
||||
GLog.i(Messages.get(LiquidMetal.class, "apply", quantity()));
|
||||
detachAll(Dungeon.hero.belongings.backpack);
|
||||
}
|
||||
|
||||
curUser.sprite.operate(curUser.pos);
|
||||
Sample.INSTANCE.play(Assets.Sounds.DRINK);
|
||||
curUser.sprite.emitter().start(Speck.factory(Speck.LIGHT), 0.1f, 10);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static class Recipe extends com.shatteredpixel.shatteredpixeldungeon.items.Recipe {
|
||||
|
||||
@Override
|
||||
public boolean testIngredients(ArrayList<Item> ingredients) {
|
||||
for (Item i : ingredients){
|
||||
if (!(i instanceof MissileWeapon)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return !ingredients.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int cost(ArrayList<Item> ingredients) {
|
||||
int cost = 1;
|
||||
for (Item i : ingredients){
|
||||
cost += i.quantity();
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item brew(ArrayList<Item> ingredients) {
|
||||
Item result = sampleOutput(ingredients);
|
||||
|
||||
for (Item i : ingredients){
|
||||
i.quantity(0);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item sampleOutput(ArrayList<Item> ingredients) {
|
||||
int metalQuantity = 0;
|
||||
|
||||
for (Item i : ingredients){
|
||||
MissileWeapon m = (MissileWeapon) i;
|
||||
float quantity = m.quantity()-1;
|
||||
quantity += 0.25f + 0.0075f*m.durabilityLeft();
|
||||
quantity *= Math.pow(2, m.level());
|
||||
metalQuantity += Math.round((5*(m.tier+1))*quantity);
|
||||
}
|
||||
|
||||
return new LiquidMetal().quantity(metalQuantity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -56,6 +56,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.spells.ReclaimTrap;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.items.spells.Recycle;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.spells.WildEnergy;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
|
||||
import com.watabou.utils.Reflection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -163,6 +164,10 @@ public abstract class Recipe {
|
|||
//*******
|
||||
// Static members
|
||||
//*******
|
||||
|
||||
private static Recipe[] variableRecipes = new Recipe[]{
|
||||
new LiquidMetal.Recipe()
|
||||
};
|
||||
|
||||
private static Recipe[] oneIngredientRecipes = new Recipe[]{
|
||||
new AlchemistsToolkit.upgradeKit(),
|
||||
|
@ -209,7 +214,13 @@ public abstract class Recipe {
|
|||
};
|
||||
|
||||
public static Recipe findRecipe(ArrayList<Item> ingredients){
|
||||
|
||||
|
||||
for (Recipe recipe : variableRecipes){
|
||||
if (recipe.testIngredients(ingredients)){
|
||||
return recipe;
|
||||
}
|
||||
}
|
||||
|
||||
if (ingredients.size() == 1){
|
||||
for (Recipe recipe : oneIngredientRecipes){
|
||||
if (recipe.testIngredients(ingredients)){
|
||||
|
@ -237,7 +248,7 @@ public abstract class Recipe {
|
|||
|
||||
public static boolean usableInRecipe(Item item){
|
||||
return !item.cursed
|
||||
&& (!(item instanceof EquipableItem) || (item instanceof AlchemistsToolkit && item.isIdentified()))
|
||||
&& (!(item instanceof EquipableItem) || (item instanceof AlchemistsToolkit && item.isIdentified()) || item instanceof MissileWeapon)
|
||||
&& !(item instanceof Wand);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
package com.shatteredpixel.shatteredpixeldungeon.items.bags;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.LiquidMetal;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||
|
||||
|
@ -33,7 +34,7 @@ public class PotionBandolier extends Bag {
|
|||
|
||||
@Override
|
||||
public boolean canHold( Item item ) {
|
||||
if (item instanceof Potion){
|
||||
if (item instanceof Potion || item instanceof LiquidMetal){
|
||||
return super.canHold(item);
|
||||
} else {
|
||||
return false;
|
||||
|
|
|
@ -257,6 +257,14 @@ abstract public class MissileWeapon extends Weapon {
|
|||
parent = null;
|
||||
super.onThrow(cell);
|
||||
}
|
||||
|
||||
public float durabilityLeft(){
|
||||
return durability;
|
||||
}
|
||||
|
||||
public void repair( float amount ){
|
||||
durability += amount;
|
||||
}
|
||||
|
||||
protected float durabilityPerUse(){
|
||||
float usages = baseUses * (float)(Math.pow(3, level()));
|
||||
|
|
|
@ -466,10 +466,12 @@ public class ItemSpriteSheet {
|
|||
public static final int SCROLL_TIWAZ = SCROLLS+11;
|
||||
|
||||
public static final int SCROLL_CATALYST = SCROLLS+13;
|
||||
public static final int ARCANE_RESIN = SCROLLS+14;
|
||||
static {
|
||||
for (int i = SCROLLS; i < SCROLLS+16; i++)
|
||||
assignItemRect(i, 15, 14);
|
||||
assignItemRect(SCROLL_CATALYST, 12, 11);
|
||||
assignItemRect(ARCANE_RESIN , 12, 11);
|
||||
}
|
||||
|
||||
private static final int EXOTIC_SCROLLS = xy(1, 20); //16 slots
|
||||
|
@ -522,10 +524,12 @@ public class ItemSpriteSheet {
|
|||
public static final int POTION_SILVER = POTIONS+10;
|
||||
public static final int POTION_IVORY = POTIONS+11;
|
||||
public static final int POTION_CATALYST = POTIONS+13;
|
||||
public static final int LIQUID_METAL = POTIONS+14;
|
||||
static {
|
||||
for (int i = POTIONS; i < POTIONS+16; i++)
|
||||
assignItemRect(i, 12, 14);
|
||||
assignItemRect(POTION_CATALYST, 6, 15);
|
||||
assignItemRect(LIQUID_METAL, 8, 15);
|
||||
}
|
||||
|
||||
private static final int EXOTIC_POTIONS = xy(1, 23); //16 slots
|
||||
|
|
Loading…
Reference in New Issue
Block a user