v2.5.0: overhauled the crossbow's weapon ability

This commit is contained in:
Evan Debenham
2024-07-19 12:21:15 -04:00
parent 1064fbe8f5
commit 3f63a6b401
4 changed files with 74 additions and 15 deletions

View File

@@ -1693,12 +1693,12 @@ 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=charged shot
items.weapon.melee.crossbow.typical_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 to enemies in a 7x7 tile area, and typically last for _%d more uses_ if it is tipped.
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 to enemies in a 7x7 tile area, and last for _%d more uses_ if it is tipped.
items.weapon.melee.crossbow.typical_ability_desc=The Duelist can _charge_ her crossbow, causing her next attack with it to always hit and apply one of three effects: melee attacks will knock enemies away, untipped darts will typically deal _+%1$d damage_, and tipped darts will apply their effect in a 7x7 area and typically last for _%2$d more uses_.
items.weapon.melee.crossbow.ability_desc=The Duelist can _charge_ her crossbow, causing her next attack with it to always hit and apply one of three effects: melee attacks will knock enemies away, untipped darts will deal _+%1$d damage_, and tipped darts will apply their effect in a 7x7 area and last for _%2$d more uses_.
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.upgrade_ability_stat_name=Ability Extra Uses
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 7x7 area. Positive dart effects will only affect allies, and harmful effects will only apply to enemies.\n\nTipped darts will also have extra uses when fired using a charged shot. The Duelist cannot use this ability to apply positive dart effects to herself.
items.weapon.melee.crossbow.upgrade_ability_stat_name=Ability Boost
items.weapon.melee.crossbow$chargedshot.name=charged
items.weapon.melee.crossbow$chargedshot.desc=The Duelist is focusing power into her crossbow. The next attack she makes with it will always hit and apply one of three effects:\n- Melee attacks with knock enemies a few tiles away.\n- Untipped darts will deal bonus damage.\n- Tipped darts will gain extra uses and apply their effect in a 7x7 area. Positive dart effects will only affect allies, and harmful effects will only apply to enemies. 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.

View File

@@ -22,8 +22,13 @@
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
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.items.wands.WandOfBlastWave;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.darts.Dart;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
@@ -55,7 +60,49 @@ public class Crossbow extends MeleeWeapon {
return false;
}
}
@Override
public float accuracyFactor(Char owner, Char target) {
if (owner.buff(Crossbow.ChargedShot.class) != null){
Actor.add(new Actor() {
{ actPriority = VFX_PRIO; }
@Override
protected boolean act() {
if (owner instanceof Hero && !target.isAlive()){
onAbilityKill((Hero)owner, target);
}
Actor.remove(this);
return true;
}
});
return Float.POSITIVE_INFINITY;
} else {
return super.accuracyFactor(owner, target);
}
}
@Override
public int proc(Char attacker, Char defender, int damage) {
int dmg = super.proc(attacker, defender, damage);
//stronger elastic effect
if (attacker.buff(ChargedShot.class) != null && !(curItem instanceof Dart)){
//trace a ballistica to our target (which will also extend past them
Ballistica trajectory = new Ballistica(attacker.pos, defender.pos, Ballistica.STOP_TARGET);
//trim it to just be the part that goes past them
trajectory = new Ballistica(trajectory.collisionPos, trajectory.path.get(trajectory.path.size()-1), Ballistica.PROJECTILE);
//knock them back along that ballistica
WandOfBlastWave.throwChar(defender,
trajectory,
3,
true,
true,
this);
attacker.buff(Crossbow.ChargedShot.class).detach();
}
return dmg;
}
@Override
public int max(int lvl) {
return 4*(tier+1) + //20 base, down from 25
@@ -79,9 +126,9 @@ public class Crossbow extends MeleeWeapon {
@Override
public String abilityInfo() {
if (levelKnown){
return Messages.get(this, "ability_desc", 3+buffedLvl());
return Messages.get(this, "ability_desc", 3+buffedLvl(), 3+buffedLvl());
} else {
return Messages.get(this, "typical_ability_desc", 3);
return Messages.get(this, "typical_ability_desc", 3, 3);
}
}

View File

@@ -307,6 +307,8 @@ public class MeleeWeapon extends Weapon {
ACC *= 1f + 0.1f * ((Hero) owner).pointsInTalent(Talent.PRECISE_ASSAULT);
} else if (this instanceof Flail && owner.buff(Flail.SpinAbilityTracker.class) != null){
//do nothing, this is not a regular attack so don't consume talent fx
} else if (this instanceof Crossbow && owner.buff(Crossbow.ChargedShot.class) != null){
//do nothing, this is not a regular attack so don't consume talent fx
} else if (owner.buff(Talent.PreciseAssaultTracker.class) != null) {
// 2x/5x/inf. ACC for duelist if she just used a weapon ability
switch (((Hero) owner).pointsInTalent(Talent.PRECISE_ASSAULT)){

View File

@@ -78,8 +78,14 @@ public class Dart extends MissileWeapon {
@Override
public int min(int lvl) {
if (bow != null){
return 4 + //4 base
bow.buffedLvl() + lvl; //+1 per level or bow level
if (!(this instanceof TippedDart) && Dungeon.hero.buff(Crossbow.ChargedShot.class) != null){
//ability increases base dmg by 37.5%, scaling by 50%
return 7 + //7 base
2*bow.buffedLvl() + lvl;//+2 per bow level, +1 per level
} else {
return 4 + //4 base
bow.buffedLvl() + lvl; //+1 per level or bow level
}
} else {
return 1 + //1 base, down from 2
lvl; //scaling unchanged
@@ -89,8 +95,14 @@ public class Dart extends MissileWeapon {
@Override
public int max(int lvl) {
if (bow != null){
return 12 + //12 base
3*bow.buffedLvl() + 2*lvl; //+3 per bow level, +2 per level (default scaling +2)
if (!(this instanceof TippedDart) && Dungeon.hero.buff(Crossbow.ChargedShot.class) != null){
//ability increases base dmg by 37.5%, scaling by 50%
return 15 + //15 base
4*bow.buffedLvl() + 2*lvl; //+4 per bow level, +2 per level
} else {
return 12 + //12 base
3*bow.buffedLvl() + 2*lvl; //+3 per bow level, +2 per level
}
} else {
return 2 + //2 base, down from 5
2*lvl; //scaling unchanged
@@ -136,9 +148,7 @@ public class Dart extends MissileWeapon {
@Override
public int proc(Char attacker, Char defender, int damage) {
if (bow != null
//only apply enchant effects to enemies when processing charged shot
&& (!processingChargedShot || attacker.alignment != defender.alignment)){
if (bow != null && !processingChargedShot){
damage = bow.proc(attacker, defender, damage);
}