diff --git a/core/src/main/assets/interfaces/buffs.png b/core/src/main/assets/interfaces/buffs.png index 3f1f00d9a..f8cb82a25 100644 Binary files a/core/src/main/assets/interfaces/buffs.png and b/core/src/main/assets/interfaces/buffs.png differ diff --git a/core/src/main/assets/interfaces/large_buffs.png b/core/src/main/assets/interfaces/large_buffs.png index b9fe51c04..ace48dab3 100644 Binary files a/core/src/main/assets/interfaces/large_buffs.png and b/core/src/main/assets/interfaces/large_buffs.png differ diff --git a/core/src/main/assets/messages/items/items.properties b/core/src/main/assets/messages/items/items.properties index 33b6541b7..2dd488be5 100644 --- a/core/src/main/assets/messages/items/items.properties +++ b/core/src/main/assets/messages/items/items.properties @@ -1498,9 +1498,11 @@ items.weapon.melee.battleaxe.desc=The enormous steel head of this battle axe put items.weapon.melee.crossbow.name=crossbow items.weapon.melee.crossbow.stats_desc=This weapon enhances the damage of thrown darts when equipped, and will even grant its enchantment to them. -items.weapon.melee.crossbow.ability_name=heavy blow -items.weapon.melee.crossbow.ability_desc=The Duelist can peform a _..._ with a crossbow. This attack causes the next fired dart to always hit and apply on-hit effects to all characters in a 5x5 tile radius. +items.weapon.melee.crossbow.ability_name=charged shot +items.weapon.melee.crossbow.ability_desc=The Duelist can ready a _charged shot_ with a crossbow. This ability activates instantly and causes the next fired dart to always hit, apply on-hit effects in a 3x3 tile area, and last longer if it is tipped. items.weapon.melee.crossbow.desc=A fairly intricate weapon which shoots bolts at exceptional speeds. While it isn't designed for it, this crossbow's heft and sturdy construction make it a decent melee weapon as well. +items.weapon.melee.crossbow$chargedshot.name=charged shot +items.weapon.melee.crossbow$chargedshot.desc=The Duelist is focusing power into her crossbow. The next dart she fires with it will always hit and apply tipped dart effects and the crossbow's enchantment in a 3x3 area. Tipped darts will also have one extra use when fired using a charged shot. The Duelist cannot use this ability to apply positive dart effects to herself. items.weapon.melee.dagger.name=dagger items.weapon.melee.dagger.stats_desc=This weapon is stronger against unaware enemies. diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Crossbow.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Crossbow.java index 2851d82e2..d1c84ec57 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Crossbow.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Crossbow.java @@ -22,7 +22,10 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee; import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; public class Crossbow extends MeleeWeapon { @@ -41,4 +44,28 @@ public class Crossbow extends MeleeWeapon { return 4*(tier+1) + //20 base, down from 25 lvl*(tier); //+4 per level, down from +5 } + + @Override + protected void duelistAbility(Hero hero, Integer target) { + beforeAbilityUsed(hero); + Buff.affect(hero, ChargedShot.class); + hero.sprite.operate(hero.pos); + hero.next(); + afterAbilityUsed(hero); + } + + public static class ChargedShot extends Buff{ + + { + announced = true; + type = buffType.POSITIVE; + } + + @Override + public int icon() { + return BuffIndicator.DUEL_XBOW; + } + + } + } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/MeleeWeapon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/MeleeWeapon.java index 866cc7cc2..a71e0a464 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/MeleeWeapon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/MeleeWeapon.java @@ -157,8 +157,9 @@ public class MeleeWeapon extends Weapon { return dst; //weapon abilities do not use projectile logic, no autoaim } - //TODO make abstract - protected void duelistAbility( Hero hero, Integer target ){} + protected void duelistAbility( Hero hero, Integer target ){ + //do nothing by default + } protected void beforeAbilityUsed(Hero hero ){ hero.belongings.abilityWeapon = this; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/AdrenalineDart.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/AdrenalineDart.java index 876f85f2a..59e15edcf 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/AdrenalineDart.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/AdrenalineDart.java @@ -21,6 +21,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.darts; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Adrenaline; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; @@ -36,7 +37,7 @@ public class AdrenalineDart extends TippedDart { @Override public int proc(Char attacker, Char defender, int damage) { - if (attacker.alignment == defender.alignment){ + if (attacker.alignment == defender.alignment && defender != attacker){ Buff.prolong( defender, Adrenaline.class, Adrenaline.DURATION); return 0; } else { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/CleansingDart.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/CleansingDart.java index bf60ec92b..2db6d9806 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/CleansingDart.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/CleansingDart.java @@ -39,7 +39,7 @@ public class CleansingDart extends TippedDart { @Override public int proc(Char attacker, final Char defender, int damage) { - if (attacker.alignment == defender.alignment){ + if (attacker.alignment == defender.alignment && defender != attacker){ PotionOfCleansing.cleanse(defender, PotionOfCleansing.Cleanse.DURATION*2f); return 0; } else { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/Dart.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/Dart.java index 460c2e1d7..4c7449e15 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/Dart.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/Dart.java @@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.darts; 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.MagicImmune; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; @@ -39,6 +40,7 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag; import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions; import com.watabou.noosa.audio.Sample; +import com.watabou.utils.PathFinder; import com.watabou.utils.Random; import java.util.ArrayList; @@ -120,7 +122,17 @@ public class Dart extends MissileWeapon { return super.hasEnchant(type, owner); } } - + + @Override + public float accuracyFactor(Char owner, Char target) { + //don't update xbow here, as dart is the active weapon atm + if (bow != null && owner.buff(Crossbow.ChargedShot.class) != null){ + return Char.INFINITE_ACCURACY; + } else { + return super.accuracyFactor(owner, target); + } + } + @Override public int proc(Char attacker, Char defender, int damage) { if (bow != null){ @@ -140,6 +152,21 @@ public class Dart extends MissileWeapon { protected void onThrow(int cell) { updateCrossbow(); super.onThrow(cell); + processChargedShot(cell); + } + + protected void processChargedShot( int cell ){ + //don't update xbow here, as dart may be the active weapon atm + if (bow != null && Dungeon.hero.buff(Crossbow.ChargedShot.class) != null) { + PathFinder.buildDistanceMap(cell, Dungeon.level.passable, 1); + for (Char ch : Actor.chars()){ + if (PathFinder.distance[ch.pos] != Integer.MAX_VALUE){ + proc(Dungeon.hero, ch, 0); + } + } + + Dungeon.hero.buff(Crossbow.ChargedShot.class).detach(); + } } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/HealingDart.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/HealingDart.java index 1d715003c..6b266c236 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/HealingDart.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/HealingDart.java @@ -21,6 +21,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.darts; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Healing; @@ -35,6 +36,10 @@ public class HealingDart extends TippedDart { @Override public int proc(Char attacker, Char defender, int damage) { + + if (defender == attacker){ + return super.proc(attacker, defender, damage); + } //heals 30 hp at base, scaling with enemy HT PotionOfHealing.cure( defender ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/HolyDart.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/HolyDart.java index ae611087c..b8723b550 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/HolyDart.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/HolyDart.java @@ -40,7 +40,7 @@ public class HolyDart extends TippedDart { @Override public int proc(Char attacker, Char defender, int damage) { - if (attacker.alignment == defender.alignment){ + if (attacker.alignment == defender.alignment && defender != attacker){ Buff.affect(defender, Bless.class, Math.round(Bless.DURATION)); return 0; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/IncendiaryDart.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/IncendiaryDart.java index 63e79ef23..aaf04ac44 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/IncendiaryDart.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/IncendiaryDart.java @@ -46,6 +46,7 @@ public class IncendiaryDart extends TippedDart { if (durability > 0){ super.onThrow(cell); } else { + processChargedShot(cell); Dungeon.level.drop(new Dart(), cell).sprite.drop(); } } else{ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/TippedDart.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/TippedDart.java index 01a38aec8..e920014d9 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/TippedDart.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/TippedDart.java @@ -31,6 +31,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent; import com.shatteredpixel.shatteredpixeldungeon.items.Generator; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfRegrowth; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Crossbow; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.plants.Blindweed; @@ -178,6 +179,11 @@ public abstract class TippedDart extends Dart { } } use *= (1f - lotusPreserve); + + //grants 1 extra use with charged shot + if (Dungeon.hero.buff(Crossbow.ChargedShot.class) != null){ + use = 100f/((use/100f) + 1f) + 0.001f; + } return use; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java index cb17212d4..d6f83ceef 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java @@ -117,6 +117,7 @@ public class BuffIndicator extends Component { public static final int DUEL_EVASIVE= 63; public static final int DUEL_DANCE = 64; public static final int DUEL_BRAWL = 65; + public static final int DUEL_XBOW = 66; public static final int SIZE_SMALL = 7; public static final int SIZE_LARGE = 16;