diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java
index 6b563ed66..b1f562ef9 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java
@@ -109,6 +109,12 @@ public class ShatteredPixelDungeon extends Game {
com.watabou.utils.Bundle.addAlias(
com.shatteredpixel.shatteredpixeldungeon.actors.mobs.OldTengu.class,
"com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Tengu" );
+
+ //v0.7.6
+ com.watabou.utils.Bundle.addAlias(
+ com.shatteredpixel.shatteredpixeldungeon.actors.mobs.ArmoredBrute.class,
+ "com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Shielded");
+
}
@Override
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/ArmoredBrute.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/ArmoredBrute.java
new file mode 100644
index 000000000..1fc70174f
--- /dev/null
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/ArmoredBrute.java
@@ -0,0 +1,91 @@
+/*
+ * Pixel Dungeon
+ * Copyright (C) 2012-2015 Oleg Dolya
+ *
+ * Shattered Pixel Dungeon
+ * Copyright (C) 2014-2019 Evan Debenham
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ */
+
+package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
+
+import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
+import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
+import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
+import com.shatteredpixel.shatteredpixeldungeon.items.Item;
+import com.shatteredpixel.shatteredpixeldungeon.items.armor.PlateArmor;
+import com.shatteredpixel.shatteredpixeldungeon.items.armor.ScaleArmor;
+import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
+import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
+import com.shatteredpixel.shatteredpixeldungeon.sprites.ShieldedSprite;
+import com.watabou.utils.Random;
+
+public class ArmoredBrute extends Brute {
+
+ {
+ spriteClass = ShieldedSprite.class;
+
+ //see rollToDropLoot
+ loot = Generator.Category.ARMOR;
+ lootChance = 1f;
+ }
+
+ @Override
+ public int drRoll() {
+ return Random.NormalIntRange(6, 10);
+ }
+
+ @Override
+ protected void triggerEnrage () {
+ Buff.affect(this, ArmoredRage.class).setShield(HT/2 + 1);
+ if (Dungeon.level.heroFOV[pos]) {
+ sprite.showStatus( CharSprite.NEGATIVE, Messages.get(this, "enraged") );
+ }
+ spend( TICK );
+ hasRaged = true;
+ }
+
+ @Override
+ protected Item createLoot () {
+ if (Random.Int( 4 ) == 0) {
+ return new PlateArmor().random();
+ }
+ return new ScaleArmor().random();
+ }
+
+ //similar to regular brute rate, but deteriorates much slower. 60 turns to death total.
+ public static class ArmoredRage extends Brute.BruteRage {
+
+ @Override
+ public boolean act() {
+
+ if (target.HP > 0){
+ detach();
+ return true;
+ }
+
+ absorbDamage( 1 );
+
+ if (shielding() <= 0){
+ target.die(null);
+ }
+
+ spend( 3*TICK );
+
+ return true;
+ }
+
+ }
+}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bat.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bat.java
index 7db143a58..1778f2f67 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bat.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bat.java
@@ -49,7 +49,7 @@ public class Bat extends Mob {
@Override
public int damageRoll() {
- return Random.NormalIntRange( 5, 18 );
+ return Random.NormalIntRange( 6, 16 );
}
@Override
@@ -65,7 +65,7 @@ public class Bat extends Mob {
@Override
public int attackProc( Char enemy, int damage ) {
damage = super.attackProc( enemy, damage );
- int reg = Math.min( damage, HT - HP );
+ int reg = Math.min( damage - 4, HT - HP );
if (reg > 0) {
HP += reg;
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java
index ef483e625..098828a71 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java
@@ -218,7 +218,7 @@ public class Bestiary {
} else if (cl == Thief.class) {
cl = Bandit.class;
} else if (cl == Brute.class) {
- cl = Shielded.class;
+ cl = ArmoredBrute.class;
} else if (cl == Monk.class) {
cl = Senior.class;
} else if (cl == Scorpio.class) {
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Brute.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Brute.java
index 1bfeb1a67..9bb3e651f 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Brute.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Brute.java
@@ -23,11 +23,14 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
+import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
+import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ShieldBuff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror;
import com.shatteredpixel.shatteredpixeldungeon.items.Gold;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.BruteSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
+import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.watabou.utils.Bundle;
import com.watabou.utils.Random;
@@ -46,17 +49,12 @@ public class Brute extends Mob {
lootChance = 0.5f;
}
- private boolean enraged = false;
-
- @Override
- public void restoreFromBundle( Bundle bundle ) {
- super.restoreFromBundle( bundle );
- enraged = HP < HT / 4;
- }
+ protected boolean hasRaged = false;
@Override
public int damageRoll() {
- return enraged ?
+ //TODO final balance decisions on these numbers
+ return buff(BruteRage.class) != null ?
Random.NormalIntRange( 15, 45 ) :
Random.NormalIntRange( 6, 26 );
}
@@ -72,19 +70,83 @@ public class Brute extends Mob {
}
@Override
- public void damage( int dmg, Object src ) {
- super.damage( dmg, src );
-
- if (isAlive() && !enraged && HP < HT / 4) {
- enraged = true;
- spend( TICK );
- if (Dungeon.level.heroFOV[pos]) {
- sprite.showStatus( CharSprite.NEGATIVE, Messages.get(this, "enraged") );
+ public boolean isAlive() {
+ if (HP > 0){
+ return true;
+ } else {
+ if (!hasRaged){
+ triggerEnrage();
}
+ return buff(BruteRage.class) != null;
}
}
+ protected void triggerEnrage(){
+ Buff.affect(this, BruteRage.class).setShield(HT/2 + 4);
+ if (Dungeon.level.heroFOV[pos]) {
+ sprite.showStatus( CharSprite.NEGATIVE, Messages.get(this, "enraged") );
+ }
+ spend( TICK );
+ hasRaged = true;
+ }
+
+ private static final String HAS_RAGED = "has_raged";
+
+ @Override
+ public void storeInBundle(Bundle bundle) {
+ super.storeInBundle(bundle);
+ bundle.put(HAS_RAGED, hasRaged);
+ }
+
+ @Override
+ public void restoreFromBundle(Bundle bundle) {
+ super.restoreFromBundle(bundle);
+ hasRaged = bundle.getBoolean(HAS_RAGED);
+ }
+
{
immunities.add( Terror.class );
}
+
+ public static class BruteRage extends ShieldBuff {
+
+ {
+ type = buffType.POSITIVE;
+ }
+
+ @Override
+ public boolean act() {
+
+ if (target.HP > 0){
+ detach();
+ return true;
+ }
+
+ absorbDamage( 4 );
+
+ if (shielding() <= 0){
+ target.die(null);
+ }
+
+ spend( TICK );
+
+ return true;
+ }
+
+ @Override
+ public int icon () {
+ return BuffIndicator.FURY;
+ }
+
+ @Override
+ public String toString () {
+ return Messages.get(this, "name");
+ }
+
+ @Override
+ public String desc () {
+ return Messages.get(this, "desc", shielding());
+ }
+
+ }
}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Shielded.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Shielded.java
deleted file mode 100644
index c28b67db9..000000000
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Shielded.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Pixel Dungeon
- * Copyright (C) 2012-2015 Oleg Dolya
- *
- * Shattered Pixel Dungeon
- * Copyright (C) 2014-2019 Evan Debenham
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see
- */
-
-package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
-
-import com.shatteredpixel.shatteredpixeldungeon.sprites.ShieldedSprite;
-import com.watabou.utils.Random;
-
-public class Shielded extends Brute {
-
- {
- spriteClass = ShieldedSprite.class;
-
- defenseSkill = 20;
- }
-
- @Override
- public int drRoll() {
- return Random.NormalIntRange(0, 10);
- }
-
-}
diff --git a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties
index b52dbf9d8..e6c9fa32c 100644
--- a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties
+++ b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties
@@ -437,7 +437,7 @@ actors.mobs.albino.desc=This is a rare breed of marsupial rat, with pure white f
actors.mobs.bandit.name=crazy bandit
actors.mobs.bat.name=vampire bat
-actors.mobs.bat.desc=These brisk and tenacious inhabitants of cave domes may defeat much larger opponents by replenishing their health with each successful attack.
+actors.mobs.bat.desc=These brisk and tenacious inhabitants of the caves are much more dangerous than they seem. They replenish their health with each successful attack, which allows them to defeat much larger opponents.
actors.mobs.bee.name=golden bee
actors.mobs.bee.desc_honey=Despite their small size, golden bees tend to protect their home fiercely. This one has been placated, and seems to want to follow you.
@@ -446,7 +446,9 @@ actors.mobs.bee.desc=Despite their small size, golden bees tend to protect their
actors.mobs.brute.name=gnoll brute
actors.mobs.brute.enraged=enraged
actors.mobs.brute.def_verb=blocked
-actors.mobs.brute.desc=Brutes are the largest, strongest and toughest of all gnolls. When severely wounded, they go berserk, inflicting even more damage to their enemies.
+actors.mobs.brute.desc=Brutes are the largest, strongest, and toughest of all gnolls. When mortally wounded, they go berserk, gaining temporary shielding and a large boost to damage.
+actors.mobs.brute$bruterage.name=Brute Rage
+actors.mobs.brute$bruterage.desc=This gnoll brute is dieing, but wants to take you with it!\n\nThe brute will die when its shielding wears off, either due to time or if it is damaged. In the meantime, it will deal hugely increased damage, so watch out!\n\nShield remaining: %d.
actors.mobs.causticslime.name=caustic slime
actors.mobs.causticslime.desc=This slime seems to have been tainted by the dark magic emanating from below. It has lost its usual green color, and drips with caustic ooze.
@@ -558,7 +560,8 @@ actors.mobs.shaman.name=gnoll shaman
actors.mobs.shaman.zap_kill=The lightning bolt killed you...
actors.mobs.shaman.desc=The most intelligent gnolls can master shamanistic magic. Gnoll shamans prefer battle spells to compensate for lack of might, not hesitating to use them on those who question their status in a tribe.
-actors.mobs.shielded.name=shielded brute
+actors.mobs.armoredbrute.name=armored brute
+actors.mobs.armoredbrute.desc=The most senior gnoll brutes often wear powerful armor to show their status. The armor makes these brutes much more resilient to physical damage, and their greater discipline means they can rage for much longer before succumbing to their wounds.
actors.mobs.skeleton.name=skeleton
actors.mobs.skeleton.explo_kill=You were killed by the explosion of bones...