diff --git a/core/src/main/assets/items.png b/core/src/main/assets/items.png
index 65f73bb61..4e002f762 100644
Binary files a/core/src/main/assets/items.png and b/core/src/main/assets/items.png differ
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/ArtifactRecharge.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/ArtifactRecharge.java
index dfbb40916..b5d1ee829 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/ArtifactRecharge.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/ArtifactRecharge.java
@@ -36,7 +36,7 @@ public class ArtifactRecharge extends Buff {
type = buffType.POSITIVE;
}
- private int left = 30;
+ private int left;
@Override
public boolean act() {
@@ -62,8 +62,8 @@ public class ArtifactRecharge extends Buff {
return true;
}
- public void reset(){
- left = 30;
+ public void set( int amount ){
+ left = amount;
}
@Override
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ScrollOfMysticalEnergy.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ScrollOfMysticalEnergy.java
index 5cf629099..3c4f7ab5c 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ScrollOfMysticalEnergy.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ScrollOfMysticalEnergy.java
@@ -39,7 +39,7 @@ public class ScrollOfMysticalEnergy extends ExoticScroll {
public void doRead() {
//append buff
- Buff.affect(curUser, ArtifactRecharge.class).reset();
+ Buff.affect(curUser, ArtifactRecharge.class).set( 30 );
Sample.INSTANCE.play( Assets.SND_READ );
Invisibility.dispel();
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/Alchemize.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/Alchemize.java
new file mode 100644
index 000000000..b23843eaf
--- /dev/null
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/Alchemize.java
@@ -0,0 +1,58 @@
+/*
+ * Pixel Dungeon
+ * Copyright (C) 2012-2015 Oleg Dolya
+ *
+ * Shattered Pixel Dungeon
+ * Copyright (C) 2014-2018 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
+ */
+
+package com.shatteredpixel.shatteredpixeldungeon.items.spells;
+
+import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
+import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
+import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
+import com.shatteredpixel.shatteredpixeldungeon.scenes.AlchemyScene;
+import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
+import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
+
+public class Alchemize extends Spell implements AlchemyScene.AlchemyProvider {
+
+ {
+ image = ItemSpriteSheet.ALCHEMIZE;
+ }
+
+ @Override
+ protected void onCast(Hero hero) {
+ if (hero.visibleEnemies() > hero.mindVisionEnemies.size()) {
+ GLog.i( Messages.get(this, "enemy_near") );
+ return;
+ }
+ detach( curUser.belongings.backpack );
+ updateQuickslot();
+ AlchemyScene.setProvider(this);
+ ShatteredPixelDungeon.switchScene(AlchemyScene.class);
+ }
+
+ @Override
+ public int getEnergy() {
+ return 0;
+ }
+
+ @Override
+ public void spendEnergy(int reduction) {
+ //do nothing
+ }
+}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/BeaconOfReturning.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/BeaconOfReturning.java
index c100ebe8d..da0ef7c24 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/BeaconOfReturning.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/BeaconOfReturning.java
@@ -21,8 +21,26 @@
package com.shatteredpixel.shatteredpixeldungeon.items.spells;
+import com.shatteredpixel.shatteredpixeldungeon.Assets;
+import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
+import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
+import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
+import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
+import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourglass;
+import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
+import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
+import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
+import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene;
+import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
+import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
+import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
+import com.watabou.noosa.Game;
+import com.watabou.noosa.audio.Sample;
+import com.watabou.utils.Bundle;
+import com.watabou.utils.PathFinder;
public class BeaconOfReturning extends Spell {
@@ -30,8 +48,128 @@ public class BeaconOfReturning extends Spell {
image = ItemSpriteSheet.RETURN_BEACON;
}
+ public int returnDepth = -1;
+ public int returnPos;
+
@Override
- protected void onCast(Hero hero) {
- //TODO
+ protected void onCast(final Hero hero) {
+
+ if (returnDepth == -1){
+ setBeacon(hero);
+ } else {
+ GameScene.show(new WndOptions(Messages.titleCase(name()),
+ Messages.get(BeaconOfReturning.class, "wnd_body"),
+ Messages.get(BeaconOfReturning.class, "wnd_set"),
+ Messages.get(BeaconOfReturning.class, "wnd_return")){
+ @Override
+ protected void onSelect(int index) {
+ if (index == 0){
+ setBeacon(hero);
+ } else if (index == 1){
+ returnBeacon(hero);
+ }
+ }
+ });
+
+ }
+ }
+
+ @Override
+ protected void onDetach() {
+ returnDepth = -1;
+ }
+
+ private void setBeacon(Hero hero ){
+ returnDepth = Dungeon.depth;
+ returnPos = hero.pos;
+
+ hero.spend( 1f );
+ hero.busy();
+
+ GLog.i( Messages.get(this, "set") );
+
+ hero.sprite.operate( hero.pos );
+ Sample.INSTANCE.play( Assets.SND_BEACON );
+ updateQuickslot();
+ }
+
+ private void returnBeacon( Hero hero ){
+ if (Dungeon.bossLevel()) {
+ GLog.w( Messages.get(this, "preventing") );
+ return;
+ }
+
+ for (int i = 0; i < PathFinder.NEIGHBOURS8.length; i++) {
+ Char ch = Actor.findChar(hero.pos + PathFinder.NEIGHBOURS8[i]);
+ if (ch != null && ch.alignment == Char.Alignment.ENEMY) {
+ GLog.w( Messages.get(this, "creatures") );
+ return;
+ }
+ }
+
+ if (returnDepth == Dungeon.depth) {
+ ScrollOfTeleportation.appear( hero, returnPos );
+ for(Mob m : Dungeon.level.mobs){
+ if (m.pos == hero.pos){
+ //displace mob
+ for(int i : PathFinder.NEIGHBOURS8){
+ if (Actor.findChar(m.pos+i) == null && Dungeon.level.passable[m.pos + i]){
+ m.pos += i;
+ m.sprite.point(m.sprite.worldToCamera(m.pos));
+ break;
+ }
+ }
+ }
+ }
+ Dungeon.level.press( returnPos, hero );
+ Dungeon.observe();
+ GameScene.updateFog();
+ } else {
+
+ Buff buff = Dungeon.hero.buff(TimekeepersHourglass.timeFreeze.class);
+ if (buff != null) buff.detach();
+
+ InterlevelScene.mode = InterlevelScene.Mode.RETURN;
+ InterlevelScene.returnDepth = returnDepth;
+ InterlevelScene.returnPos = returnPos;
+ Game.switchScene( InterlevelScene.class );
+ }
+ returnDepth = -1;
+ detach(hero.belongings.backpack);
+ }
+
+ @Override
+ public String desc() {
+ String desc = super.desc();
+ if (returnDepth != -1){
+ desc += "\n\n" + Messages.get(this, "desc_set", returnDepth);
+ }
+ return desc;
+ }
+
+ private static final ItemSprite.Glowing WHITE = new ItemSprite.Glowing( 0xFFFFFF );
+
+ @Override
+ public ItemSprite.Glowing glowing() {
+ return returnDepth != -1 ? WHITE : null;
+ }
+
+ private static final String DEPTH = "depth";
+ private static final String POS = "pos";
+
+ @Override
+ public void storeInBundle( Bundle bundle ) {
+ super.storeInBundle( bundle );
+ bundle.put( DEPTH, returnDepth );
+ if (returnDepth != -1) {
+ bundle.put( POS, returnPos );
+ }
+ }
+
+ @Override
+ public void restoreFromBundle( Bundle bundle ) {
+ super.restoreFromBundle(bundle);
+ returnDepth = bundle.getInt( DEPTH );
+ returnPos = bundle.getInt( POS );
}
}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/CurseInfusion.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/CurseInfusion.java
new file mode 100644
index 000000000..ebe6929b6
--- /dev/null
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/CurseInfusion.java
@@ -0,0 +1,62 @@
+/*
+ * Pixel Dungeon
+ * Copyright (C) 2012-2015 Oleg Dolya
+ *
+ * Shattered Pixel Dungeon
+ * Copyright (C) 2014-2018 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
+ */
+
+package com.shatteredpixel.shatteredpixeldungeon.items.spells;
+
+import com.shatteredpixel.shatteredpixeldungeon.items.Item;
+import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
+import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
+import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon;
+import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Boomerang;
+import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
+import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
+
+public class CurseInfusion extends InventorySpell {
+
+ {
+ image = ItemSpriteSheet.CURSE_INFUSE;
+ mode = WndBag.Mode.CURSABLE;
+ }
+
+ @Override
+ protected void onItemSelected(Item item) {
+
+ //TODO visuals
+
+ item.cursed = true;
+ if (item instanceof MeleeWeapon || item instanceof Boomerang) {
+ Weapon w = (Weapon) item;
+ Class extends Weapon.Enchantment> curr = null;
+ if (w.enchantment != null) {
+ w.enchant(Weapon.Enchantment.randomCurse(w.enchantment.getClass()));
+ } else {
+ w.enchant(Weapon.Enchantment.randomCurse(curr));
+ }
+ } else if (item instanceof Armor){
+ Armor a = (Armor) item;
+ if (a.glyph != null){
+ a.inscribe(Armor.Glyph.randomCurse(a.glyph.getClass()));
+ } else {
+ a.inscribe(Armor.Glyph.randomCurse());
+ }
+ }
+ }
+}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/FeatherFall.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/FeatherFall.java
index 0bd043a59..776579530 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/FeatherFall.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/FeatherFall.java
@@ -23,8 +23,11 @@ package com.shatteredpixel.shatteredpixeldungeon.items.spells;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
+import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FlavourBuff;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
+import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
+import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
public class FeatherFall extends Spell {
@@ -35,16 +38,18 @@ public class FeatherFall extends Spell {
@Override
protected void onCast(Hero hero) {
- Buff.append(hero, FeatherBuff.class);
+ Buff.append(hero, FeatherBuff.class, 30f);
hero.sprite.operate(hero.pos);
Sample.INSTANCE.play(Assets.SND_READ );
+ GLog.p(Messages.get(this, "feather"));
+
detach( curUser.belongings.backpack );
updateQuickslot();
hero.spendAndNext( 1f );
}
- public static class FeatherBuff extends Buff {
+ public static class FeatherBuff extends FlavourBuff {
//does nothing, just waits to be triggered by chasm falling
}
}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/MagicalPorter.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/MagicalPorter.java
index 1424955b5..f6af6ae41 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/MagicalPorter.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/MagicalPorter.java
@@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.spells;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
+import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
@@ -40,7 +41,7 @@ public class MagicalPorter extends InventorySpell {
@Override
protected void onCast(Hero hero) {
if (Dungeon.depth >= 25){
- GLog.w("There is nowhere for you to port an item to.");
+ GLog.w(Messages.get(this, "nowhere"));
} else {
super.onCast(hero);
}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/PhaseShift.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/PhaseShift.java
index 5b4d5bf80..bc81b8ea8 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/PhaseShift.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/PhaseShift.java
@@ -26,7 +26,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
-import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
@@ -61,8 +60,7 @@ public class PhaseShift extends TargetedSpell {
} else if (ch.properties().contains(Char.Property.IMMOVABLE)) {
- //TODO move text
- GLog.w( Messages.get(LloydsBeacon.class, "tele_fail") );
+ GLog.w( Messages.get(this, "tele_fail") );
} else {
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/ReclaimTrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/ReclaimTrap.java
new file mode 100644
index 000000000..2acdae7d2
--- /dev/null
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/ReclaimTrap.java
@@ -0,0 +1,58 @@
+/*
+ * Pixel Dungeon
+ * Copyright (C) 2012-2015 Oleg Dolya
+ *
+ * Shattered Pixel Dungeon
+ * Copyright (C) 2014-2018 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
+ */
+
+package com.shatteredpixel.shatteredpixeldungeon.items.spells;
+
+import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
+import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ArtifactRecharge;
+import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
+import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Recharging;
+import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
+import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRecharging;
+import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap;
+import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
+import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
+import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
+import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
+
+public class ReclaimTrap extends TargetedSpell {
+
+ {
+ image = ItemSpriteSheet.RECLAIM_TRAP;
+ }
+
+ @Override
+ protected void affectTarget(Ballistica bolt, Hero hero) {
+ Trap t = Dungeon.level.traps.get(bolt.collisionPos);
+ if (t != null && t.active){
+ if (!t.visible) t.reveal();
+ t.disarm();
+
+ ScrollOfRecharging.charge(hero);
+ Buff.affect(hero, Recharging.class, 10f);
+ Buff.affect(hero, ArtifactRecharge.class).set( 10 );
+
+ } else {
+ GLog.w(Messages.get(this, "no_trap"));
+ }
+ }
+
+}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/Recycle.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/Recycle.java
new file mode 100644
index 000000000..eb858ae5c
--- /dev/null
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/Recycle.java
@@ -0,0 +1,69 @@
+/*
+ * Pixel Dungeon
+ * Copyright (C) 2012-2015 Oleg Dolya
+ *
+ * Shattered Pixel Dungeon
+ * Copyright (C) 2014-2018 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
+ */
+
+package com.shatteredpixel.shatteredpixeldungeon.items.spells;
+
+import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
+import com.shatteredpixel.shatteredpixeldungeon.items.Item;
+import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
+import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
+import com.shatteredpixel.shatteredpixeldungeon.items.stones.Runestone;
+import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
+import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
+import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
+import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
+import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
+
+public class Recycle extends InventorySpell {
+
+ {
+ image = ItemSpriteSheet.RECYCLE;
+ mode = WndBag.Mode.RECYCLABLE;
+ }
+
+ @Override
+ protected void onItemSelected(Item item) {
+ Item result;
+ do {
+ if (item instanceof Potion) {
+ result = Generator.random(Generator.Category.POTION);
+ } else if (item instanceof Scroll) {
+ result = Generator.random(Generator.Category.SCROLL);
+ } else if (item instanceof Plant.Seed) {
+ result = Generator.random(Generator.Category.SEED);
+ } else {
+ result = Generator.random(Generator.Category.STONE);
+ }
+ } while (result.getClass() == item.getClass());
+
+ item.detach(curUser.belongings.backpack);
+ GLog.p(Messages.get(this, "recycled", result.name()));
+ result.collect();
+ //TODO visuals
+ }
+
+ public static boolean isRecyclable(Item item){
+ return item instanceof Potion ||
+ item instanceof Scroll ||
+ item instanceof Plant.Seed ||
+ item instanceof Runestone;
+ }
+}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java
index 013b5c631..319067500 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java
@@ -558,7 +558,7 @@ public class ItemSpriteSheet {
assignItemRect(BREW_BLIZZARD, 10, 14);
assignItemRect(BREW_SHOCKING, 10, 14);
}
-
+ //sprites still pretty WIP
private static final int SPELLS = xy(1, 27); //16 slots
public static final int PHASE_SHIFT = SPELLS+0;
public static final int AQUA_BLAST = SPELLS+1;
@@ -566,6 +566,10 @@ public class ItemSpriteSheet {
public static final int MAGIC_PORTER = SPELLS+3;
public static final int RETURN_BEACON = SPELLS+4;
public static final int FEATHER_FALL = SPELLS+5;
+ public static final int CURSE_INFUSE = SPELLS+6;
+ public static final int RECLAIM_TRAP = SPELLS+7;
+ public static final int ALCHEMIZE = SPELLS+8;
+ public static final int RECYCLE = SPELLS+9;
static{
assignItemRect(PHASE_SHIFT, 12, 11);
assignItemRect(AQUA_BLAST, 11, 11);
@@ -573,6 +577,10 @@ public class ItemSpriteSheet {
assignItemRect(MAGIC_PORTER, 12, 11);
assignItemRect(RETURN_BEACON, 8, 16);
assignItemRect(FEATHER_FALL, 11, 11);
+ assignItemRect(CURSE_INFUSE, 10, 15);
+ assignItemRect(RECLAIM_TRAP, 11, 11);
+ assignItemRect(ALCHEMIZE, 10, 15);
+ assignItemRect(RECYCLE, 10, 15);
}
private static final int FOOD = xy(1, 28); //16 slots
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndBag.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndBag.java
index 1c4942823..a3f6c5e0b 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndBag.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndBag.java
@@ -41,10 +41,12 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRemoveCurse;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTransmutation;
+import com.shatteredpixel.shatteredpixeldungeon.items.spells.Recycle;
import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfDetectCurse;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Boomerang;
+import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant.Seed;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
@@ -69,6 +71,7 @@ public class WndBag extends WndTabbed {
ALL,
UNIDENTIFED,
UNCURSABLE,
+ CURSABLE,
UPGRADEABLE,
QUICKSLOT,
FOR_SALE,
@@ -85,6 +88,7 @@ public class WndBag extends WndTabbed {
EQUIPMENT,
TRANMSUTABLE,
ALCHEMY,
+ RECYCLABLE,
NOT_EQUIPPED
}
@@ -395,6 +399,7 @@ public class WndBag extends WndTabbed {
mode == Mode.UPGRADEABLE && item.isUpgradable() ||
mode == Mode.UNIDENTIFED && !item.isIdentified() ||
mode == Mode.UNCURSABLE && ScrollOfRemoveCurse.uncursable(item) ||
+ mode == Mode.CURSABLE && ((item instanceof EquipableItem && !(item instanceof MissileWeapon)) || item instanceof Boomerang || item instanceof Wand) ||
mode == Mode.QUICKSLOT && (item.defaultAction != null) ||
mode == Mode.WEAPON && (item instanceof MeleeWeapon || item instanceof Boomerang) ||
mode == Mode.ARMOR && (item instanceof Armor) ||
@@ -410,6 +415,7 @@ public class WndBag extends WndTabbed {
mode == Mode.ALCHEMY && Recipe.usableInRecipe(item) ||
mode == Mode.TRANMSUTABLE && ScrollOfTransmutation.canTransmute(item) ||
mode == Mode.NOT_EQUIPPED && !item.isEquipped(Dungeon.hero) ||
+ mode == Mode.RECYCLABLE && Recycle.isRecyclable(item) ||
mode == Mode.ALL
);
}
diff --git a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/items/items.properties b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/items/items.properties
index e36aee965..a35c3a7df 100644
--- a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/items/items.properties
+++ b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/items/items.properties
@@ -905,14 +905,29 @@ items.scrolls.exotic.scrollofpsionicblast.desc=This scroll contains incredible d
###spells
-items.spells.aquablast.name=aqua blast
-items.spells.aquablast.desc=WIP
+items.spells.alchemize.name=alchemize
+items.spells.alchemize.enemy_near=You cannot do that with enemies nearby.
+items.spells.alchemize.desc=This spell channels alchemical energy, allowing you to perform alchemy as if you were at a pot with no energy for a short time.
-items.spells.featherfall.name=feather fall
-items.spells.featherfall.desc=WIP
+items.spells.aquablast.name=aqua blast
+items.spells.aquablast.desc=This spell will create a burst of water at the target location. It isn't forceful enough to do damage (even to fiery enemies), but it will spread water to nearby terrain and very briefly stun anything caught in the center of the burst.
items.spells.beaconofreturning.name=beacon of returning
-items.spells.beaconofreturning.desc=WIP
+items.spells.beaconofreturning.preventing=The strong magic aura of this place prevents you from using the spell!
+items.spells.beaconofreturning.creatures=The Psychic aura of neighbouring creatures doesn't allow you to teleport at this moment.
+items.spells.beaconofreturning.set=The beacon was set at your current location.
+items.spells.beaconofreturning.wnd_body=Setting will override the location the beacon was previously set to.\n\nReturning will return to your last set location and consume one use of the spell.
+items.spells.beaconofreturning.wnd_set=Set
+items.spells.beaconofreturning.wnd_return=Return
+items.spells.beaconofreturning.desc_set=This beacon was set somewhere on floor %d.
+items.spells.beaconofreturning.desc=This intricate spell grants the user the ability to return to a set location, regardless of distance. The spell will only be consumed by returning, it can be set as many times as you like, but it will only remember the most recent location it was set to.
+
+items.spells.curseinfusion.name=curse infusion
+items.spells.curseinfusion.desc=This spell infuses a piece of equipment with the same malignant magic present within DM-300. The item it is used on will immediately be cursed, and any enchantment or glyph it may have had will be overridden.
+
+items.spells.featherfall.name=feather fall
+items.spells.featherfall.light=You feel light as a feather!
+items.spells.featherfall.desc=This spell manipulates gravity's affect on the caster, allowing them to fall great distances without harm for a short time.
items.spells.spell.ac_cast=CAST
@@ -923,10 +938,21 @@ items.spells.magicalinfusion.desc=This spell will infuse a weapon or armor with
items.spells.magicalporter.name=magical porter
items.spells.magicalporter.inv_title=Port an item
-items.spells.magicalporter.desc=WIP
+items.spells.magicalporter.nowhere=There is nowhere for you to port an item to.
+items.spells.magicalporter.desc=This spell will magical transport any item it is cast on. Unlike a merchant's beacon however, the items will be transported to the entrance of next boss floor.
items.spells.phaseshift.name=phase shift
-items.spells.phaseshift.desc=WIP
+items.spells.phaseshift.tele_fail=The teleportation magic fails.
+items.spells.phaseshift.desc=This chaotic spell will teleport any character it is aimed at to a random location on the current floor. This spell can be directed at a target or at the user themselves.
+
+items.spells.reclaimtrap.name=reclaim trap
+items.spells.reclaimtrap.no_trap=There is no trap there.
+items.spells.reclaimtrap.desc=This spell contains remnants of the repairing ability of DM-300. When cast on an active trap, the mechanical power of the trap will be recycled into magical energy which recharges the user's wands and artifacts.
+
+items.spells.recycle.name=recycle
+items.spells.recycle.inv_title=Recycle an item
+items.spells.recycle.recycled=Your item was recycled into: %s.
+items.spells.recycle.desc=This spell contains a lesser form of transmutation magic. While it won't work on equipment, this spell will transform a scroll, potion, seed, or runestone into a random item of the same type.
items.spells.targetedspell.prompt=Choose a target
items.spells.targetedspell.inv_title=Infuse an item