v0.7.0: rebalanced scroll of mirror image

This commit is contained in:
Evan Debenham 2018-07-01 16:13:04 -04:00
parent ec6e88139c
commit e3833aadec
5 changed files with 125 additions and 32 deletions

View File

@ -22,79 +22,164 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.CorrosiveGas;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.MirrorSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.watabou.utils.Bundle;
import com.watabou.utils.Random;
public class MirrorImage extends NPC {
{
spriteClass = MirrorSprite.class;
HP = HT = 1;
defenseSkill = 0;
alignment = Alignment.ALLY;
state = HUNTING;
//before other mobs
actPriority = MOB_PRIO + 1;
}
public int tier;
private Hero hero;
private int heroID;
public int armTier;
private int attack;
private int damage;
@Override
protected boolean act() {
private static final String TIER = "tier";
private static final String ATTACK = "attack";
private static final String DAMAGE = "damage";
if ( hero == null ){
hero = (Hero)Actor.findById(heroID);
if ( hero == null ){
die(null);
sprite.killAndErase();
return true;
}
}
if (hero.tier() != armTier){
armTier = hero.tier();
((MirrorSprite)sprite).updateArmor( armTier );
}
return super.act();
}
private static final String HEROID = "hero_id";
@Override
public void storeInBundle( Bundle bundle ) {
super.storeInBundle( bundle );
bundle.put( TIER, tier );
bundle.put( ATTACK, attack );
bundle.put( DAMAGE, damage );
bundle.put( HEROID, heroID );
}
@Override
public void restoreFromBundle( Bundle bundle ) {
super.restoreFromBundle( bundle );
tier = bundle.getInt( TIER );
attack = bundle.getInt( ATTACK );
damage = bundle.getInt( DAMAGE );
heroID = bundle.getInt( HEROID );
}
public void duplicate( Hero hero ) {
tier = hero.tier();
attack = hero.attackSkill( hero );
damage = hero.damageRoll();
}
@Override
public int attackSkill( Char target ) {
return attack;
this.hero = hero;
Buff.affect(this, MirrorInvis.class, Short.MAX_VALUE);
}
@Override
public int damageRoll() {
return damage;
int damage;
if (hero.belongings.weapon != null){
damage = hero.belongings.weapon.damageRoll(this);
} else {
damage = hero.damageRoll(); //handles ring of force
}
return (damage+1)/2; //half hero damage, rounded up
}
@Override
public int attackSkill( Char target ) {
return hero.attackSkill(target);
}
@Override
public int defenseSkill(Char enemy) {
if (hero != null) {
int baseEvasion = 4 + hero.lvl;
int heroEvasion = hero.defenseSkill(enemy);
//if the hero has more/less evasion, 50% of it is applied
return (baseEvasion + heroEvasion) / 2;
} else {
return 0;
}
}
@Override
protected float attackDelay() {
return hero.attackDelay(); //handles ring of furor
}
@Override
protected boolean canAttack(Char enemy) {
if (hero.belongings.weapon != null){
return Dungeon.level.distance( pos, enemy.pos ) <= hero.belongings.weapon.reachFactor(this);
} else {
return super.canAttack(enemy);
}
}
@Override
public int drRoll() {
if (hero != null && hero.belongings.weapon != null){
return Random.NormalIntRange(0, hero.belongings.weapon.defenseFactor(this)/2);
} else {
return 0;
}
}
@Override
public int attackProc( Char enemy, int damage ) {
damage = super.attackProc( enemy, damage );
destroy();
sprite.die();
MirrorInvis buff = buff(MirrorInvis.class);
if (buff != null){
buff.detach();
}
return damage;
if (enemy instanceof Mob) {
((Mob)enemy).aggro( this );
}
if (hero.belongings.weapon != null){
return hero.belongings.weapon.proc( this, enemy, damage );
} else {
return damage;
}
}
@Override
public CharSprite sprite() {
CharSprite s = super.sprite();
((MirrorSprite)s).updateArmor( tier );
//pre-0.7.0 saves
if (heroID == 0){
heroID = Dungeon.hero.id();
}
hero = (Hero)Actor.findById(heroID);
if (hero != null) {
armTier = hero.tier();
}
((MirrorSprite)s).updateArmor( armTier );
return s;
}
@ -120,4 +205,12 @@ public class MirrorImage extends NPC {
immunities.add( CorrosiveGas.class );
immunities.add( Burning.class );
}
public static class MirrorInvis extends Invisibility {
@Override
public int icon() {
return BuffIndicator.NONE;
}
}
}

View File

@ -43,7 +43,7 @@ public class ScrollOfMirrorImage extends Scroll {
initials = 3;
}
private static final int NIMAGES = 3;
private static final int NIMAGES = 2;
@Override
public void doRead() {
@ -61,8 +61,8 @@ public class ScrollOfMirrorImage extends Scroll {
@Override
public void empoweredRead() {
//spawns 2 images right away, delays 4 of them, 6 total.
new DelayedImageSpawner(6 - spawnImages(curUser, 2), 2, 3).attachTo(curUser);
//spawns 2 images right away, delays 3 of them, 5 total.
new DelayedImageSpawner(5 - spawnImages(curUser, 2), 1, 2).attachTo(curUser);
setKnown();

View File

@ -42,7 +42,7 @@ public class MirrorSprite extends MobSprite {
@Override
public void link( Char ch ) {
super.link( ch );
updateArmor( ((MirrorImage)ch).tier );
updateArmor( ((MirrorImage)ch).armTier );
}
public void updateArmor( int tier ) {

View File

@ -341,7 +341,7 @@ actors.mobs.npcs.impshopkeeper.thief=I thought I could trust you!
actors.mobs.npcs.impshopkeeper.desc=Imps are lesser demons. They are notable for neither their strength nor their magic talent. But they are quite smart and sociable, and many of imps prefer to live and do business among non-demons.
actors.mobs.npcs.mirrorimage.name=mirror image
actors.mobs.npcs.mirrorimage.desc=This illusion bears a close resemblance to you, but it's paler and twitches a little.
actors.mobs.npcs.mirrorimage.desc=This illusion bears a close resemblance to you, even seeming to wield your current weapon and armor.\n\nMirror images will seek and attack enemies using their mimicked weapon, which behaves the same as yours, but deals less damage. They start out ethereal, but must take on a solid form in order to attack.\n\nWhile their offensive power can be potent, mirror images have no durability, and will fade the moment they take damage.
actors.mobs.npcs.ratking.name=rat king
actors.mobs.npcs.ratking.not_sleeping=I'm not sleeping!

View File

@ -632,7 +632,7 @@ items.scrolls.scrollofmagicmapping.layout=You are now aware of the level layout.
items.scrolls.scrollofmagicmapping.desc=When this scroll is read, an image of crystal clarity will be etched into your memory, alerting you to the precise layout of the level and revealing all hidden secrets. The locations of items and creatures will remain unknown.
items.scrolls.scrollofmirrorimage.name=scroll of mirror image
items.scrolls.scrollofmirrorimage.desc=The incantation on this scroll will create illusionary twins of the reader, which will chase their enemies.
items.scrolls.scrollofmirrorimage.desc=The incantation on this scroll will create two illusory twins of the reader. These mirror images act as weaker clones of the reader, and will chase down their enemies. They have no durability however, and will fade upon taking damage.
items.scrolls.scrollofpsionicblast.name=scroll of psionic blast
items.scrolls.scrollofpsionicblast.desc=This scroll contains destructive energy that can be channeled to assault the minds all visible creatures, blinding and damaging them. The power unleashed by the scroll is chaotic, so it will also blind and weaken the user.\n\nThe more injured the user is, the more powerful the scroll will be. At very low health psionic blast can kill most enemies instantly.