v0.6.5: significant berserker changes
This commit is contained in:
parent
7d3622b3a9
commit
67d9e83b20
|
@ -23,7 +23,6 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.SpellSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.BrokenSeal.WarriorShield;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
|
@ -36,107 +35,86 @@ import com.watabou.utils.Bundle;
|
|||
public class Berserk extends Buff {
|
||||
|
||||
private enum State{
|
||||
NORMAL, BERSERK, EXHAUSTED, RECOVERING;
|
||||
NORMAL, BERSERK, RECOVERING;
|
||||
}
|
||||
private State state = State.NORMAL;
|
||||
|
||||
private static final int EXHAUSTION_START = 30;
|
||||
private int exhaustion;
|
||||
|
||||
private static final float LEVEL_RECOVER_START = 2f;
|
||||
private float levelRecovery;
|
||||
|
||||
private int pastRages = 0;
|
||||
private float power = 0;
|
||||
|
||||
private static final String STATE = "state";
|
||||
private static final String EXHAUSTION = "exhaustion";
|
||||
private static final String LEVEL_RECOVERY = "levelrecovery";
|
||||
private static final String PAST_RAGES = "pastrages";
|
||||
private static final String POWER = "power";
|
||||
|
||||
@Override
|
||||
public void storeInBundle(Bundle bundle) {
|
||||
super.storeInBundle(bundle);
|
||||
bundle.put(STATE, state);
|
||||
if (state == State.EXHAUSTED) bundle.put(EXHAUSTION, exhaustion);
|
||||
if (state == State.EXHAUSTED || state == State.RECOVERING) bundle.put(LEVEL_RECOVERY, levelRecovery);
|
||||
bundle.put( PAST_RAGES, pastRages );
|
||||
bundle.put(POWER, power);
|
||||
if (state == State.RECOVERING) bundle.put(LEVEL_RECOVERY, levelRecovery);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle(Bundle bundle) {
|
||||
super.restoreFromBundle(bundle);
|
||||
state = bundle.getEnum(STATE, State.class);
|
||||
if (state == State.EXHAUSTED) exhaustion = bundle.getInt(EXHAUSTION);
|
||||
if (state == State.EXHAUSTED || state == State.RECOVERING) levelRecovery = bundle.getFloat(LEVEL_RECOVERY);
|
||||
pastRages = bundle.getInt(PAST_RAGES);
|
||||
//pre-0.6.5 saves
|
||||
if (bundle.contains("exhaustion")){
|
||||
state = State.RECOVERING;
|
||||
} else {
|
||||
state = bundle.getEnum(STATE, State.class);
|
||||
}
|
||||
if (bundle.contains(POWER)){
|
||||
power = bundle.getFloat(POWER);
|
||||
} else {
|
||||
power = 1f;
|
||||
}
|
||||
if (state == State.RECOVERING) levelRecovery = bundle.getFloat(LEVEL_RECOVERY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean act() {
|
||||
if (berserking()){
|
||||
if (target.HP <= 0) {
|
||||
target.SHLD -= Math.min(target.SHLD, 2);
|
||||
if (target.SHLD == 0) {
|
||||
target.SHLD -= 1 + Math.ceil(target.SHLD * 0.1f);
|
||||
if (target.SHLD <= 0) {
|
||||
target.SHLD = 0;
|
||||
target.die(this);
|
||||
if (!target.isAlive()) Dungeon.fail(this.getClass());
|
||||
}
|
||||
} else {
|
||||
state = State.EXHAUSTED;
|
||||
exhaustion = EXHAUSTION_START;
|
||||
state = State.RECOVERING;
|
||||
levelRecovery = LEVEL_RECOVER_START;
|
||||
BuffIndicator.refreshHero();
|
||||
target.SHLD = 0;
|
||||
pastRages++;
|
||||
power = 0f;
|
||||
}
|
||||
} else {
|
||||
} else if (state == State.NORMAL) {
|
||||
power -= 0.01f * (target.HP/(float)target.HT);
|
||||
|
||||
if (target.HP > targetHPMax()){
|
||||
target.HP = Math.max(targetHPMax(), target.HP - 1);
|
||||
if (target instanceof Hero){
|
||||
((Hero) target).resting = false;
|
||||
target.remove(MagicalSleep.class);
|
||||
}
|
||||
}
|
||||
|
||||
if (state == State.EXHAUSTED){
|
||||
exhaustion--;
|
||||
if (exhaustion == 0){
|
||||
state = State.RECOVERING;
|
||||
BuffIndicator.refreshHero();
|
||||
}
|
||||
if (power <= 0){
|
||||
detach();
|
||||
}
|
||||
BuffIndicator.refreshHero();
|
||||
}
|
||||
spend(TICK);
|
||||
return true;
|
||||
}
|
||||
|
||||
public int damageFactor(int dmg){
|
||||
float bonus;
|
||||
|
||||
if (state == State.BERSERK){
|
||||
bonus = 2f;
|
||||
} else if (state == State.EXHAUSTED) {
|
||||
bonus = 1f - ((float)Math.sqrt(exhaustion) / 10f);
|
||||
} else {
|
||||
float percentMissing = 1f - target.HP/(float)targetHPMax();
|
||||
bonus = 1f + (0.5f * (float)Math.pow(percentMissing, 2));
|
||||
}
|
||||
|
||||
float bonus = Math.min(1.5f, 1f + (power / 2f));
|
||||
return Math.round(dmg * bonus);
|
||||
}
|
||||
|
||||
public int targetHPMax(){
|
||||
return Math.round(target.HT * Math.round(20* Math.pow(0.8f, pastRages))/20f);
|
||||
}
|
||||
|
||||
public boolean berserking(){
|
||||
if (target.HP == 0 && state == State.NORMAL){
|
||||
if (target.HP == 0 && state == State.NORMAL && power >= 1f){
|
||||
|
||||
WarriorShield shield = target.buff(WarriorShield.class);
|
||||
if (shield != null){
|
||||
state = State.BERSERK;
|
||||
BuffIndicator.refreshHero();
|
||||
target.SHLD = shield.maxShield() * 5;
|
||||
target.SHLD = shield.maxShield() * 10;
|
||||
|
||||
SpellSprite.show(target, SpellSprite.BERSERK);
|
||||
Sample.INSTANCE.play( Assets.SND_CHALLENGE );
|
||||
|
@ -147,13 +125,18 @@ public class Berserk extends Buff {
|
|||
|
||||
return state == State.BERSERK;
|
||||
}
|
||||
|
||||
public void damage(int damage){
|
||||
if (state == State.RECOVERING) return;
|
||||
power = Math.min(1.1f, power + ( 0.5f * damage/(float)target.HT) );
|
||||
}
|
||||
|
||||
public void recover(float percent){
|
||||
if (levelRecovery > 0){
|
||||
levelRecovery -= percent;
|
||||
BuffIndicator.refreshHero();
|
||||
if (levelRecovery <= 0) {
|
||||
state = State.NORMAL;
|
||||
BuffIndicator.refreshHero();
|
||||
levelRecovery = 0;
|
||||
}
|
||||
}
|
||||
|
@ -168,16 +151,13 @@ public class Berserk extends Buff {
|
|||
public void tintIcon(Image icon) {
|
||||
switch (state){
|
||||
case NORMAL: default:
|
||||
icon.hardlight(1f, 0.67f, 0.2f);
|
||||
if (power < 1f) icon.hardlight(1f, 1f - 0.6f*power, 0f);
|
||||
else icon.hardlight(1f, 0f, 0f);
|
||||
break;
|
||||
case BERSERK:
|
||||
icon.hardlight(1f, 0.1f, 0.1f);
|
||||
break;
|
||||
case EXHAUSTED:
|
||||
icon.resetColor();
|
||||
icon.hardlight(1f, 0f, 0f);
|
||||
break;
|
||||
case RECOVERING:
|
||||
//icon.hardlight(0.12f, 0.20f, 0.55f);
|
||||
icon.hardlight(0.35f, 0.45f, 0.75f);
|
||||
break;
|
||||
}
|
||||
|
@ -190,8 +170,6 @@ public class Berserk extends Buff {
|
|||
return Messages.get(this, "angered");
|
||||
case BERSERK:
|
||||
return Messages.get(this, "berserk");
|
||||
case EXHAUSTED:
|
||||
return Messages.get(this, "exhausted");
|
||||
case RECOVERING:
|
||||
return Messages.get(this, "recovering");
|
||||
}
|
||||
|
@ -199,27 +177,15 @@ public class Berserk extends Buff {
|
|||
|
||||
@Override
|
||||
public String desc() {
|
||||
float dispDamage = damageFactor(100);
|
||||
String text;
|
||||
float dispDamage = (damageFactor(10000) / 100f) - 100f;
|
||||
switch (state){
|
||||
case NORMAL: default:
|
||||
text = Messages.get(this, "angered_desc", dispDamage);
|
||||
break;
|
||||
return Messages.get(this, "angered_desc", Math.floor(power * 100f), dispDamage);
|
||||
case BERSERK:
|
||||
return Messages.get(this, "berserk_desc");
|
||||
case EXHAUSTED:
|
||||
text = Messages.get(this, "exhausted_desc", exhaustion , dispDamage);
|
||||
break;
|
||||
case RECOVERING:
|
||||
text = Messages.get(this, "recovering_desc", levelRecovery, dispDamage);
|
||||
break;
|
||||
return Messages.get(this, "recovering_desc", levelRecovery);
|
||||
}
|
||||
if (pastRages == 0){
|
||||
text += "\n\n" + Messages.get(this, "no_rages");
|
||||
} else {
|
||||
int dispPercent = (int)(targetHPMax()/(float)target.HT * 100);
|
||||
text += "\n\n" + Messages.get(this, "past_rages", pastRages, dispPercent);
|
||||
}
|
||||
return text;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,6 +69,6 @@ public class Regeneration extends Buff {
|
|||
}
|
||||
|
||||
public int regencap(){
|
||||
return target.buff(Berserk.class) == null ? target.HT : target.buff(Berserk.class).targetHPMax();
|
||||
return target.HT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -236,8 +236,6 @@ public class Hero extends Char {
|
|||
heroClass = HeroClass.restoreInBundle( bundle );
|
||||
subClass = HeroSubClass.restoreInBundle( bundle );
|
||||
|
||||
berserk = subClass == HeroSubClass.BERSERKER ? buff(Berserk.class) : null;
|
||||
|
||||
attackSkill = bundle.getInt( ATTACK );
|
||||
defenseSkill = bundle.getInt( DEFENSE );
|
||||
|
||||
|
@ -361,10 +359,10 @@ public class Hero extends Char {
|
|||
dmg = RingOfForce.damageRoll(this);
|
||||
}
|
||||
if (dmg < 0) dmg = 0;
|
||||
if (subClass == HeroSubClass.BERSERKER){
|
||||
berserk = Buff.affect(this, Berserk.class);
|
||||
dmg = berserk.damageFactor(dmg);
|
||||
}
|
||||
|
||||
Berserk berserk = buff(Berserk.class);
|
||||
if (berserk != null) dmg = berserk.damageFactor(dmg);
|
||||
|
||||
return buff( Fury.class ) != null ? (int)(dmg * 1.5f) : dmg;
|
||||
}
|
||||
|
||||
|
@ -926,6 +924,11 @@ public class Hero extends Char {
|
|||
@Override
|
||||
public int defenseProc( Char enemy, int damage ) {
|
||||
|
||||
if (damage > 0 && subClass == HeroSubClass.BERSERKER){
|
||||
Berserk berserk = Buff.affect(this, Berserk.class);
|
||||
berserk.damage(damage);
|
||||
}
|
||||
|
||||
if (belongings.armor != null) {
|
||||
damage = belongings.armor.proc( enemy, this, damage );
|
||||
}
|
||||
|
@ -966,10 +969,6 @@ public class Hero extends Char {
|
|||
dmg -= Random.NormalIntRange(belongings.armor.DRMin(), belongings.armor.DRMax())/3;
|
||||
}
|
||||
|
||||
if (subClass == HeroSubClass.BERSERKER && berserk == null){
|
||||
berserk = Buff.affect(this, Berserk.class);
|
||||
}
|
||||
|
||||
super.damage( dmg, src );
|
||||
}
|
||||
|
||||
|
@ -1188,11 +1187,9 @@ public class Hero extends Char {
|
|||
|
||||
HornOfPlenty.hornRecharge horn = buff(HornOfPlenty.hornRecharge.class);
|
||||
if (horn != null) horn.gainCharge(percent);
|
||||
|
||||
if (subClass == HeroSubClass.BERSERKER){
|
||||
berserk = Buff.affect(this, Berserk.class);
|
||||
berserk.recover(percent);
|
||||
}
|
||||
|
||||
Berserk berserk = buff(Berserk.class);
|
||||
if (berserk != null) berserk.recover(percent);
|
||||
|
||||
boolean levelUp = false;
|
||||
while (this.exp >= maxExp()) {
|
||||
|
@ -1393,13 +1390,14 @@ public class Hero extends Char {
|
|||
|
||||
@Override
|
||||
public boolean isAlive() {
|
||||
if (subClass == HeroSubClass.BERSERKER
|
||||
&& berserk != null
|
||||
&& berserk.berserking()
|
||||
&& SHLD > 0){
|
||||
return true;
|
||||
|
||||
if (HP <= 0){
|
||||
if (berserk == null) berserk = buff(Berserk.class);
|
||||
return berserk != null && berserk.berserking();
|
||||
} else {
|
||||
berserk = null;
|
||||
return super.isAlive();
|
||||
}
|
||||
return super.isAlive();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -23,8 +23,6 @@ package com.shatteredpixel.shatteredpixeldungeon.items;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Berserk;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||
|
@ -124,8 +122,5 @@ public class TomeOfMastery extends Item {
|
|||
curUser.sprite.emitter().burst( Speck.factory( Speck.MASTERY ), 12 );
|
||||
GLog.w( Messages.get(this, "way", way.title()) );
|
||||
|
||||
if (way == HeroSubClass.BERSERKER) {
|
||||
Buff.affect( curUser, Berserk.class );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,10 +45,9 @@ actors.buffs.berserk.angered=Angered
|
|||
actors.buffs.berserk.berserk=Berserking
|
||||
actors.buffs.berserk.exhausted=Exhausted
|
||||
actors.buffs.berserk.recovering=Recovering
|
||||
actors.buffs.berserk.angered_desc=The severity of the berserker's injuries strengthen his blows. The lower the berserker's health is, the more bonus damage he will deal. This bonus is significantly stronger when the berserker is close to death.\n\nWhen the berserker is brought to 0 hp and is wearing his seal, he will go berserk and _refuse to die_ for a short time.\n\nCurrent damage: _%.0f%%_
|
||||
actors.buffs.berserk.berserk_desc=At the brink of death, fear and uncertainty bleed away, leaving only anger. In this state of near-death the berserker is incredibly powerful, _dealing double damage, gaining bonus shielding, and refusing to die._\n\nThis bonus shielding is stronger the better the berserker's armor, and will slowly deplete over time. When this shielding is reduced to 0, the berserker will give in and die.\n\nAny form of healing will return the berserker to stability, but he will be exhausted. While exhausted, the berserker will suffer a large reduction in damage for a short time, and then will need to gain experience before being able to berserk again.
|
||||
actors.buffs.berserk.exhausted_desc=Inner strength has its limits. The berserker is exhausted, weakening him and making him unable to rage.\n\nIn this state The berserker deals significantly reduced damage, and will _immediately die at 0 health._\n\nTurns of exhaustion remaining: _%d_\nCurrent damage: _%.0f%%_
|
||||
actors.buffs.berserk.recovering_desc=Inner strength has its limits. The berserker must rest before using his rage again.\n\nWhile recovering the berserker still deals bonus damage, but will _immediately die at 0 health._\n\nLevels until recovered: _%.2f_\nCurrent damage: _%.0f%%_
|
||||
actors.buffs.berserk.angered_desc=The severity of the berserker's injuries strengthen his blows. As the berserker takes physical damage, his rage will build, granting him bonus damage. Damage which is blocked by armor still counts towards building rage.\n\nRage will fade over time. The lower the berserker's health, the longer it will last.\n\nIf the berserker is brought to 0 hp while at full rage, and is wearing his seal, he will go berserk and _refuse to die_ for a short time.\n\nCurrent Rage: _%.0f%%_ \n_+%.0f%%_ damage
|
||||
actors.buffs.berserk.berserk_desc=At the brink of death, fear and uncertainty bleed away, leaving only anger. In this state of near-death the berserker is extremely powerful _dealing +50% damage, gaining bonus shielding, and refusing to die._\n\nThis bonus shielding is stronger the better the berserker's armor, and will deplete over time. When this shielding is reduced to 0, the berserker will give in and die.\n\nAny form of healing will return the berserker to stability, but he will be exhausted. While exhausted, the berserker will need to gain experience before being able to build rage again.
|
||||
actors.buffs.berserk.recovering_desc=Inner strength has its limits. The berserker must rest before using his rage again.\n\nWhile recovering the berserker does not build any rage from taking damage.\n\nLevels until recovered: _%.2f_
|
||||
actors.buffs.berserk.no_rages=Berserking will also permanently wear on him, reducing his max health each time.
|
||||
actors.buffs.berserk.past_rages=Times berserker has raged: _%d_\nMax health reduced to: _%d%%_
|
||||
actors.buffs.berserk.rankings_desc=Berserked to Death
|
||||
|
@ -276,7 +275,7 @@ actors.hero.heroclass.huntress_desc_subclasses=A subclass can be chosen after de
|
|||
actors.hero.herosubclass.gladiator=gladiator
|
||||
actors.hero.herosubclass.gladiator_desc=A successful attack with a melee weapon allows the _Gladiator_ to start a combo. Building combo allows him to use unique finisher moves.
|
||||
actors.hero.herosubclass.berserker=berserker
|
||||
actors.hero.herosubclass.berserker_desc=The _Berserker_ deals bonus damage scaling with the severity of his wounds. When reduced to 0 health, he will _refuse to die_ for a short time, at the cost of exhaustion.
|
||||
actors.hero.herosubclass.berserker_desc=The _Berserker_ deals bonus damage scaling with damage taken. When at full rage, he can refuse to die for a short time, at the cost of exhaustion.
|
||||
actors.hero.herosubclass.warlock=warlock
|
||||
actors.hero.herosubclass.warlock_desc=When using wands on an enemy, the _Warlock_ has a chance to mark their soul. Marked enemies will heal him and restore his hunger whenever they take physical damage.
|
||||
actors.hero.herosubclass.battlemage=battlemage
|
||||
|
|
Loading…
Reference in New Issue
Block a user