v0.3.5: rough berserker implementation

This commit is contained in:
Evan Debenham 2016-03-26 06:13:12 -04:00
parent c3910a1277
commit 97365b1ecf
3 changed files with 162 additions and 8 deletions

View File

@ -0,0 +1,145 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
import com.shatteredpixel.shatteredpixeldungeon.items.BrokenSigil.SigilShield;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.watabou.utils.Bundle;
/**
* Created by Evan on 20/03/2016.
*/
public class Berserk extends Buff {
private enum State{
NORMAL, BERSERK, EXHAUSTED, RECOVERING;
}
private State state = State.NORMAL;
private static final int EXHAUSTION_START = 40;
private int exhaustion;
private static final float LEVEL_RECOVER_START = 2f;
private float levelRecovery;
private static final String STATE = "state";
private static final String EXHAUSTION = "exhaustion";
private static final String LEVEL_RECOVERY = "levelrecovery";
@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);
}
@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);
}
@Override
public boolean act() {
if (berserking()){
if (target.HP <= 0) {
target.SHLD -= Math.min(target.SHLD, 2);
if (target.SHLD == 0) {
target.die(this);
}
} else {
state = State.EXHAUSTED;
exhaustion = EXHAUSTION_START;
levelRecovery = LEVEL_RECOVER_START;
BuffIndicator.refreshHero();
target.SHLD = 0;
}
} else if (state == State.EXHAUSTED){
exhaustion--;
if (exhaustion == 0){
state = State.RECOVERING;
BuffIndicator.refreshHero();
}
}
spend(TICK);
return true;
}
public int damageFactor(int dmg){
float percentMissing = 1f - target.HP/(float)target.HT;
float bonus = 1f + (percentMissing * percentMissing);
if (state == State.EXHAUSTED) bonus *= (50 - exhaustion) / 50f;
return Math.round(dmg * bonus);
}
public boolean berserking(){
if (target.HP == 0 && state == State.NORMAL){
SigilShield sigil = target.buff(SigilShield.class);
if (sigil != null){
state = State.BERSERK;
BuffIndicator.refreshHero();
target.SHLD = sigil.maxShield() * 5;
}
}
return state == State.BERSERK;
}
public void recover(float percent){
if (levelRecovery > 0){
levelRecovery -= percent;
if (levelRecovery <= 0) {
state = State.NORMAL;
BuffIndicator.refreshHero();
levelRecovery = 0;
}
}
}
@Override
public int icon() {
switch (state){
case NORMAL: default:
return BuffIndicator.NONE;
case BERSERK:
return BuffIndicator.FURY;
case EXHAUSTED:
return BuffIndicator.FURY;
case RECOVERING:
return BuffIndicator.FURY;
}
}
@Override
public String toString() {
switch (state){
case NORMAL: default:
return "";
case BERSERK:
return "BERSERK!";
case EXHAUSTED:
return "Exhausted";
case RECOVERING:
return "Recovering";
}
}
@Override
public String desc() {
switch (state){
case NORMAL: default:
return "";
case BERSERK:
return "Berserking, you're invincible!";
case EXHAUSTED:
return "Exhausted! Damage down!";
case RECOVERING:
return "Recovering from rage, can't do it again.";
}
}
}

View File

@ -29,6 +29,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barkskin;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Berserk;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Bless;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Combo;
@ -321,6 +322,9 @@ public class Hero extends Char {
}
}
if (dmg < 0) dmg = 0;
if (subClass == HeroSubClass.BERSERKER){
dmg = Buff.affect(this, Berserk.class).damageFactor(dmg);
}
return buff( Fury.class ) != null ? (int)(dmg * 1.5f) : dmg;
}
@ -905,10 +909,6 @@ public class Hero extends Char {
dmg = (int)Math.ceil((float)dmg * Math.pow(0.9, tenacity*((float)(HT - HP)/HT)));
super.damage( dmg, src );
if (subClass == HeroSubClass.BERSERKER && 0 < HP && HP <= HT * Fury.LEVEL) {
Buff.affect( this, Fury.class );
}
}
private void checkVisibleMobs() {
@ -1081,6 +1081,7 @@ public class Hero extends Char {
EtherealChains.chainsRecharge chains = buff(EtherealChains.chainsRecharge.class);
if (chains != null) chains.gainExp(percent);
if (subClass == HeroSubClass.BERSERKER) Buff.affect(this, Berserk.class).recover(percent);
boolean levelUp = false;
while (this.exp >= maxExp()) {
@ -1289,6 +1290,11 @@ public class Hero extends Char {
Dungeon.deleteGame( Dungeon.hero.heroClass, true );
}
@Override
public boolean isAlive() {
return super.isAlive() || (subClass == HeroSubClass.BERSERKER && Buff.affect(this, Berserk.class).berserking());
}
@Override
public void move( int step ) {
super.move( step );

View File

@ -77,9 +77,8 @@ public class BrokenSigil extends Item {
public boolean act() {
if (armor == null) detach();
else if (armor.isEquipped((Hero)target)) {
int maxShield = 1 + armor.tier + armor.level();
if (target.SHLD < maxShield){
partialShield += 1/(30*Math.pow(0.9f, (maxShield - target.SHLD)));
if (target.SHLD < maxShield()){
partialShield += 1/(30*Math.pow(0.9f, (maxShield() - target.SHLD)));
}
}
while (partialShield >= 1){
@ -93,5 +92,9 @@ public class BrokenSigil extends Item {
public void setArmor(Armor arm){
armor = arm;
}
public int maxShield() {
return 1 + armor.tier + armor.level();
}
}
}