v3.2.0: hold fast buffed, now reduces shielding and combo decay

This commit is contained in:
Evan Debenham
2025-07-23 15:26:07 -04:00
parent 12c2e163ef
commit d639069ed1
7 changed files with 66 additions and 17 deletions

View File

@@ -257,7 +257,7 @@ actors.buffs.hex.heromsg=You have been hexed!
actors.buffs.hex.desc=Dark magic which saps focus, making the target slightly disoriented.\n\nHexing reduces accuracy and evasion by 20%%, making the target less effective in combat.\n\nTurns of hex remaining: %s. actors.buffs.hex.desc=Dark magic which saps focus, making the target slightly disoriented.\n\nHexing reduces accuracy and evasion by 20%%, making the target less effective in combat.\n\nTurns of hex remaining: %s.
actors.buffs.holdfast.name=hold fast actors.buffs.holdfast.name=hold fast
actors.buffs.holdfast.desc=The Warrior is holding his position, increasing his armor by %1$d-%2$d. This will last until he moves. actors.buffs.holdfast.desc=The Warrior is holding his position, increasing his armor by %1$d-%2$d and slowing the decay rate of some buffs by %3$d%%. This will last until he moves.
actors.buffs.hunger.hungry=hungry actors.buffs.hunger.hungry=hungry
actors.buffs.hunger.starving=starving actors.buffs.hunger.starving=starving
@@ -922,7 +922,7 @@ actors.hero.talent.improvised_projectiles.title=improvised projectiles
actors.hero.talent.improvised_projectiles.desc=_+1:_ The Warrior can blind an enemy for _2 turns_ by throwing any item that isnt a thrown weapon at them. This has a 50 turn cooldown.\n\n_+2:_ The Warrior can blind an enemy for _3 turns_ by throwing any item that isnt a thrown weapon at them. This has a 50 turn cooldown. actors.hero.talent.improvised_projectiles.desc=_+1:_ The Warrior can blind an enemy for _2 turns_ by throwing any item that isnt a thrown weapon at them. This has a 50 turn cooldown.\n\n_+2:_ The Warrior can blind an enemy for _3 turns_ by throwing any item that isnt a thrown weapon at them. This has a 50 turn cooldown.
actors.hero.talent.hold_fast.title=hold fast actors.hero.talent.hold_fast.title=hold fast
actors.hero.talent.hold_fast.desc=_+1:_ When the Warrior waits he gains _1-2 armor_ until he moves.\n\n_+2:_ When the Warrior waits he gains _2-4 armor_ until he moves.\n\n_+3:_ When the Warrior waits he gains _3-6 armor_ until he moves. actors.hero.talent.hold_fast.desc=_+1:_ When the Warrior waits he gains _1-2 armor_ and slows the decay of combo and shielding buffs by _50%_ until he moves.\n\n_+2:_ When the Warrior waits he gains _2-4 armor_ and slows the decay of combo and shielding buffs by _75%_ until he moves.\n\n_+3:_ When the Warrior waits he gains _3-6 armor_ and slows the decay of combo and shielding buffs by _100%_ until he moves.
actors.hero.talent.strongman.title=strongman actors.hero.talent.strongman.title=strongman
actors.hero.talent.strongman.desc=_+1:_ The Warrior's strength is _increased by 8%_, rounded down.\n\n_+2:_ The Warrior's strength is _increased by 13%_, rounded down.\n\n_+3:_ The Warrior's strength is _increased by 18%_, rounded down. actors.hero.talent.strongman.desc=_+1:_ The Warrior's strength is _increased by 8%_, rounded down.\n\n_+2:_ The Warrior's strength is _increased by 13%_, rounded down.\n\n_+3:_ The Warrior's strength is _increased by 18%_, rounded down.

View File

@@ -51,7 +51,7 @@ public class Barrier extends ShieldBuff {
@Override @Override
public boolean act() { public boolean act() {
partialLostShield += Math.min(1f, shielding()/20f); partialLostShield += Math.min(1f, shielding()/20f) * HoldFast.buffDecayFactor(target);
if (partialLostShield >= 1f) { if (partialLostShield >= 1f) {
absorbDamage(1); absorbDamage(1);

View File

@@ -42,6 +42,7 @@ import com.watabou.noosa.Visual;
import com.watabou.noosa.audio.Sample; import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundle; import com.watabou.utils.Bundle;
import com.watabou.utils.GameMath; import com.watabou.utils.GameMath;
import com.watabou.utils.Random;
public class Berserk extends ShieldBuff implements ActionIndicator.Action { public class Berserk extends ShieldBuff implements ActionIndicator.Action {
@@ -102,9 +103,12 @@ public class Berserk extends ShieldBuff implements ActionIndicator.Action {
if (state == State.BERSERK){ if (state == State.BERSERK){
if (target.shielding() > 0) { if (target.shielding() > 0) {
//lose 2.5% of shielding per turn, but no less than 1 //lose 2.5% of shielding per turn, but no less than 1
int dmg = (int)Math.ceil(target.shielding() * 0.025f); float dmg = (float)Math.ceil(target.shielding() * 0.025f) * HoldFast.buffDecayFactor(target);
if (Random.Float() < dmg % 1){
dmg++;
}
dmg = ShieldBuff.processDamage(target, dmg, this); ShieldBuff.processDamage(target, (int)dmg, this);
if (target.shielding() <= 0){ if (target.shielding() <= 0){
state = State.RECOVERING; state = State.RECOVERING;

View File

@@ -123,7 +123,7 @@ public class Combo extends Buff implements ActionIndicator.Action {
@Override @Override
public boolean act() { public boolean act() {
comboTime-=TICK; comboTime -= TICK * HoldFast.buffDecayFactor(target);
spend(TICK); spend(TICK);
if (comboTime <= 0) { if (comboTime <= 0) {
detach(); detach();

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.buffs; package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
@@ -57,6 +58,24 @@ public class HoldFast extends Buff {
} }
} }
public static float buffDecayFactor(Char target){
HoldFast buff = target.buff(HoldFast.class);
if (buff != null && target.pos == buff.pos && target instanceof Hero){
switch (((Hero) target).pointsInTalent(Talent.HOLD_FAST)){
case 1:
return 0.5f;
case 2:
return 0.25f;
case 3:
return 0;
}
} else if (buff != null) {
buff.detach();
}
return 1;
}
@Override @Override
public int icon() { public int icon() {
return BuffIndicator.ARMOR; return BuffIndicator.ARMOR;
@@ -69,7 +88,10 @@ public class HoldFast extends Buff {
@Override @Override
public String desc() { public String desc() {
return Messages.get(this, "desc", Dungeon.hero.pointsInTalent(Talent.HOLD_FAST), 2*Dungeon.hero.pointsInTalent(Talent.HOLD_FAST)); return Messages.get(this, "desc",
Dungeon.hero.pointsInTalent(Talent.HOLD_FAST),
2*Dungeon.hero.pointsInTalent(Talent.HOLD_FAST),
25 + 25*Dungeon.hero.pointsInTalent(Talent.HOLD_FAST));
} }
private static final String POS = "pos"; private static final String POS = "pos";

View File

@@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items;
import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Combo; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Combo;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.HoldFast;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Regeneration; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Regeneration;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ShieldBuff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ShieldBuff;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Belongings; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Belongings;
@@ -254,7 +255,7 @@ public class BrokenSeal extends Item {
private Armor armor; private Armor armor;
private int cooldown = 0; private int cooldown = 0;
private int turnsSinceEnemies = 0; private float turnsSinceEnemies = 0;
private static int COOLDOWN_START = 150; private static int COOLDOWN_START = 150;
@@ -315,7 +316,7 @@ public class BrokenSeal extends Item {
if (shielding() > 0){ if (shielding() > 0){
if (Dungeon.hero.visibleEnemies() == 0 && Dungeon.hero.buff(Combo.class) == null){ if (Dungeon.hero.visibleEnemies() == 0 && Dungeon.hero.buff(Combo.class) == null){
turnsSinceEnemies++; turnsSinceEnemies += HoldFast.buffDecayFactor(target);
if (turnsSinceEnemies >= 5){ if (turnsSinceEnemies >= 5){
if (cooldown > 0) { if (cooldown > 0) {
float percentLeft = shielding() / (float)maxShield(); float percentLeft = shielding() / (float)maxShield();
@@ -384,7 +385,7 @@ public class BrokenSeal extends Item {
super.restoreFromBundle(bundle); super.restoreFromBundle(bundle);
if (bundle.contains(COOLDOWN)) { if (bundle.contains(COOLDOWN)) {
cooldown = bundle.getInt(COOLDOWN); cooldown = bundle.getInt(COOLDOWN);
turnsSinceEnemies = bundle.getInt(TURNS_SINCE_ENEMIES); turnsSinceEnemies = bundle.getFloat(TURNS_SINCE_ENEMIES);
//if we have shield from pre-3.1, have it last a bit //if we have shield from pre-3.1, have it last a bit
} else if (shielding() > 0) { } else if (shielding() > 0) {

View File

@@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barrier; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barrier;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.HoldFast;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ShieldBuff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ShieldBuff;
import com.shatteredpixel.shatteredpixeldungeon.effects.FloatingText; import com.shatteredpixel.shatteredpixeldungeon.effects.FloatingText;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
@@ -33,6 +34,7 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.watabou.noosa.Image; import com.watabou.noosa.Image;
import com.watabou.utils.Bundle;
import com.watabou.utils.Random; import com.watabou.utils.Random;
public class Blocking extends Weapon.Enchantment { public class Blocking extends Weapon.Enchantment {
@@ -65,7 +67,7 @@ public class Blocking extends Weapon.Enchantment {
public ItemSprite.Glowing glowing() { public ItemSprite.Glowing glowing() {
return BLUE; return BLUE;
} }
public static class BlockBuff extends ShieldBuff { public static class BlockBuff extends ShieldBuff {
{ {
@@ -74,16 +76,23 @@ public class Blocking extends Weapon.Enchantment {
shieldUsePriority = 2; shieldUsePriority = 2;
} }
private float left = 5f;
@Override @Override
public boolean act() { public boolean act() {
detach(); left -= HoldFast.buffDecayFactor(target);
if (left <= 0) {
detach();
} else {
spend(TICK);
}
return true; return true;
} }
@Override @Override
public void setShield(int shield) { public void setShield(int shield) {
super.setShield(shield); super.setShield(shield);
postpone(5f); left = 5f;
} }
@Override @Override
@@ -107,18 +116,31 @@ public class Blocking extends Weapon.Enchantment {
@Override @Override
public float iconFadePercent() { public float iconFadePercent() {
return Math.max(0, (5f - visualcooldown()) / 5f); return Math.max(0, (5f - left) / 5f);
} }
@Override @Override
public String iconTextDisplay() { public String iconTextDisplay() {
return Integer.toString((int)visualcooldown()); return Integer.toString((int)left);
} }
@Override @Override
public String desc() { public String desc() {
return Messages.get(this, "desc", shielding(), dispTurns(visualcooldown())); return Messages.get(this, "desc", shielding(), dispTurns(left));
}
public static String LEFT = "left";
@Override
public void storeInBundle(Bundle bundle) {
super.storeInBundle(bundle);
bundle.put(LEFT, left);
}
@Override
public void restoreFromBundle(Bundle bundle) {
super.restoreFromBundle(bundle);
left = bundle.getFloat(LEFT);
} }
} }
} }