v0.3.5: rough berserker implementation
This commit is contained in:
parent
c3910a1277
commit
97365b1ecf
|
@ -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.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barkskin;
|
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.Bless;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Combo;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Combo;
|
||||||
|
@ -321,6 +322,9 @@ public class Hero extends Char {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dmg < 0) dmg = 0;
|
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;
|
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)));
|
dmg = (int)Math.ceil((float)dmg * Math.pow(0.9, tenacity*((float)(HT - HP)/HT)));
|
||||||
|
|
||||||
super.damage( dmg, src );
|
super.damage( dmg, src );
|
||||||
|
|
||||||
if (subClass == HeroSubClass.BERSERKER && 0 < HP && HP <= HT * Fury.LEVEL) {
|
|
||||||
Buff.affect( this, Fury.class );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkVisibleMobs() {
|
private void checkVisibleMobs() {
|
||||||
|
@ -1081,6 +1081,7 @@ public class Hero extends Char {
|
||||||
|
|
||||||
EtherealChains.chainsRecharge chains = buff(EtherealChains.chainsRecharge.class);
|
EtherealChains.chainsRecharge chains = buff(EtherealChains.chainsRecharge.class);
|
||||||
if (chains != null) chains.gainExp(percent);
|
if (chains != null) chains.gainExp(percent);
|
||||||
|
if (subClass == HeroSubClass.BERSERKER) Buff.affect(this, Berserk.class).recover(percent);
|
||||||
|
|
||||||
boolean levelUp = false;
|
boolean levelUp = false;
|
||||||
while (this.exp >= maxExp()) {
|
while (this.exp >= maxExp()) {
|
||||||
|
@ -1289,6 +1290,11 @@ public class Hero extends Char {
|
||||||
Dungeon.deleteGame( Dungeon.hero.heroClass, true );
|
Dungeon.deleteGame( Dungeon.hero.heroClass, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAlive() {
|
||||||
|
return super.isAlive() || (subClass == HeroSubClass.BERSERKER && Buff.affect(this, Berserk.class).berserking());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void move( int step ) {
|
public void move( int step ) {
|
||||||
super.move( step );
|
super.move( step );
|
||||||
|
|
|
@ -77,9 +77,8 @@ public class BrokenSigil extends Item {
|
||||||
public boolean act() {
|
public boolean act() {
|
||||||
if (armor == null) detach();
|
if (armor == null) detach();
|
||||||
else if (armor.isEquipped((Hero)target)) {
|
else if (armor.isEquipped((Hero)target)) {
|
||||||
int maxShield = 1 + armor.tier + armor.level();
|
if (target.SHLD < maxShield()){
|
||||||
if (target.SHLD < maxShield){
|
partialShield += 1/(30*Math.pow(0.9f, (maxShield() - target.SHLD)));
|
||||||
partialShield += 1/(30*Math.pow(0.9f, (maxShield - target.SHLD)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (partialShield >= 1){
|
while (partialShield >= 1){
|
||||||
|
@ -93,5 +92,9 @@ public class BrokenSigil extends Item {
|
||||||
public void setArmor(Armor arm){
|
public void setArmor(Armor arm){
|
||||||
armor = arm;
|
armor = arm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int maxShield() {
|
||||||
|
return 1 + armor.tier + armor.level();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user