v1.2.0: balance changes to spells (except summon elemental)
This commit is contained in:
parent
81ebd0c940
commit
3c8e5c48dd
|
@ -1048,7 +1048,7 @@ items.spells.alchemize$wndalchemizeitem.energize_1=Turn 1 into %d energy
|
||||||
items.spells.alchemize$wndalchemizeitem.energize_all=Turn all into %d energy
|
items.spells.alchemize$wndalchemizeitem.energize_all=Turn all into %d energy
|
||||||
|
|
||||||
items.spells.aquablast.name=aqua blast
|
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.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 knock back characters near the burst.
|
||||||
|
|
||||||
items.spells.arcanecatalyst.name=arcane catalyst
|
items.spells.arcanecatalyst.name=arcane catalyst
|
||||||
items.spells.arcanecatalyst.desc=This ball of golden dust is made from the deconstructed essence of a scroll. It glimmers in the darkness of the dungeon.\n\nThis catalyst is primarily useful as an alchemy ingredient, but you can also channel the magic directly to get the effect of a random scroll.
|
items.spells.arcanecatalyst.desc=This ball of golden dust is made from the deconstructed essence of a scroll. It glimmers in the darkness of the dungeon.\n\nThis catalyst is primarily useful as an alchemy ingredient, but you can also channel the magic directly to get the effect of a random scroll.
|
||||||
|
@ -1065,7 +1065,7 @@ items.spells.beaconofreturning.desc=This intricate spell grants the user the abi
|
||||||
|
|
||||||
items.spells.curseinfusion.name=curse infusion
|
items.spells.curseinfusion.name=curse infusion
|
||||||
items.spells.curseinfusion.inv_title=Curse an item
|
items.spells.curseinfusion.inv_title=Curse an item
|
||||||
items.spells.curseinfusion.desc=This spell infuses a piece of equipment with the same powerful 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.\n\nIn the case of weapons, armor, and wands, the item will be upgraded in addition to being cursed. Curse infusion upgrades do not stack, and the upgrade is lost if the item becomes uncursed.
|
items.spells.curseinfusion.desc=This spell infuses a piece of equipment with the same powerful 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.\n\nIn the case of weapons, armor, and wands, the item will gain upgrades in addition to being cursed. Curse infusion upgrades do not stack, and the upgrades are lost if the item becomes uncursed.
|
||||||
|
|
||||||
items.spells.featherfall.name=feather fall
|
items.spells.featherfall.name=feather fall
|
||||||
items.spells.featherfall.light=You feel light as a feather!
|
items.spells.featherfall.light=You feel light as a feather!
|
||||||
|
@ -1085,7 +1085,9 @@ items.spells.magicalporter.nowhere=There is nowhere for you to port an item to.
|
||||||
items.spells.magicalporter.desc=This spell will magically transport any item it is cast on. Unlike a merchant's beacon however, the items will be transported to the entrance of the next boss floor.
|
items.spells.magicalporter.desc=This spell will magically transport any item it is cast on. Unlike a merchant's beacon however, the items will be transported to the entrance of the next boss floor.
|
||||||
|
|
||||||
items.spells.phaseshift.name=phase shift
|
items.spells.phaseshift.name=phase shift
|
||||||
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.phaseshift.no_self=You cannot teleport yourself with that.
|
||||||
|
items.spells.phaseshift.no_target=There is nothing to teleport there.
|
||||||
|
items.spells.phaseshift.desc=This chaotic spell will teleport any character it is aimed at to a random location on the current floor, and stun them for a significant amount of time. Powerful foes will be able to resist the stunning effect. This spell can be directed at a target or at the user themselves.
|
||||||
|
|
||||||
items.spells.reclaimtrap.name=reclaim trap
|
items.spells.reclaimtrap.name=reclaim trap
|
||||||
items.spells.reclaimtrap.no_trap=There is no trap there.
|
items.spells.reclaimtrap.no_trap=There is no trap there.
|
||||||
|
|
|
@ -314,7 +314,12 @@ public class Item implements Bundlable {
|
||||||
|
|
||||||
protected void onDetach(){}
|
protected void onDetach(){}
|
||||||
|
|
||||||
//returns the true level of the item, only affected by modifiers which are persistent (e.g. curse infusion)
|
//returns the true level of the item, ignoring all modifiers aside from upgrades
|
||||||
|
public final int trueLevel(){
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
//returns the persistant level of the item, only affected by modifiers which are persistent (e.g. curse infusion)
|
||||||
public int level(){
|
public int level(){
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,8 +238,7 @@ public class Armor extends EquipableItem {
|
||||||
this.seal = seal;
|
this.seal = seal;
|
||||||
if (seal.level() > 0){
|
if (seal.level() > 0){
|
||||||
//doesn't trigger upgrading logic such as affecting curses/glyphs
|
//doesn't trigger upgrading logic such as affecting curses/glyphs
|
||||||
int newLevel = level()+1;
|
int newLevel = trueLevel()+1;
|
||||||
if (curseInfusionBonus) newLevel--;
|
|
||||||
level(newLevel);
|
level(newLevel);
|
||||||
Badges.validateItemLevelAquired(this);
|
Badges.validateItemLevelAquired(this);
|
||||||
}
|
}
|
||||||
|
@ -379,7 +378,9 @@ public class Armor extends EquipableItem {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int level() {
|
public int level() {
|
||||||
return super.level() + (curseInfusionBonus ? 1 : 0);
|
int level = super.level();
|
||||||
|
if (curseInfusionBonus) level += 1 + level/6;
|
||||||
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
//other things can equip these, for now we assume only the hero can be affected by levelling debuffs
|
//other things can equip these, for now we assume only the hero can be affected by levelling debuffs
|
||||||
|
|
|
@ -104,7 +104,7 @@ abstract public class ClassArmor extends Armor {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
classArmor.level(armor.level() - (armor.curseInfusionBonus ? 1 : 0));
|
classArmor.level(armor.trueLevel());
|
||||||
classArmor.tier = armor.tier;
|
classArmor.tier = armor.tier;
|
||||||
classArmor.augment = armor.augment;
|
classArmor.augment = armor.augment;
|
||||||
classArmor.inscribe( armor.glyph );
|
classArmor.inscribe( armor.glyph );
|
||||||
|
|
|
@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||||
|
@ -273,6 +274,10 @@ public class ScrollOfTeleportation extends Scroll {
|
||||||
Sample.INSTANCE.play(Assets.Sounds.TELEPORT);
|
Sample.INSTANCE.play(Assets.Sounds.TELEPORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Dungeon.level.heroFOV[ch.pos] && ch != Dungeon.hero ) {
|
||||||
|
CellEmitter.get(ch.pos).start(Speck.factory(Speck.LIGHT), 0.2f, 3);
|
||||||
|
}
|
||||||
|
|
||||||
ch.move( pos, false );
|
ch.move( pos, false );
|
||||||
if (ch.pos == pos) ch.sprite.place( pos );
|
if (ch.pos == pos) ch.sprite.place( pos );
|
||||||
|
|
||||||
|
|
|
@ -170,8 +170,7 @@ public class ScrollOfTransmutation extends InventoryScroll {
|
||||||
n = (Weapon) Reflection.newInstance(c.classes[Random.chances(c.probs)]);
|
n = (Weapon) Reflection.newInstance(c.classes[Random.chances(c.probs)]);
|
||||||
} while (Challenges.isItemBlocked(n) || n.getClass() == w.getClass());
|
} while (Challenges.isItemBlocked(n) || n.getClass() == w.getClass());
|
||||||
|
|
||||||
int level = w.level();
|
int level = w.trueLevel();
|
||||||
if (w.curseInfusionBonus) level--;
|
|
||||||
if (level > 0) {
|
if (level > 0) {
|
||||||
n.upgrade( level );
|
n.upgrade( level );
|
||||||
} else if (level < 0) {
|
} else if (level < 0) {
|
||||||
|
@ -234,9 +233,7 @@ public class ScrollOfTransmutation extends InventoryScroll {
|
||||||
} while ( Challenges.isItemBlocked(n) || n.getClass() == w.getClass());
|
} while ( Challenges.isItemBlocked(n) || n.getClass() == w.getClass());
|
||||||
|
|
||||||
n.level( 0 );
|
n.level( 0 );
|
||||||
int level = w.level();
|
int level = w.trueLevel();
|
||||||
if (w.curseInfusionBonus) level--;
|
|
||||||
level -= w.resinBonus;
|
|
||||||
n.upgrade( level );
|
n.upgrade( level );
|
||||||
|
|
||||||
n.levelKnown = w.levelKnown;
|
n.levelKnown = w.levelKnown;
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class Alchemize extends Spell {
|
||||||
inputs = new Class[]{ArcaneCatalyst.class};
|
inputs = new Class[]{ArcaneCatalyst.class};
|
||||||
inQuantity = new int[]{1};
|
inQuantity = new int[]{1};
|
||||||
|
|
||||||
cost = 3;
|
cost = 2;
|
||||||
|
|
||||||
output = Alchemize.class;
|
output = Alchemize.class;
|
||||||
outQuantity = 8;
|
outQuantity = 8;
|
||||||
|
|
|
@ -21,49 +21,33 @@
|
||||||
|
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.items.spells;
|
package com.shatteredpixel.shatteredpixeldungeon.items.spells;
|
||||||
|
|
||||||
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.buffs.Paralysis;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Splash;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfStormClouds;
|
import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfStormClouds;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GeyserTrap;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||||
import com.watabou.utils.PathFinder;
|
|
||||||
import com.watabou.utils.Random;
|
|
||||||
|
|
||||||
public class AquaBlast extends TargetedSpell {
|
public class AquaBlast extends TargetedSpell {
|
||||||
|
|
||||||
{
|
{
|
||||||
image = ItemSpriteSheet.AQUA_BLAST;
|
image = ItemSpriteSheet.AQUA_BLAST;
|
||||||
|
usesTargeting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void affectTarget(Ballistica bolt, Hero hero) {
|
protected void affectTarget(Ballistica bolt, Hero hero) {
|
||||||
int cell = bolt.collisionPos;
|
int cell = bolt.collisionPos;
|
||||||
|
|
||||||
Splash.at(cell, 0x00AAFF, 10);
|
GeyserTrap geyser = new GeyserTrap();
|
||||||
|
geyser.pos = cell;
|
||||||
for (int i : PathFinder.NEIGHBOURS9){
|
geyser.centerKnockBackDirection = bolt.path.get(bolt.dist+1);
|
||||||
if (i == 0 || Random.Int(5) != 0){
|
geyser.activate();
|
||||||
Dungeon.level.setCellToWater(false, cell+i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Char target = Actor.findChar(cell);
|
|
||||||
|
|
||||||
if (target != null && target != hero){
|
|
||||||
//just enough to skip their current turn
|
|
||||||
Buff.affect(target, Paralysis.class, target.cooldown());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int value() {
|
public int value() {
|
||||||
//prices of ingredients, divided by output quantity
|
//prices of ingredients, divided by output quantity
|
||||||
return Math.round(quantity * ((60 + 40) / 12f));
|
return Math.round(quantity * ((60 + 40) / 8f));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Recipe extends com.shatteredpixel.shatteredpixeldungeon.items.Recipe.SimpleRecipe {
|
public static class Recipe extends com.shatteredpixel.shatteredpixeldungeon.items.Recipe.SimpleRecipe {
|
||||||
|
@ -75,7 +59,7 @@ public class AquaBlast extends TargetedSpell {
|
||||||
cost = 2;
|
cost = 2;
|
||||||
|
|
||||||
output = AquaBlast.class;
|
output = AquaBlast.class;
|
||||||
outQuantity = 12;
|
outQuantity = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,7 +202,7 @@ public class BeaconOfReturning extends Spell {
|
||||||
inputs = new Class[]{ScrollOfPassage.class, ArcaneCatalyst.class};
|
inputs = new Class[]{ScrollOfPassage.class, ArcaneCatalyst.class};
|
||||||
inQuantity = new int[]{1, 1};
|
inQuantity = new int[]{1, 1};
|
||||||
|
|
||||||
cost = 8;
|
cost = 6;
|
||||||
|
|
||||||
output = BeaconOfReturning.class;
|
output = BeaconOfReturning.class;
|
||||||
outQuantity = 5;
|
outQuantity = 5;
|
||||||
|
|
|
@ -99,10 +99,10 @@ public class CurseInfusion extends InventorySpell {
|
||||||
inputs = new Class[]{ScrollOfRemoveCurse.class, MetalShard.class};
|
inputs = new Class[]{ScrollOfRemoveCurse.class, MetalShard.class};
|
||||||
inQuantity = new int[]{1, 1};
|
inQuantity = new int[]{1, 1};
|
||||||
|
|
||||||
cost = 4;
|
cost = 6;
|
||||||
|
|
||||||
output = CurseInfusion.class;
|
output = CurseInfusion.class;
|
||||||
outQuantity = 3;
|
outQuantity = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ public class MagicalInfusion extends InventorySpell {
|
||||||
inputs = new Class[]{ScrollOfUpgrade.class, ArcaneCatalyst.class};
|
inputs = new Class[]{ScrollOfUpgrade.class, ArcaneCatalyst.class};
|
||||||
inQuantity = new int[]{1, 1};
|
inQuantity = new int[]{1, 1};
|
||||||
|
|
||||||
cost = 3;
|
cost = 4;
|
||||||
|
|
||||||
output = MagicalInfusion.class;
|
output = MagicalInfusion.class;
|
||||||
outQuantity = 1;
|
outQuantity = 1;
|
||||||
|
|
|
@ -24,6 +24,8 @@ package com.shatteredpixel.shatteredpixeldungeon.items.spells;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
|
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
|
||||||
|
@ -36,23 +38,28 @@ public class PhaseShift extends TargetedSpell {
|
||||||
|
|
||||||
{
|
{
|
||||||
image = ItemSpriteSheet.PHASE_SHIFT;
|
image = ItemSpriteSheet.PHASE_SHIFT;
|
||||||
|
|
||||||
|
usesTargeting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void affectTarget(Ballistica bolt, Hero hero) {
|
protected void affectTarget(Ballistica bolt, Hero hero) {
|
||||||
final Char ch = Actor.findChar(bolt.collisionPos);
|
final Char ch = Actor.findChar(bolt.collisionPos);
|
||||||
|
|
||||||
if (ch == hero){
|
if (ch != null) {
|
||||||
//TODO probably want this to not work on the hero for balance reasons?
|
|
||||||
ScrollOfTeleportation.teleportChar(curUser);
|
|
||||||
} else if (ch != null) {
|
|
||||||
if (ScrollOfTeleportation.teleportChar(ch)){
|
if (ScrollOfTeleportation.teleportChar(ch)){
|
||||||
|
|
||||||
if (ch instanceof Mob && ((Mob) ch).state == ((Mob) ch).HUNTING){
|
if (ch instanceof Mob) {
|
||||||
((Mob) ch).state = ((Mob) ch).WANDERING;
|
if (((Mob) ch).state == ((Mob) ch).HUNTING) ((Mob) ch).state = ((Mob) ch).WANDERING;
|
||||||
|
((Mob) ch).beckon(Dungeon.level.randomDestination( ch ));
|
||||||
|
}
|
||||||
|
if (!Char.hasProp(ch, Char.Property.BOSS) && !Char.hasProp(ch, Char.Property.MINIBOSS)) {
|
||||||
|
Buff.affect(ch, Paralysis.class, Paralysis.DURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
GLog.w( Messages.get(this, "no_target") );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +75,7 @@ public class PhaseShift extends TargetedSpell {
|
||||||
inputs = new Class[]{ScrollOfTeleportation.class, ArcaneCatalyst.class};
|
inputs = new Class[]{ScrollOfTeleportation.class, ArcaneCatalyst.class};
|
||||||
inQuantity = new int[]{1, 1};
|
inQuantity = new int[]{1, 1};
|
||||||
|
|
||||||
cost = 6;
|
cost = 4;
|
||||||
|
|
||||||
output = PhaseShift.class;
|
output = PhaseShift.class;
|
||||||
outQuantity = 8;
|
outQuantity = 8;
|
||||||
|
|
|
@ -117,7 +117,7 @@ public class ReclaimTrap extends TargetedSpell {
|
||||||
@Override
|
@Override
|
||||||
public int value() {
|
public int value() {
|
||||||
//prices of ingredients, divided by output quantity
|
//prices of ingredients, divided by output quantity
|
||||||
return Math.round(quantity * ((40 + 50) / 3f));
|
return Math.round(quantity * ((40 + 50) / 4f));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String STORED_TRAP = "stored_trap";
|
private static final String STORED_TRAP = "stored_trap";
|
||||||
|
@ -143,7 +143,7 @@ public class ReclaimTrap extends TargetedSpell {
|
||||||
cost = 6;
|
cost = 6;
|
||||||
|
|
||||||
output = ReclaimTrap.class;
|
output = ReclaimTrap.class;
|
||||||
outQuantity = 3;
|
outQuantity = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ public class Recycle extends InventorySpell {
|
||||||
@Override
|
@Override
|
||||||
public int value() {
|
public int value() {
|
||||||
//prices of ingredients, divided by output quantity
|
//prices of ingredients, divided by output quantity
|
||||||
return Math.round(quantity * ((50 + 40) / 8f));
|
return Math.round(quantity * ((50 + 40) / 12f));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Recipe extends com.shatteredpixel.shatteredpixeldungeon.items.Recipe.SimpleRecipe {
|
public static class Recipe extends com.shatteredpixel.shatteredpixeldungeon.items.Recipe.SimpleRecipe {
|
||||||
|
@ -103,10 +103,10 @@ public class Recycle extends InventorySpell {
|
||||||
inputs = new Class[]{ScrollOfTransmutation.class, ArcaneCatalyst.class};
|
inputs = new Class[]{ScrollOfTransmutation.class, ArcaneCatalyst.class};
|
||||||
inQuantity = new int[]{1, 1};
|
inQuantity = new int[]{1, 1};
|
||||||
|
|
||||||
cost = 6;
|
cost = 8;
|
||||||
|
|
||||||
output = Recycle.class;
|
output = Recycle.class;
|
||||||
outQuantity = 8;
|
outQuantity = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,16 +111,16 @@ public class TelekineticGrab extends TargetedSpell {
|
||||||
@Override
|
@Override
|
||||||
public int value() {
|
public int value() {
|
||||||
//prices of ingredients, divided by output quantity (rounded up slightly)
|
//prices of ingredients, divided by output quantity (rounded up slightly)
|
||||||
return Math.round(quantity * ((48) / 6f));
|
return Math.round(quantity * ((5 + 40) / 6f));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Recipe extends com.shatteredpixel.shatteredpixeldungeon.items.Recipe.SimpleRecipe {
|
public static class Recipe extends com.shatteredpixel.shatteredpixeldungeon.items.Recipe.SimpleRecipe {
|
||||||
|
|
||||||
{
|
{
|
||||||
inputs = new Class[]{LiquidMetal.class, ArcaneCatalyst.class};
|
inputs = new Class[]{LiquidMetal.class, ArcaneCatalyst.class};
|
||||||
inQuantity = new int[]{15, 1};
|
inQuantity = new int[]{10, 1};
|
||||||
|
|
||||||
cost = 4;
|
cost = 2;
|
||||||
|
|
||||||
output = TelekineticGrab.class;
|
output = TelekineticGrab.class;
|
||||||
outQuantity = 6;
|
outQuantity = 6;
|
||||||
|
|
|
@ -40,6 +40,7 @@ public class WildEnergy extends TargetedSpell {
|
||||||
|
|
||||||
{
|
{
|
||||||
image = ItemSpriteSheet.WILD_ENERGY;
|
image = ItemSpriteSheet.WILD_ENERGY;
|
||||||
|
usesTargeting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//we rely on cursedWand to do fx instead
|
//we rely on cursedWand to do fx instead
|
||||||
|
@ -75,7 +76,7 @@ public class WildEnergy extends TargetedSpell {
|
||||||
inputs = new Class[]{ScrollOfMysticalEnergy.class, MetalShard.class};
|
inputs = new Class[]{ScrollOfMysticalEnergy.class, MetalShard.class};
|
||||||
inQuantity = new int[]{1, 1};
|
inQuantity = new int[]{1, 1};
|
||||||
|
|
||||||
cost = 6;
|
cost = 4;
|
||||||
|
|
||||||
output = WildEnergy.class;
|
output = WildEnergy.class;
|
||||||
outQuantity = 5;
|
outQuantity = 5;
|
||||||
|
|
|
@ -282,7 +282,10 @@ public abstract class Wand extends Item {
|
||||||
curseInfusionBonus = false;
|
curseInfusionBonus = false;
|
||||||
updateLevel();
|
updateLevel();
|
||||||
}
|
}
|
||||||
return super.level() + resinBonus + (curseInfusionBonus ? 1 : 0);
|
int level = super.level();
|
||||||
|
if (curseInfusionBonus) level += 1 + level/6;
|
||||||
|
level += resinBonus;
|
||||||
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -186,7 +186,7 @@ public class SpiritBow extends Weapon {
|
||||||
public int min(int lvl) {
|
public int min(int lvl) {
|
||||||
int dmg = 1 + Dungeon.hero.lvl/5
|
int dmg = 1 + Dungeon.hero.lvl/5
|
||||||
+ RingOfSharpshooting.levelDamageBonus(Dungeon.hero)
|
+ RingOfSharpshooting.levelDamageBonus(Dungeon.hero)
|
||||||
+ (curseInfusionBonus ? 1 : 0);
|
+ (curseInfusionBonus ? 1 + Dungeon.hero.lvl/30 : 0);
|
||||||
return Math.max(0, dmg);
|
return Math.max(0, dmg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ public class SpiritBow extends Weapon {
|
||||||
public int max(int lvl) {
|
public int max(int lvl) {
|
||||||
int dmg = 6 + (int)(Dungeon.hero.lvl/2.5f)
|
int dmg = 6 + (int)(Dungeon.hero.lvl/2.5f)
|
||||||
+ 2*RingOfSharpshooting.levelDamageBonus(Dungeon.hero)
|
+ 2*RingOfSharpshooting.levelDamageBonus(Dungeon.hero)
|
||||||
+ (curseInfusionBonus ? 2 : 0);
|
+ (curseInfusionBonus ? 2 + Dungeon.hero.lvl/15 : 0);
|
||||||
return Math.max(0, dmg);
|
return Math.max(0, dmg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +267,9 @@ public class SpiritBow extends Weapon {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int level() {
|
public int level() {
|
||||||
return (Dungeon.hero == null ? 0 : Dungeon.hero.lvl/5) + (curseInfusionBonus ? 1 : 0);
|
int level = Dungeon.hero == null ? 0 : Dungeon.hero.lvl/5;
|
||||||
|
if (curseInfusionBonus) level += 1 + level/6;
|
||||||
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -229,7 +229,9 @@ abstract public class Weapon extends KindOfWeapon {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int level() {
|
public int level() {
|
||||||
return super.level() + (curseInfusionBonus ? 1 : 0);
|
int level = super.level();
|
||||||
|
if (curseInfusionBonus) level += 1 + level/6;
|
||||||
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
//overrides as other things can equip these
|
//overrides as other things can equip these
|
||||||
|
|
|
@ -234,10 +234,10 @@ public class MagesStaff extends MeleeWeapon {
|
||||||
wand.updateLevel();
|
wand.updateLevel();
|
||||||
|
|
||||||
//syncs the level of the two items.
|
//syncs the level of the two items.
|
||||||
int targetLevel = Math.max(this.level() - (curseInfusionBonus ? 1 : 0), wand.level());
|
int targetLevel = Math.max(this.trueLevel(), wand.trueLevel());
|
||||||
|
|
||||||
//if the staff's level is being overridden by the wand, preserve 1 upgrade
|
//if the staff's level is being overridden by the wand, preserve 1 upgrade
|
||||||
if (wand.level() >= this.level() && this.level() > (curseInfusionBonus ? 1 : 0)) targetLevel++;
|
if (wand.trueLevel() >= this.trueLevel() && this.trueLevel() > 0) targetLevel++;
|
||||||
|
|
||||||
level(targetLevel);
|
level(targetLevel);
|
||||||
this.wand = wand;
|
this.wand = wand;
|
||||||
|
@ -416,13 +416,12 @@ public class MagesStaff extends MeleeWeapon {
|
||||||
applyWand((Wand)item);
|
applyWand((Wand)item);
|
||||||
} else {
|
} else {
|
||||||
int newLevel;
|
int newLevel;
|
||||||
int itemLevel = item.level();
|
int itemLevel = item.trueLevel();
|
||||||
itemLevel -= ((Wand)item).resinBonus;
|
if (itemLevel >= trueLevel()){
|
||||||
if (itemLevel >= level()){
|
if (trueLevel() > 0) newLevel = itemLevel + 1;
|
||||||
if (level() > 0) newLevel = itemLevel + 1;
|
|
||||||
else newLevel = itemLevel;
|
else newLevel = itemLevel;
|
||||||
} else {
|
} else {
|
||||||
newLevel = level();
|
newLevel = trueLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
String bodyText = Messages.get(MagesStaff.class, "imbue_desc", newLevel);
|
String bodyText = Messages.get(MagesStaff.class, "imbue_desc", newLevel);
|
||||||
|
|
|
@ -44,6 +44,8 @@ public class GeyserTrap extends Trap {
|
||||||
shape = DIAMOND;
|
shape = DIAMOND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int centerKnockBackDirection = -1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void activate() {
|
public void activate() {
|
||||||
Splash.at( DungeonTilemap.tileCenterToWorld( pos ), -PointF.PI/2, PointF.PI/2, 0x5bc1e3, 100, 0.01f);
|
Splash.at( DungeonTilemap.tileCenterToWorld( pos ), -PointF.PI/2, PointF.PI/2, 0x5bc1e3, 100, 0.01f);
|
||||||
|
@ -51,7 +53,9 @@ public class GeyserTrap extends Trap {
|
||||||
|
|
||||||
PathFinder.buildDistanceMap( pos, BArray.not( Dungeon.level.solid, null ), 2 );
|
PathFinder.buildDistanceMap( pos, BArray.not( Dungeon.level.solid, null ), 2 );
|
||||||
for (int i = 0; i < PathFinder.distance.length; i++) {
|
for (int i = 0; i < PathFinder.distance.length; i++) {
|
||||||
if (PathFinder.distance[i] < Integer.MAX_VALUE) {
|
if (PathFinder.distance[i] == 2 && Random.Int(3) > 0){
|
||||||
|
Dungeon.level.setCellToWater(true, i);
|
||||||
|
} else if (PathFinder.distance[i] < 2){
|
||||||
Dungeon.level.setCellToWater(true, i);
|
Dungeon.level.setCellToWater(true, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,13 +75,15 @@ public class GeyserTrap extends Trap {
|
||||||
Char ch = Actor.findChar(pos);
|
Char ch = Actor.findChar(pos);
|
||||||
if (ch != null){
|
if (ch != null){
|
||||||
int targetpos = -1;
|
int targetpos = -1;
|
||||||
if (ch == Dungeon.hero){
|
if (centerKnockBackDirection != -1){
|
||||||
|
targetpos = centerKnockBackDirection;
|
||||||
|
} else if (ch == Dungeon.hero){
|
||||||
//if it is the hero, random direction that isn't into a hazard
|
//if it is the hero, random direction that isn't into a hazard
|
||||||
ArrayList<Integer> candidates = new ArrayList<>();
|
ArrayList<Integer> candidates = new ArrayList<>();
|
||||||
for (int i : PathFinder.NEIGHBOURS8){
|
for (int i : PathFinder.NEIGHBOURS8){
|
||||||
//add as a candidate if both cells on the trajectory are safe
|
//add as a candidate if both cells on the trajectory are safe
|
||||||
if (!Dungeon.level.avoid[pos + i] && !Dungeon.level.avoid[pos + i + i]){
|
if (!Dungeon.level.avoid[pos + i] && !Dungeon.level.avoid[pos + i + i]){
|
||||||
candidates.add(pos + i + i);
|
candidates.add(pos + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!candidates.isEmpty()){
|
if (!candidates.isEmpty()){
|
||||||
|
@ -85,11 +91,11 @@ public class GeyserTrap extends Trap {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//random direction if it isn't the hero
|
//random direction if it isn't the hero
|
||||||
targetpos = pos + 2*PathFinder.NEIGHBOURS8[Random.Int(8)];
|
targetpos = pos + PathFinder.NEIGHBOURS8[Random.Int(8)];
|
||||||
}
|
}
|
||||||
if (targetpos != -1){
|
if (targetpos != -1){
|
||||||
//trace a ballistica in the direction of our target
|
//trace a ballistica in the direction of our target
|
||||||
Ballistica trajectory = new Ballistica(pos, targetpos, Ballistica.PROJECTILE);
|
Ballistica trajectory = new Ballistica(pos, targetpos, Ballistica.MAGIC_BOLT);
|
||||||
//knock them back along that ballistica
|
//knock them back along that ballistica
|
||||||
WandOfBlastWave.throwChar(ch, trajectory, 2, true);
|
WandOfBlastWave.throwChar(ch, trajectory, 2, true);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user