v2.0.0: added a weapon ability for the ring of force

This commit is contained in:
Evan Debenham
2023-01-06 12:59:51 -05:00
parent 5d32f70631
commit f006e1722a
7 changed files with 191 additions and 10 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -900,7 +900,11 @@ items.rings.ringofevasion.desc=This ring quickens the wearer's reactions, making
items.rings.ringofforce.name=ring of force
items.rings.ringofforce.stats=When unarmed, at your current strength, this ring will deal _%1$d-%2$d damage._ With a weapon equipped, this ring will increase damage by _%3$d._
items.rings.ringofforce.typical_stats=When unarmed, at your current strength, typically this ring will deal _%1$d-%2$d damage._ With a weapon equipped, typically this ring will increase damage by _%3$d._
items.rings.ringofforce.ability_name=brawler's stance
items.rings.ringofforce.ability_desc=The Duelist can adopt a _brawler's stance_ with a ring of force. While in this stance the Duelist's regular attacks will use her ring of force even with a weapon equipped. The ring will also inherit the weapon's enchantment and augmentation. Each regular attack in this stance consumes 1/3 of a weapon charge.
items.rings.ringofforce.desc=This ring enhances the force of the wearer's melee blows. This extra power is fairly weak when wielding weapons, but an unarmed attack will be made much stronger. A cursed ring will instead weaken the wearer's blows.
items.rings.ringofforce$brawlersstance.name=brawler's stance
items.rings.ringofforce$brawlersstance.desc=While in this stance the Duelist's regular attacks will use an equipped ring of force even when she has a weapon equipped. The attack will still use the weapon's augmentation and enchantment however.\n\nEach regular attack in this stance consumes 1/4 of a weapon charge. You currently have enough charge for %d attacks.\n\nThis stance can be toggled on or off by using a ring of force.
items.rings.ringoffuror.name=ring of furor
items.rings.ringoffuror.stats=When worn, this ring will increase the speed of your attacks by _%s%%._
@@ -1494,6 +1498,8 @@ 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.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.dagger.name=dagger

View File

@@ -397,7 +397,7 @@ public class Hero extends Char {
@Override
public void hitSound(float pitch) {
if ( belongings.weapon() != null ){
if (!RingOfForce.fightingUnarmed(this)) {
belongings.weapon().hitSound(pitch);
} else if (RingOfForce.getBuffedBonus(this, RingOfForce.Force.class) > 0) {
//pitch deepens by 2.5% (additive) per point of strength, down to 75%
@@ -474,7 +474,7 @@ public class Hero extends Char {
}
}
if (wep != null) {
if (!RingOfForce.fightingUnarmed(this)) {
return (int)(attackSkill * accuracy * wep.accuracyFactor( this, target ));
} else {
return (int)(attackSkill * accuracy);
@@ -573,7 +573,7 @@ public class Hero extends Char {
KindOfWeapon wep = belongings.weapon();
int dmg;
if (wep != null) {
if (!RingOfForce.fightingUnarmed(this)) {
dmg = wep.damageRoll( this );
if (heroClass != HeroClass.DUELIST
@@ -589,6 +589,9 @@ public class Hero extends Char {
if (!(wep instanceof MissileWeapon)) dmg += RingOfForce.armedDamageBonus(this);
} else {
dmg = RingOfForce.damageRoll(this);
if (RingOfForce.unarmedGetsWeaponEffects(this)){
dmg = ((Weapon)belongings.weapon()).augment.damageFactor(dmg);
}
}
PhysicalEmpower emp = buff(PhysicalEmpower.class);
@@ -644,6 +647,7 @@ public class Hero extends Char {
@Override
public boolean canSurpriseAttack(){
if (belongings.weapon() == null || !(belongings.weapon() instanceof Weapon)) return true;
if (RingOfForce.fightingUnarmed(this)) return true;
if (STR() < ((Weapon)belongings.weapon()).STRReq()) return false;
if (belongings.weapon() instanceof Flail) return false;
@@ -675,7 +679,7 @@ public class Hero extends Char {
return 0;
}
if (belongings.weapon() != null) {
if (!RingOfForce.fightingUnarmed(this)) {
return belongings.weapon().delayFactor( this );
@@ -683,7 +687,13 @@ public class Hero extends Char {
//Normally putting furor speed on unarmed attacks would be unnecessary
//But there's going to be that one guy who gets a furor+force ring combo
//This is for that one guy, you shall get your fists of fury!
return 1f/RingOfFuror.attackSpeedMultiplier(this);
float delay = 1f/RingOfFuror.attackSpeedMultiplier(this);
if (RingOfForce.unarmedGetsWeaponEffects(this)){
delay = ((Weapon)belongings.weapon).augment.delayFactor(delay);
}
return delay;
}
}
@@ -1240,7 +1250,8 @@ public class Hero extends Char {
@Override
public int attackProc( final Char enemy, int damage ) {
damage = super.attackProc( enemy, damage );
//procs with weapon even in brawler's stance
KindOfWeapon wep = belongings.weapon();
if (wep != null) damage = wep.proc( this, enemy, damage );
@@ -1948,6 +1959,18 @@ public class Hero extends Char {
Buff.append( this, Sai.ComboStrikeTracker.class, Sai.ComboStrikeTracker.DURATION);
}
RingOfForce.BrawlersStance brawlStance = buff(RingOfForce.BrawlersStance.class);
if (brawlStance != null && brawlStance.hitsLeft() > 0){
MeleeWeapon.Charger charger = Buff.affect(this, MeleeWeapon.Charger.class);
charger.partialCharge -= 0.25f;
while (charger.partialCharge < 0) {
charger.charges--;
charger.partialCharge++;
}
BuffIndicator.refreshHero();
Item.updateQuickslot();
}
curAction = null;
super.onAttackComplete();

View File

@@ -23,11 +23,19 @@ package com.shatteredpixel.shatteredpixeldungeon.items.rings;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
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.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.Image;
import com.watabou.utils.Random;
import java.util.ArrayList;
public class RingOfForce extends Ring {
{
@@ -99,5 +107,148 @@ public class RingOfForce extends Ring {
public class Force extends RingBuff {
}
//Duelist stuff
public static String AC_ABILITY = "ABILITY";
@Override
public void activate(Char ch) {
super.activate(ch);
if (ch instanceof Hero && ((Hero) ch).heroClass == HeroClass.DUELIST){
Buff.affect(ch, MeleeWeapon.Charger.class);
}
}
@Override
public String defaultAction() {
if (Dungeon.hero != null && Dungeon.hero.heroClass == HeroClass.DUELIST){
return AC_ABILITY;
} else {
return super.defaultAction();
}
}
@Override
public ArrayList<String> actions(Hero hero) {
ArrayList<String> actions = super.actions(hero);
if (isEquipped(hero) && hero.heroClass == HeroClass.DUELIST){
actions.add(AC_ABILITY);
}
return actions;
}
@Override
public String actionName(String action, Hero hero) {
if (action.equals(AC_ABILITY)){
return Messages.upperCase(Messages.get(this, "ability_name"));
} else {
return super.actionName(action, hero);
}
}
@Override
public void execute(Hero hero, String action) {
if (action.equals(AC_ABILITY)){
if (hero.buff(BrawlersStance.class) != null){
hero.buff(BrawlersStance.class).detach();
} else if (!isEquipped(hero)) {
GLog.w(Messages.get(MeleeWeapon.class, "ability_need_equip"));
} else if ((Buff.affect(hero, MeleeWeapon.Charger.class).charges + Buff.affect(hero, MeleeWeapon.Charger.class).partialCharge) < 0.333f){
GLog.w(Messages.get(MeleeWeapon.class, "ability_no_charge"));
} else {
Buff.affect(hero, BrawlersStance.class);
}
} else {
super.execute(hero, action);
}
}
@Override
public String info() {
String info = super.info();
if (Dungeon.hero.heroClass == HeroClass.DUELIST){
info += "\n\n" + Messages.get(this, "ability_desc");
}
return info;
}
public static boolean fightingUnarmed( Hero hero ){
if (hero.belongings.weapon() == null){
return true;
}
if (hero.belongings.thrownWeapon != null || hero.belongings.abilityWeapon != null){
return false;
}
BrawlersStance stance = hero.buff(BrawlersStance.class);
if (stance != null && stance.hitsLeft() > 0){
return true;
}
return false;
}
public static boolean unarmedGetsWeaponEffects( Hero hero ){
if (hero.belongings.weapon() == null){
return false;
}
BrawlersStance stance = hero.buff(BrawlersStance.class);
if (stance != null && stance.hitsLeft() > 0){
return true;
}
return false;
}
public static class BrawlersStance extends Buff {
public static float HIT_CHARGE_USE = 0.25f;
{
announced = true;
type = buffType.POSITIVE;
}
public int hitsLeft(){
MeleeWeapon.Charger charger = Buff.affect(target, MeleeWeapon.Charger.class);
float charges = charger.charges;
charges += charger.partialCharge;
return (int)(charges/HIT_CHARGE_USE);
}
@Override
public int icon() {
return BuffIndicator.DUEL_BRAWL;
}
@Override
public void tintIcon(Image icon) {
if (hitsLeft() == 0){
icon.brightness(0.25f);
} else {
icon.resetColor();
}
}
@Override
public float iconFadePercent() {
float usableCharges = hitsLeft()*HIT_CHARGE_USE;
return 1f - (usableCharges / Buff.affect(target, MeleeWeapon.Charger.class).chargeCap());
}
@Override
public String iconTextDisplay() {
return Integer.toString(hitsLeft());
}
@Override
public String desc() {
return Messages.get(this, "desc", hitsLeft());
}
}
}

View File

@@ -351,13 +351,13 @@ public class MeleeWeapon extends Weapon {
public static class Charger extends Buff implements ActionIndicator.Action {
private int charges = 3;
private float partialCharge;
public int charges = 3;
public float partialCharge;
//offhand charge as well?
//champion subclass
private int secondCharges = 0;
private float secondPartialCharge;
public int secondCharges = 3;
public float secondPartialCharge;
@Override
public boolean act() {

View File

@@ -116,6 +116,7 @@ public class BuffIndicator extends Component {
public static final int DUEL_SPIN = 62;
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 SIZE_SMALL = 7;
public static final int SIZE_LARGE = 16;