From ca077cefaed960b8dafc46076909db2ace914a38 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Fri, 1 Sep 2017 20:39:48 -0400 Subject: [PATCH] v0.6.2: reworked wand of corruption --- .../shatteredpixeldungeon/actors/Char.java | 4 + .../actors/buffs/Doom.java | 54 +++++ .../actors/buffs/Weakness.java | 19 -- .../actors/hero/Hero.java | 4 +- .../actors/mobs/Albino.java | 1 + .../actors/mobs/Bat.java | 2 +- .../actors/mobs/Bee.java | 1 + .../actors/mobs/Elemental.java | 1 + .../actors/mobs/FetidRat.java | 1 + .../actors/mobs/GnollTrickster.java | 1 + .../actors/mobs/Goo.java | 1 + .../actors/mobs/King.java | 1 + .../actors/mobs/Mob.java | 23 +- .../actors/mobs/Monk.java | 1 + .../actors/mobs/RotLasher.java | 1 + .../actors/mobs/Scorpio.java | 1 + .../actors/mobs/Senior.java | 1 + .../actors/mobs/Spinner.java | 1 + .../actors/mobs/Statue.java | 1 + .../actors/mobs/Succubus.java | 1 + .../actors/mobs/Thief.java | 2 + .../actors/mobs/Yog.java | 6 +- .../actors/mobs/npcs/MirrorImage.java | 4 +- .../items/artifacts/DriedRose.java | 6 +- .../items/wands/WandOfCorruption.java | 197 ++++++++++++++---- .../messages/actors/actors.properties | 9 +- .../messages/items/items.properties | 8 +- 27 files changed, 269 insertions(+), 83 deletions(-) create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Doom.java diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java index 8094c80bf..04c8ea02d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java @@ -28,6 +28,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Chill; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Doom; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.EarthImbue; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FireImbue; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost; @@ -244,6 +245,9 @@ public abstract class Char extends Actor { if (this.buff(MagicalSleep.class) != null){ Buff.detach(this, MagicalSleep.class); } + if (this.buff(Doom.class) != null){ + dmg *= 2; + } Class srcClass = src.getClass(); if (immunities().contains( srcClass )) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Doom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Doom.java new file mode 100644 index 000000000..1e742b92f --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Doom.java @@ -0,0 +1,54 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2017 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.buffs; + +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; +import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; + +public class Doom extends Buff { + + { + type = buffType.NEGATIVE; + } + + @Override + public void fx(boolean on) { + if (on) target.sprite.add( CharSprite.State.DARKENED ); + else if (target.invisible == 0) target.sprite.remove( CharSprite.State.DARKENED ); + } + + @Override + public int icon() { + return BuffIndicator.CORRUPT; + } + + @Override + public String toString() { + return Messages.get(this, "name"); + } + + @Override + public String desc() { + return Messages.get(this, "desc"); + } +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Weakness.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Weakness.java index 3981dac4b..e090fb2d6 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Weakness.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Weakness.java @@ -22,7 +22,6 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.buffs; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; -import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfElements; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; @@ -45,24 +44,6 @@ public class Weakness extends FlavourBuff { return Messages.get(this, "name"); } - @Override - public boolean attachTo( Char target ) { - if (super.attachTo( target )) { - Hero hero = (Hero)target; - hero.weakened = true; - - return true; - } else { - return false; - } - } - - @Override - public void detach() { - super.detach(); - ((Hero)target).weakened = false; - } - public static float duration( Char ch ) { return DURATION * RingOfElements.durationFactor( ch ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java index 5106ff5ff..7275b16d4 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java @@ -44,6 +44,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Regeneration; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SnipersMark; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Weakness; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.NPC; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; @@ -159,7 +160,6 @@ public class Hero extends Char { public Belongings belongings; public int STR; - public boolean weakened = false; public float awareness; @@ -205,7 +205,7 @@ public class Hero extends Char { STR += RingOfMight.strengthBonus( this ); - return weakened ? STR - 2 : STR; + return (buff(Weakness.class) != null) ? STR - 2 : STR; } private static final String ATTACK = "attackSkill"; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Albino.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Albino.java index d43f27d0d..3eeafd649 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Albino.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Albino.java @@ -44,6 +44,7 @@ public class Albino extends Rat { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); if (Random.Int( 2 ) == 0) { Buff.affect( enemy, Bleeding.class ).set( damage ); } 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 d3ba33153..d519a4fdd 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 @@ -67,7 +67,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 ); if (reg > 0) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bee.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bee.java index 07084b917..6c755861a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bee.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bee.java @@ -100,6 +100,7 @@ public class Bee extends Mob { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); if (enemy instanceof Mob) { ((Mob)enemy).aggro( this ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Elemental.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Elemental.java index 4241f99bd..9b6272f83 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Elemental.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Elemental.java @@ -72,6 +72,7 @@ public class Elemental extends Mob { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); if (Random.Int( 2 ) == 0) { Buff.affect( enemy, Burning.class ).reignite( enemy ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/FetidRat.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/FetidRat.java index a64dad202..c50d62e60 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/FetidRat.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/FetidRat.java @@ -61,6 +61,7 @@ public class FetidRat extends Rat { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); if (Random.Int(3) == 0) { Buff.affect(enemy, Ooze.class); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/GnollTrickster.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/GnollTrickster.java index f30446d7b..334e37a3c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/GnollTrickster.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/GnollTrickster.java @@ -71,6 +71,7 @@ public class GnollTrickster extends Gnoll { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); //The gnoll's attacks get more severe the more the player lets it hit them combo++; int effect = Random.Int(4)+combo; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Goo.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Goo.java index 7a34b81f4..c1281c204 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Goo.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Goo.java @@ -129,6 +129,7 @@ public class Goo extends Mob { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); if (Random.Int( 3 ) == 0) { Buff.affect( enemy, Ooze.class ); enemy.sprite.burst( 0x000000, 5 ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/King.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/King.java index 11c7ff67e..972117d15 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/King.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/King.java @@ -296,6 +296,7 @@ public class King extends Mob { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); if (Random.Int( MAX_ARMY_SIZE ) == 0) { Buff.prolong( enemy, Paralysis.class, 1 ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java index f94a6cddd..1b02ddae8 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java @@ -35,6 +35,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hunger; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Sleep; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SoulMark; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Weakness; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass; import com.shatteredpixel.shatteredpixeldungeon.effects.Flare; @@ -83,7 +84,7 @@ public abstract class Mob extends Char { protected int defenseSkill = 0; - protected int EXP = 1; + public int EXP = 1; protected int maxLvl = Hero.MAX_LEVEL; protected Char enemy; @@ -272,10 +273,7 @@ public abstract class Mob extends Char { @Override public void add( Buff buff ) { super.add( buff ); - if (buff instanceof Amok) { - if (sprite != null) { - sprite.showStatus( CharSprite.NEGATIVE, Messages.get(this, "rage") ); - } + if (buff instanceof Amok || buff instanceof Corruption) { state = HUNTING; } else if (buff instanceof Terror) { state = FLEEING; @@ -453,6 +451,15 @@ public abstract class Mob extends Char { super.onAttackComplete(); } + @Override + public int attackProc(Char enemy, int damage) { + damage = super.attackProc(enemy, damage); + if (buff(Weakness.class) != null){ + damage *= 0.67f; + } + return damage; + } + @Override public int defenseSkill( Char enemy ) { boolean seen = enemySeen || (enemy == Dungeon.hero && !Dungeon.hero.canSurpriseAttack()); @@ -533,17 +540,13 @@ public abstract class Mob extends Char { Statistics.qualifiedForNoKilling = false; } - int exp = exp(); + int exp = Dungeon.hero.lvl <= maxLvl ? EXP : 0; if (exp > 0) { Dungeon.hero.sprite.showStatus( CharSprite.POSITIVE, Messages.get(this, "exp", exp) ); Dungeon.hero.earnExp( exp ); } } } - - public int exp() { - return Dungeon.hero.lvl <= maxLvl ? EXP : 0; - } @Override public void die( Object cause ) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Monk.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Monk.java index 2a64708f8..5fb9ef66a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Monk.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Monk.java @@ -86,6 +86,7 @@ public class Monk extends Mob { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); if (enemy == Dungeon.hero) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/RotLasher.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/RotLasher.java index 5567e6e08..9cd09834e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/RotLasher.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/RotLasher.java @@ -71,6 +71,7 @@ public class RotLasher extends Mob { @Override public int attackProc(Char enemy, int damage) { + damage = super.attackProc( enemy, damage ); Buff.affect( enemy, Cripple.class, 2f ); return super.attackProc(enemy, damage); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Scorpio.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Scorpio.java index d37a01cf3..3af69dc5b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Scorpio.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Scorpio.java @@ -78,6 +78,7 @@ public class Scorpio extends Mob { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); if (Random.Int( 2 ) == 0) { Buff.prolong( enemy, Cripple.class, Cripple.DURATION ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Senior.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Senior.java index 71a5c8827..67d7994c0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Senior.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Senior.java @@ -41,6 +41,7 @@ public class Senior extends Monk { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); if (Random.Int( 10 ) == 0) { Buff.prolong( enemy, Paralysis.class, 1.1f ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Spinner.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Spinner.java index 0c6353f83..fffe8888a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Spinner.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Spinner.java @@ -80,6 +80,7 @@ public class Spinner extends Mob { @Override public int attackProc(Char enemy, int damage) { + damage = super.attackProc( enemy, damage ); if (Random.Int(2) == 0) { Buff.affect(enemy, Poison.class).set(Random.Int(7, 9) * Poison.durationFactor(enemy)); state = FLEEING; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Statue.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Statue.java index 775bbeabf..9477b3760 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Statue.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Statue.java @@ -122,6 +122,7 @@ public class Statue extends Mob { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); return weapon.proc( this, enemy, damage ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Succubus.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Succubus.java index db481fa63..c62a3dfec 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Succubus.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Succubus.java @@ -72,6 +72,7 @@ public class Succubus extends Mob { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); if (Random.Int( 3 ) == 0) { Buff.affect( enemy, Charm.class, Charm.durationFactor( enemy ) * Random.IntRange( 3, 7 ) ).object = id(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Thief.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Thief.java index 234645749..90aae79af 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Thief.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Thief.java @@ -125,6 +125,8 @@ public class Thief extends Mob { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); + if (item == null && enemy instanceof Hero && steal( (Hero)enemy )) { state = FLEEING; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Yog.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Yog.java index 6200de0ba..adf161af7 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Yog.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Yog.java @@ -242,6 +242,8 @@ public class Yog extends Mob { @Override public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); + if (Random.Int( 3 ) == 0) { Buff.affect( enemy, Ooze.class ); enemy.sprite.burst( 0xFF000000, 5 ); @@ -332,7 +334,7 @@ public class Yog extends Mob { } @Override - public boolean attack( Char enemy ) { + public boolean doAttack( Char enemy ) { if (!Dungeon.level.adjacent( pos, enemy.pos )) { spend( attackDelay() ); @@ -357,7 +359,7 @@ public class Yog extends Mob { return false; } } else { - return super.attack( enemy ); + return super.doAttack( enemy ); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/MirrorImage.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/MirrorImage.java index a067d85fd..576e0abd4 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/MirrorImage.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/MirrorImage.java @@ -86,12 +86,12 @@ public class MirrorImage extends NPC { @Override public int attackProc( Char enemy, int damage ) { - int dmg = super.attackProc( enemy, damage ); + damage = super.attackProc( enemy, damage ); destroy(); sprite.die(); - return dmg; + return damage; } protected Char chooseEnemy() { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java index 927b630a3..98223e592 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java @@ -539,11 +539,11 @@ public class DriedRose extends Artifact { @Override public int attackProc(Char enemy, int damage) { + damage = super.attackProc(enemy, damage); if (rose != null && rose.weapon != null) { - return rose.weapon.proc( this, enemy, damage ); - } else { - return super.attackProc(enemy, damage); + damage = rose.weapon.proc( this, enemy, damage ); } + return damage; } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfCorruption.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfCorruption.java index efd0ae45c..0d8a07fb2 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfCorruption.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfCorruption.java @@ -22,74 +22,199 @@ package com.shatteredpixel.shatteredpixeldungeon.items.wands; import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Bleeding; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Blindness; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Chill; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Corruption; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Doom; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Drowsy; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FlavourBuff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicalSleep; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Ooze; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Poison; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Roots; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Slow; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SoulMark; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Venom; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Weakness; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.King; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Piranha; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Statue; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Swarm; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Wraith; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Yog; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.NPC; import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff; import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.noosa.audio.Sample; import com.watabou.utils.Callback; import com.watabou.utils.Random; +import java.util.HashMap; + +//TODO final balancing decisions here public class WandOfCorruption extends Wand { { image = ItemSpriteSheet.WAND_CORRUPTION; } - + + //Note that some debuffs here have a 0% chance to be applied. + // This is because the wand of corruption considers them to be a certain level of harmful + // for the purposes of reducing resistance, but does not actually apply them itself + + private static final float MINOR_DEBUFF_WEAKEN = 4/5f; + private static final HashMap, Float> MINOR_DEBUFFS = new HashMap<>(); + static{ + MINOR_DEBUFFS.put(Weakness.class, 2f); + MINOR_DEBUFFS.put(Cripple.class, 1f); + MINOR_DEBUFFS.put(Blindness.class, 1f); + MINOR_DEBUFFS.put(Terror.class, 1f); + + MINOR_DEBUFFS.put(Chill.class, 0f); + MINOR_DEBUFFS.put(Ooze.class, 0f); + MINOR_DEBUFFS.put(Roots.class, 0f); + MINOR_DEBUFFS.put(Vertigo.class, 0f); + MINOR_DEBUFFS.put(Drowsy.class, 0f); + MINOR_DEBUFFS.put(Bleeding.class, 0f); + MINOR_DEBUFFS.put(Burning.class, 0f); + MINOR_DEBUFFS.put(Poison.class, 0f); + } + + private static final float MAJOR_DEBUFF_WEAKEN = 2/3f; + private static final HashMap, Float> MAJOR_DEBUFFS = new HashMap<>(); + static{ + MAJOR_DEBUFFS.put(Amok.class, 3f); + MAJOR_DEBUFFS.put(Slow.class, 2f); + MAJOR_DEBUFFS.put(Paralysis.class, 1f); + + MAJOR_DEBUFFS.put(Charm.class, 0f); + MAJOR_DEBUFFS.put(MagicalSleep.class, 0f); + MAJOR_DEBUFFS.put(SoulMark.class, 0f); + MAJOR_DEBUFFS.put(Venom.class, 0f); + MAJOR_DEBUFFS.put(Frost.class, 0f); + MAJOR_DEBUFFS.put(Doom.class, 0f); + } + @Override protected void onZap(Ballistica bolt) { Char ch = Actor.findChar(bolt.collisionPos); - if (ch != null && !(ch instanceof NPC)){ + if (ch != null && ch instanceof Mob && !(ch instanceof NPC)){ - if(ch.buff(Corruption.class) != null){ - GLog.w( Messages.get(this, "already_corrupted") ); - return; + Mob enemy = (Mob) ch; + + float corruptingPower = 2 + level(); + + //base enemy resistance is usually based on their exp, but in special cases it is based on other criteria + float enemyResist = 1 + enemy.EXP; + if (ch instanceof Mimic || ch instanceof Statue){ + enemyResist = 1 + Dungeon.depth; + } else if (ch instanceof Piranha) { + enemyResist = 1 + Dungeon.depth/2f; + } else if (ch instanceof Wraith) { + enemyResist = 1 + Dungeon.depth/4f; + } else if (ch instanceof Yog.BurningFist || ch instanceof Yog.RottingFist) { + enemyResist = 1 + 30; + } else if (ch instanceof Yog.Larva || ch instanceof King.Undead){ + enemyResist = 1 + 5; + } else if (ch instanceof Swarm){ + //child swarms don't give exp, so we force this here. + enemyResist = 1 + 3; } - - if (ch.properties().contains(Char.Property.BOSS) || ch.properties().contains(Char.Property.MINIBOSS)){ - GLog.w( Messages.get(this, "boss") ); - return; + + //100% health: 3x resist 75%: 2.1x resist 50%: 1.5x resist 25%: 1.1x resist + enemyResist *= 1 + 2*Math.pow(enemy.HP/(float)enemy.HT, 2); + + //debuffs placed on the enemy reduce their resistance + for (Buff buff : enemy.buffs()){ + if (MAJOR_DEBUFFS.containsKey(buff.getClass())) enemyResist *= MAJOR_DEBUFF_WEAKEN; + else if (MINOR_DEBUFFS.containsKey(buff.getClass())) enemyResist *= MINOR_DEBUFF_WEAKEN; + else if (buff.type == Buff.buffType.NEGATIVE) enemyResist *= MINOR_DEBUFF_WEAKEN; } - - int basePower = 10 + 2*level(); - int mobPower = Random.IntRange(0, ch.HT) + ch.HP*2; - for ( Buff buff : ch.buffs()){ - if (buff.type == Buff.buffType.NEGATIVE){ - mobPower *= 0.67; - break; + + //cannot re-corrupt or doom an enemy, so give them a major debuff instead + if(enemy.buff(Corruption.class) != null || enemy.buff(Doom.class) != null){ + enemyResist = corruptingPower*.99f; + } + + if (corruptingPower > enemyResist){ + corruptEnemy( enemy ); + } else { + float debuffChance = corruptingPower / enemyResist; + if (Random.Float() < debuffChance){ + debuffEnemy( enemy, MAJOR_DEBUFFS); + } else { + debuffEnemy( enemy, MINOR_DEBUFFS); } } - int extraCharges = 0; - //try to use extra charges to overpower the mob - while (basePower <= mobPower){ - extraCharges++; - basePower += 5 + level(); + processSoulMark(ch, chargesPerCast()); + } + } + + private void debuffEnemy( Mob enemy, HashMap, Float> category ){ + HashMap, Float> debuffs = new HashMap<>(category); + for (Buff existing : enemy.buffs()){ + if (debuffs.containsKey(existing.getClass())) { + debuffs.put(existing.getClass(), 0f); } - - //if we fail, lose all charges, remember we have 1 left to lose from using the wand. - if (extraCharges >= curCharges){ - curCharges = 1; - GLog.w( Messages.get(this, "fail") ); - return; + } + + //all buffs with a > 0 chance are flavor buffs + Class debuffCls = (Class) Random.chances(debuffs); + + if (debuffCls != null){ + Buff.append(enemy, debuffCls, 6 + level()*3); + } else { + //if no debuff can be applied (all are present), then go up one tier + if (category == MINOR_DEBUFFS) debuffEnemy( enemy, MAJOR_DEBUFFS); + else if (category == MAJOR_DEBUFFS) corruptEnemy( enemy ); + } + } + + private void corruptEnemy( Mob enemy ){ + //cannot re-corrupt or doom an enemy, so give them a major debuff instead + if(enemy.buff(Corruption.class) != null || enemy.buff(Doom.class) != null){ + GLog.w( Messages.get(this, "already_corrupted") ); + return; + } + + if (!enemy.properties().contains(Char.Property.BOSS) && + !enemy.properties().contains(Char.Property.MINIBOSS) && + !enemy.immunities().contains(Corruption.class)){ + enemy.HP = enemy.HT; + for (Buff buff : enemy.buffs()) { + buff.detach(); } - - //otherwise corrupt the mob & spend charges - Buff.append(ch, Corruption.class); - ch.HP = ch.HT; - curCharges -= extraCharges; - usagesToKnow -= extraCharges; - - processSoulMark(ch, extraCharges+chargesPerCast()); + Buff.affect(enemy, Corruption.class); + if (enemy.EXP > 0) { + curUser.sprite.showStatus(CharSprite.POSITIVE, Messages.get(enemy, "exp", enemy.EXP)); + curUser.earnExp(enemy.EXP); + enemy.EXP = 0; + } + //TODO perhaps enemies should also drop loot here + } else { + Buff.affect(enemy, Doom.class); } } @@ -99,7 +224,7 @@ public class WandOfCorruption extends Wand { // lvl 1 - 40% // lvl 2 - 50% if (Random.Int( level() + 4 ) >= 3){ - Buff.prolong( defender, Amok.class, 3+level()); + Buff.prolong( defender, Amok.class, 4+level()*2); } } 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 0401f061a..fb2da694e 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 @@ -90,12 +90,15 @@ actors.buffs.combo.fury_desc=_Fury_ is currently available. This devastating att actors.buffs.combo.desc=The gladiator builds momentum as they land successful blows. Each blow increases the combo counter by one, but taking too long to attack, missing more than once, or using items will reset the combo counter to 0.\n\nBuilding combo unlocks special finisher abilities: powerful attacks that cannot miss! A different finisher is available at 2, 4, 6, 8, and 10 combo count, and using a finisher will reset your combo. actors.buffs.corruption.name=Corrupted -actors.buffs.corruption.desc=Corruption seeps into the essence of a being, twisting them against their former nature.\n\nCorrupted creatures will attack and aggravate their allies, and ignore their former enemies. Corruption is damaging as well, and will slowly cause its target to succumb.\n\nCorruption is permanent, its effects only end in death. +actors.buffs.corruption.desc=Corruption seeps into the essence of a being, twisting them against their former nature.\n\nCorrupted creatures will attack their allies, and ignore their former enemies. Corruption is damaging as well, and will slowly cause its target to succumb.\n\nCorruption is permanent, its effects only end in death. actors.buffs.cripple.name=Crippled actors.buffs.cripple.heromsg=You are crippled! actors.buffs.cripple.desc=You're pretty sure legs aren't meant to bend that way.\n\nCrippled halves movement speed, making moving a tile usually take two turns instead of one.\n\nTurns of cripple remaining: %s. +actors.buffs.doom.name=Doomed +actors.buffs.doom.desc=It's hard to keep going when it seems like the universe wants you dead.\n\nDoomed characters will receive double damage from all sources.\n\nDoom is permanent, its effects only end in death. + actors.buffs.drowsy.name=Drowsy actors.buffs.drowsy.desc=A magical force is making it difficult to stay awake.\n\nThe hero can resist drowsiness by taking damage or by being at full health.\n\nAfter a few turns, the target will fall into a deep magical sleep. @@ -199,7 +202,7 @@ actors.buffs.vertigo.desc=Walking in a straight line can be difficult when the w actors.buffs.weakness.name=Weakened actors.buffs.weakness.heromsg=You feel weakened! -actors.buffs.weakness.desc=Your gear suddenly feels a lot heavier.\n\nWeakening magic is affecting you, reducing your effective strength by 2 points.\n\nTurns of weakness remaining: %s. +actors.buffs.weakness.desc=Everything suddenly seems much heavier.\n\nWeakening magic reduces a character's physical strength. The hero will lose 2 points of effective strength, while enemies will deal reduced damage.\n\nTurns of weakness remaining: %s. @@ -434,7 +437,7 @@ actors.mobs.king$undead.desc=These undead dwarves, risen by the will of the King actors.mobs.mimic.name=mimic actors.mobs.mimic.desc=Mimics are magical creatures which can take any shape they wish. In dungeons they almost always choose a shape of a treasure chest, because they know how to beckon an adventurer. -actors.mobs.mob.died=You hear something died in the distance. +actors.mobs.mob.died=You hear something die the distance. actors.mobs.mob.rage=#$%^ actors.mobs.mob.exp=%+dEXP actors.mobs.mob.rankings_desc=Slain by: %s diff --git a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/items/items.properties b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/items/items.properties index 685f50b0a..4ac7d0b28 100644 --- a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/items/items.properties +++ b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/items/items.properties @@ -672,11 +672,9 @@ items.wands.wandofblastwave.stats_desc=This wand shoots a bolt which violently d items.wands.wandofcorruption.name=wand of corruption items.wands.wandofcorruption.staff_name=staff of corruption -items.wands.wandofcorruption.already_corrupted=That character is already corrupted. -items.wands.wandofcorruption.boss=Bosses are immune to corruption. -items.wands.wandofcorruption.fail=The corrupting power was not strong enough, nothing happens. -items.wands.wandofcorruption.desc=This wand radiates dark energy, if that weren't already obvious from the small decorative skull shaped onto its tip. -items.wands.wandofcorruption.stats_desc=This wand will release a blast of corrupting energy, attempting to bend enemies to your will. Full health enemies are much harder to corrupt than weakened ones. This wand uses at least one charge per cast, but will often use more in an attempt to overpower more healthy enemies. +items.wands.wandofcorruption.already_corrupted=That character cannot be influenced further. +items.wands.wandofcorruption.desc=This wand radiates chaotic dark energy, if that weren't already obvious from the small decorative skull shaped onto its tip. +items.wands.wandofcorruption.stats_desc=This wand will release a blast of corrupting energy which will debuff enemies and eventually bend them to your will. Enemies are able to resist the corruption, but weakened enemies are much easier to corrupt than healthy ones. items.wands.wandofdisintegration.name=wand of disintegration items.wands.wandofdisintegration.staff_name=staff of disintegration