Merging Source v1.7.2: actor changes
This commit is contained in:
parent
724338b57f
commit
4a49763309
|
@ -131,9 +131,11 @@ public abstract class Actor implements Bundlable {
|
||||||
chars[pos] = null;
|
chars[pos] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void next() {
|
/*protected*/public void next() {
|
||||||
|
if (current == this) {
|
||||||
current = null;
|
current = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void process() {
|
public static void process() {
|
||||||
|
|
||||||
|
@ -167,6 +169,14 @@ public abstract class Actor implements Bundlable {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current != null) {
|
if (current != null) {
|
||||||
|
|
||||||
|
if (current instanceof Char && ((Char)current).sprite.isMoving) {
|
||||||
|
// If it's character's turn to act, but its sprite
|
||||||
|
// is moving, wait till the movement is over
|
||||||
|
current = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
doNext = current.act();
|
doNext = current.act();
|
||||||
if (doNext && !Dungeon.hero.isAlive()) {
|
if (doNext && !Dungeon.hero.isAlive()) {
|
||||||
doNext = false;
|
doNext = false;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.actors;
|
package com.shatteredpixel.shatteredpixeldungeon.actors;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.*;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.*;
|
||||||
|
@ -120,9 +121,9 @@ public abstract class Char extends Actor {
|
||||||
GLog.i( TXT_HIT, name, enemy.name );
|
GLog.i( TXT_HIT, name, enemy.name );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refactoring needed!
|
// FIXME
|
||||||
int dr = this instanceof Hero && ((Hero)this).usingRanged && ((Hero)this).subClass == HeroSubClass.SNIPER ?
|
int dr = this instanceof Hero && ((Hero)this).rangedWeapon != null && ((Hero)this).subClass ==
|
||||||
0 : Random.IntRange( 0, enemy.dr() );
|
HeroSubClass.SNIPER ? 0 : Random.IntRange( 0, enemy.dr() );
|
||||||
|
|
||||||
int dmg = damageRoll();
|
int dmg = damageRoll();
|
||||||
int effectiveDamage = Math.max( dmg - dr, 0 );;
|
int effectiveDamage = Math.max( dmg - dr, 0 );;
|
||||||
|
@ -368,6 +369,10 @@ public abstract class Char extends Actor {
|
||||||
|
|
||||||
sprite.showStatus( CharSprite.NEGATIVE, "bleeding" );
|
sprite.showStatus( CharSprite.NEGATIVE, "bleeding" );
|
||||||
|
|
||||||
|
} else if (buff instanceof Vertigo) {
|
||||||
|
|
||||||
|
sprite.showStatus( CharSprite.NEGATIVE, "dizzy" );
|
||||||
|
|
||||||
} else if (buff instanceof Sleep) {
|
} else if (buff instanceof Sleep) {
|
||||||
sprite.idle();
|
sprite.idle();
|
||||||
}
|
}
|
||||||
|
@ -441,6 +446,19 @@ public abstract class Char extends Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void move( int step ) {
|
public void move( int step ) {
|
||||||
|
|
||||||
|
if (buff( Vertigo.class ) != null) {
|
||||||
|
ArrayList<Integer> candidates = new ArrayList<Integer>();
|
||||||
|
for (int dir : Level.NEIGHBOURS8) {
|
||||||
|
int p = pos + dir;
|
||||||
|
if ((Level.passable[p] || Level.avoid[p]) && Actor.findChar( p ) == null) {
|
||||||
|
candidates.add( p );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step = Random.element( candidates );
|
||||||
|
}
|
||||||
|
|
||||||
if (Dungeon.level.map[pos] == Terrain.OPEN_DOOR) {
|
if (Dungeon.level.map[pos] == Terrain.OPEN_DOOR) {
|
||||||
Door.leave( pos );
|
Door.leave( pos );
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Pixel Dungeon
|
||||||
|
* Copyright (C) 2012-2014 Oleg Dolya
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
package com.shatteredpixel.shatteredpixeldungeon.actors.blobs;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.BlobEmitter;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||||
|
|
||||||
|
public class ConfusionGas extends Blob {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void evolve() {
|
||||||
|
super.evolve();
|
||||||
|
|
||||||
|
Char ch;
|
||||||
|
for (int i=0; i < LENGTH; i++) {
|
||||||
|
if (cur[i] > 0 && (ch = Actor.findChar( i )) != null) {
|
||||||
|
Buff.prolong( ch, Vertigo.class, Vertigo.duration( ch ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void use( BlobEmitter emitter ) {
|
||||||
|
super.use( emitter );
|
||||||
|
|
||||||
|
emitter.pour( Speck.factory( Speck.CONFUSION, true ), 0.6f );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String tileDesc() {
|
||||||
|
return "A cloud of confusion gas is swirling here.";
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.BlobEmitter;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.utils.Utils;
|
import com.shatteredpixel.shatteredpixeldungeon.utils.Utils;
|
||||||
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
public class ToxicGas extends Blob implements Hero.Doom {
|
public class ToxicGas extends Blob implements Hero.Doom {
|
||||||
|
|
||||||
|
@ -41,8 +42,8 @@ public class ToxicGas extends Blob implements Hero.Doom {
|
||||||
if (cur[i] > 0 && (ch = Actor.findChar( i )) != null) {
|
if (cur[i] > 0 && (ch = Actor.findChar( i )) != null) {
|
||||||
|
|
||||||
int damage = (ch.HT + levelDamage) / 40;
|
int damage = (ch.HT + levelDamage) / 40;
|
||||||
if (damage < 1) {
|
if (Random.Int( 40 ) < (ch.HT + levelDamage) % 40) {
|
||||||
damage = 1;
|
damage++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ch.damage( damage, this );
|
ch.damage( damage, this );
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
|
package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
|
||||||
|
|
||||||
// Special kind of buff, that doesn't perform any kind actions
|
//Special kind of buff, that doesn't perform any kind actions
|
||||||
public class FlavourBuff extends Buff {
|
public class FlavourBuff extends Buff {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class MagicalSleep extends Buff {
|
||||||
GLog.i("You fall into a deep magical sleep.");
|
GLog.i("You fall into a deep magical sleep.");
|
||||||
}
|
}
|
||||||
else if (target instanceof Mob)
|
else if (target instanceof Mob)
|
||||||
((Mob)target).state = Mob.State.SLEEPING;
|
((Mob)target).state = ((Mob)target).SLEEPEING;
|
||||||
|
|
||||||
target.paralysed = true;
|
target.paralysed = true;
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,6 @@ import com.watabou.utils.Bundle;
|
||||||
|
|
||||||
public class Poison extends Buff implements Hero.Doom {
|
public class Poison extends Buff implements Hero.Doom {
|
||||||
|
|
||||||
public static final int DOT = 2;
|
|
||||||
|
|
||||||
protected float left;
|
protected float left;
|
||||||
|
|
||||||
private static final String LEFT = "left";
|
private static final String LEFT = "left";
|
||||||
|
@ -67,7 +65,7 @@ public class Poison extends Buff implements Hero.Doom {
|
||||||
public boolean act() {
|
public boolean act() {
|
||||||
if (target.isAlive()) {
|
if (target.isAlive()) {
|
||||||
|
|
||||||
target.damage( DOT, this );
|
target.damage( (int)(left / 3) + 1, this );
|
||||||
spend( TICK );
|
spend( TICK );
|
||||||
|
|
||||||
if ((left -= TICK) <= 0) {
|
if ((left -= TICK) <= 0) {
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2014 Oleg Dolya
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfElements.Resistance;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
|
||||||
|
|
||||||
|
public class Vertigo extends FlavourBuff {
|
||||||
|
|
||||||
|
public static final float DURATION = 10f;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int icon() {
|
||||||
|
return BuffIndicator.VERTIGO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Vertigo";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float duration( Char ch ) {
|
||||||
|
Resistance r = ch.buff( Resistance.class );
|
||||||
|
return r != null ? r.durationFactor() * DURATION : DURATION;
|
||||||
|
}
|
||||||
|
}
|
|
@ -120,12 +120,11 @@ public class Belongings implements Iterable<Item> {
|
||||||
|
|
||||||
public void countIronKeys() {
|
public void countIronKeys() {
|
||||||
|
|
||||||
IronKey.curDepthQunatity = 0;
|
IronKey.curDepthQuantity = 0;
|
||||||
|
|
||||||
for (Item item : backpack) {
|
for (Item item : backpack) {
|
||||||
if (item instanceof IronKey && ((IronKey)item).depth == Dungeon.depth) {
|
if (item instanceof IronKey && ((IronKey)item).depth == Dungeon.depth) {
|
||||||
IronKey.curDepthQunatity = item.quantity();
|
IronKey.curDepthQuantity++;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,16 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.hero;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ResultDescriptions;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Drowsy;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Drowsy;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.NPC;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.CapeOfThorns;
|
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.CapeOfThorns;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TalismanOfForesight;
|
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TalismanOfForesight;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.*;
|
import com.shatteredpixel.shatteredpixeldungeon.items.rings.*;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
|
||||||
import com.watabou.noosa.Camera;
|
import com.watabou.noosa.Camera;
|
||||||
import com.watabou.noosa.Game;
|
import com.watabou.noosa.Game;
|
||||||
import com.watabou.noosa.audio.Sample;
|
import com.watabou.noosa.audio.Sample;
|
||||||
|
@ -143,7 +147,7 @@ public class Hero extends Char {
|
||||||
|
|
||||||
public boolean restoreHealth = false;
|
public boolean restoreHealth = false;
|
||||||
|
|
||||||
public boolean usingRanged = false;
|
public MissileWeapon rangedWeapon = null;
|
||||||
public Belongings belongings;
|
public Belongings belongings;
|
||||||
|
|
||||||
public int STR;
|
public int STR;
|
||||||
|
@ -224,9 +228,6 @@ public class Hero extends Char {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void preview( GamesInProgress.Info info, Bundle bundle ) {
|
public static void preview( GamesInProgress.Info info, Bundle bundle ) {
|
||||||
// Refactoring needed!
|
|
||||||
Armor armor = (Armor)bundle.get( "armor" );
|
|
||||||
info.armor = armor == null ? 0 : armor.tier;
|
|
||||||
info.level = bundle.getInt( LEVEL );
|
info.level = bundle.getInt( LEVEL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,28 +244,27 @@ public class Hero extends Char {
|
||||||
return belongings.armor == null ? 0 : belongings.armor.tier;
|
return belongings.armor == null ? 0 : belongings.armor.tier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shoot( Char enemy, Weapon wep ) {
|
public boolean shoot( Char enemy, MissileWeapon wep ) {
|
||||||
|
|
||||||
// Ugly...
|
|
||||||
usingRanged = true;
|
|
||||||
|
|
||||||
KindOfWeapon curWep = belongings.weapon;
|
|
||||||
belongings.weapon = wep;
|
|
||||||
|
|
||||||
|
rangedWeapon = wep;
|
||||||
boolean result = attack( enemy );
|
boolean result = attack( enemy );
|
||||||
|
rangedWeapon = null;
|
||||||
belongings.weapon = curWep;
|
|
||||||
usingRanged = false;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int attackSkill( Char target ) {
|
public int attackSkill( Char target ) {
|
||||||
if (belongings.weapon != null) {
|
float accuracy = 1;
|
||||||
return (int) (attackSkill * belongings.weapon.acuracyFactor(this));
|
if (rangedWeapon != null && Level.distance( pos, target.pos ) == 1) {
|
||||||
|
accuracy *= 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
KindOfWeapon wep = rangedWeapon != null ? rangedWeapon : belongings.weapon;
|
||||||
|
if (wep != null) {
|
||||||
|
return (int)(attackSkill * accuracy * wep.acuracyFactor( this ));
|
||||||
} else {
|
} else {
|
||||||
return attackSkill;
|
return (int)(attackSkill * accuracy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,14 +312,15 @@ public class Hero extends Char {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int damageRoll() {
|
public int damageRoll() {
|
||||||
|
KindOfWeapon wep = rangedWeapon != null ? rangedWeapon : belongings.weapon;
|
||||||
int dmg;
|
int dmg;
|
||||||
int bonus = 0;
|
int bonus = 0;
|
||||||
for (Buff buff : buffs( RingOfForce.Force.class )) {
|
for (Buff buff : buffs( RingOfForce.Force.class )) {
|
||||||
bonus += ((RingOfForce.Force)buff).level;
|
bonus += ((RingOfForce.Force)buff).level;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (belongings.weapon != null) {
|
if (wep != null) {
|
||||||
dmg = belongings.weapon.damageRoll( this ) + bonus;
|
dmg = wep.damageRoll( this ) + bonus;
|
||||||
} else {
|
} else {
|
||||||
int bonusMax = 1 + (int)(bonus * (lvl/5f));
|
int bonusMax = 1 + (int)(bonus * (lvl/5f));
|
||||||
dmg = Random.NormalIntRange( 1+bonus, Math.max(1+bonus , STR()-9+bonusMax ) );
|
dmg = Random.NormalIntRange( 1+bonus, Math.max(1+bonus , STR()-9+bonusMax ) );
|
||||||
|
@ -353,9 +354,10 @@ public class Hero extends Char {
|
||||||
}
|
}
|
||||||
|
|
||||||
public float attackDelay() {
|
public float attackDelay() {
|
||||||
if (belongings.weapon != null) {
|
KindOfWeapon wep = rangedWeapon != null ? rangedWeapon : belongings.weapon;
|
||||||
|
if (wep != null) {
|
||||||
|
|
||||||
return belongings.weapon.speedFactor( this );
|
return wep.speedFactor( this );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//Normally putting furor speed on unarmed attacks would be unnecessary
|
//Normally putting furor speed on unarmed attacks would be unnecessary
|
||||||
|
@ -408,6 +410,7 @@ public class Hero extends Char {
|
||||||
}
|
}
|
||||||
|
|
||||||
ready();
|
ready();
|
||||||
|
return false;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -417,52 +420,52 @@ public class Hero extends Char {
|
||||||
|
|
||||||
if (curAction instanceof HeroAction.Move) {
|
if (curAction instanceof HeroAction.Move) {
|
||||||
|
|
||||||
actMove( (HeroAction.Move)curAction );
|
return actMove( (HeroAction.Move)curAction );
|
||||||
|
|
||||||
} else
|
} else
|
||||||
if (curAction instanceof HeroAction.Interact) {
|
if (curAction instanceof HeroAction.Interact) {
|
||||||
|
|
||||||
actInteract( (HeroAction.Interact)curAction );
|
return actInteract( (HeroAction.Interact)curAction );
|
||||||
|
|
||||||
} else
|
} else
|
||||||
if (curAction instanceof HeroAction.Buy) {
|
if (curAction instanceof HeroAction.Buy) {
|
||||||
|
|
||||||
actBuy( (HeroAction.Buy)curAction );
|
return actBuy( (HeroAction.Buy)curAction );
|
||||||
|
|
||||||
}else
|
}else
|
||||||
if (curAction instanceof HeroAction.PickUp) {
|
if (curAction instanceof HeroAction.PickUp) {
|
||||||
|
|
||||||
actPickUp( (HeroAction.PickUp)curAction );
|
return actPickUp( (HeroAction.PickUp)curAction );
|
||||||
|
|
||||||
} else
|
} else
|
||||||
if (curAction instanceof HeroAction.OpenChest) {
|
if (curAction instanceof HeroAction.OpenChest) {
|
||||||
|
|
||||||
actOpenChest( (HeroAction.OpenChest)curAction );
|
return actOpenChest( (HeroAction.OpenChest)curAction );
|
||||||
|
|
||||||
} else
|
} else
|
||||||
if (curAction instanceof HeroAction.Unlock) {
|
if (curAction instanceof HeroAction.Unlock) {
|
||||||
|
|
||||||
actUnlock( (HeroAction.Unlock)curAction );
|
return actUnlock((HeroAction.Unlock) curAction);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
if (curAction instanceof HeroAction.Descend) {
|
if (curAction instanceof HeroAction.Descend) {
|
||||||
|
|
||||||
actDescend( (HeroAction.Descend)curAction );
|
return actDescend( (HeroAction.Descend)curAction );
|
||||||
|
|
||||||
} else
|
} else
|
||||||
if (curAction instanceof HeroAction.Ascend) {
|
if (curAction instanceof HeroAction.Ascend) {
|
||||||
|
|
||||||
actAscend( (HeroAction.Ascend)curAction );
|
return actAscend( (HeroAction.Ascend)curAction );
|
||||||
|
|
||||||
} else
|
} else
|
||||||
if (curAction instanceof HeroAction.Attack) {
|
if (curAction instanceof HeroAction.Attack) {
|
||||||
|
|
||||||
actAttack( (HeroAction.Attack)curAction );
|
return actAttack( (HeroAction.Attack)curAction );
|
||||||
|
|
||||||
} else
|
} else
|
||||||
if (curAction instanceof HeroAction.Cook) {
|
if (curAction instanceof HeroAction.Cook) {
|
||||||
|
|
||||||
actCook( (HeroAction.Cook)curAction );
|
return actCook( (HeroAction.Cook)curAction );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -495,40 +498,47 @@ public class Hero extends Char {
|
||||||
act();
|
act();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void actMove( HeroAction.Move action ) {
|
private boolean actMove( HeroAction.Move action ) {
|
||||||
|
|
||||||
if (getCloser( action.dst )) {
|
if (getCloser( action.dst )) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (Dungeon.level.map[pos] == Terrain.SIGN) {
|
if (Dungeon.level.map[pos] == Terrain.SIGN) {
|
||||||
GameScene.show( new WndMessage( Dungeon.tip() ) );
|
GameScene.show( new WndMessage( Dungeon.tip() ) );
|
||||||
}
|
}
|
||||||
ready();
|
ready();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void actInteract( HeroAction.Interact action ) {
|
private boolean actInteract( HeroAction.Interact action ) {
|
||||||
|
|
||||||
Mob.NPC npc = action.npc;
|
NPC npc = action.npc;
|
||||||
|
|
||||||
if (Level.adjacent( pos, npc.pos )) {
|
if (Level.adjacent( pos, npc.pos )) {
|
||||||
|
|
||||||
ready();
|
ready();
|
||||||
sprite.turnTo( pos, npc.pos );
|
sprite.turnTo( pos, npc.pos );
|
||||||
npc.interact();
|
npc.interact();
|
||||||
|
return false;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (Level.fieldOfView[npc.pos] && getCloser( npc.pos )) {
|
if (Level.fieldOfView[npc.pos] && getCloser( npc.pos )) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ready();
|
ready();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void actBuy( HeroAction.Buy action ) {
|
private boolean actBuy( HeroAction.Buy action ) {
|
||||||
int dst = action.dst;
|
int dst = action.dst;
|
||||||
if (pos == dst || Level.adjacent( pos, dst )) {
|
if (pos == dst || Level.adjacent( pos, dst )) {
|
||||||
|
|
||||||
|
@ -539,28 +549,37 @@ public class Hero extends Char {
|
||||||
GameScene.show( new WndTradeItem( heap, true ) );
|
GameScene.show( new WndTradeItem( heap, true ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
} else if (getCloser( dst )) {
|
} else if (getCloser( dst )) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ready();
|
ready();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void actCook( HeroAction.Cook action ) {
|
private boolean actCook( HeroAction.Cook action ) {
|
||||||
int dst = action.dst;
|
int dst = action.dst;
|
||||||
if (Dungeon.visible[dst]) {
|
if (Dungeon.visible[dst]) {
|
||||||
|
|
||||||
ready();
|
ready();
|
||||||
AlchemyPot.operate( this, dst );
|
AlchemyPot.operate( this, dst );
|
||||||
|
return false;
|
||||||
|
|
||||||
} else if (getCloser( dst )) {
|
} else if (getCloser( dst )) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ready();
|
ready();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void actPickUp( HeroAction.PickUp action ) {
|
private boolean actPickUp( HeroAction.PickUp action ) {
|
||||||
int dst = action.dst;
|
int dst = action.dst;
|
||||||
if (pos == dst) {
|
if (pos == dst) {
|
||||||
|
|
||||||
|
@ -599,14 +618,19 @@ public class Hero extends Char {
|
||||||
ready();
|
ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
} else if (getCloser( dst )) {
|
} else if (getCloser( dst )) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ready();
|
ready();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void actOpenChest( HeroAction.OpenChest action ) {
|
private boolean actOpenChest( HeroAction.OpenChest action ) {
|
||||||
int dst = action.dst;
|
int dst = action.dst;
|
||||||
if (Level.adjacent( pos, dst ) || pos == dst) {
|
if (Level.adjacent( pos, dst ) || pos == dst) {
|
||||||
|
|
||||||
|
@ -624,7 +648,7 @@ public class Hero extends Char {
|
||||||
if (theKey == null) {
|
if (theKey == null) {
|
||||||
GLog.w( TXT_LOCKED_CHEST );
|
GLog.w( TXT_LOCKED_CHEST );
|
||||||
ready();
|
ready();
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,14 +670,19 @@ public class Hero extends Char {
|
||||||
ready();
|
ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
} else if (getCloser( dst )) {
|
} else if (getCloser( dst )) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ready();
|
ready();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void actUnlock( HeroAction.Unlock action ) {
|
private boolean actUnlock( HeroAction.Unlock action ) {
|
||||||
int doorCell = action.dst;
|
int doorCell = action.dst;
|
||||||
if (Level.adjacent( pos, doorCell )) {
|
if (Level.adjacent( pos, doorCell )) {
|
||||||
|
|
||||||
|
@ -682,14 +711,19 @@ public class Hero extends Char {
|
||||||
ready();
|
ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
} else if (getCloser( doorCell )) {
|
} else if (getCloser( doorCell )) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ready();
|
ready();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void actDescend( HeroAction.Descend action ) {
|
private boolean actDescend( HeroAction.Descend action ) {
|
||||||
int stairs = action.dst;
|
int stairs = action.dst;
|
||||||
if (pos == stairs && pos == Dungeon.level.exit) {
|
if (pos == stairs && pos == Dungeon.level.exit) {
|
||||||
|
|
||||||
|
@ -703,14 +737,19 @@ public class Hero extends Char {
|
||||||
InterlevelScene.mode = InterlevelScene.Mode.DESCEND;
|
InterlevelScene.mode = InterlevelScene.Mode.DESCEND;
|
||||||
Game.switchScene( InterlevelScene.class );
|
Game.switchScene( InterlevelScene.class );
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
} else if (getCloser( stairs )) {
|
} else if (getCloser( stairs )) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ready();
|
ready();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void actAscend( HeroAction.Ascend action ) {
|
private boolean actAscend( HeroAction.Ascend action ) {
|
||||||
int stairs = action.dst;
|
int stairs = action.dst;
|
||||||
if (pos == stairs && pos == Dungeon.level.entrance) {
|
if (pos == stairs && pos == Dungeon.level.entrance) {
|
||||||
|
|
||||||
|
@ -720,6 +759,7 @@ public class Hero extends Char {
|
||||||
GameScene.show( new WndMessage( TXT_LEAVE ) );
|
GameScene.show( new WndMessage( TXT_LEAVE ) );
|
||||||
ready();
|
ready();
|
||||||
} else {
|
} else {
|
||||||
|
Dungeon.win( ResultDescriptions.WIN );
|
||||||
Dungeon.deleteGame( Dungeon.hero.heroClass, true );
|
Dungeon.deleteGame( Dungeon.hero.heroClass, true );
|
||||||
Game.switchScene( SurfaceScene.class );
|
Game.switchScene( SurfaceScene.class );
|
||||||
}
|
}
|
||||||
|
@ -737,14 +777,19 @@ public class Hero extends Char {
|
||||||
Game.switchScene( InterlevelScene.class );
|
Game.switchScene( InterlevelScene.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
} else if (getCloser( stairs )) {
|
} else if (getCloser( stairs )) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ready();
|
ready();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void actAttack( HeroAction.Attack action ) {
|
private boolean actAttack( HeroAction.Attack action ) {
|
||||||
|
|
||||||
enemy = action.target;
|
enemy = action.target;
|
||||||
|
|
||||||
|
@ -753,12 +798,17 @@ public class Hero extends Char {
|
||||||
spend( attackDelay() );
|
spend( attackDelay() );
|
||||||
sprite.attack( enemy.pos );
|
sprite.attack( enemy.pos );
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (Level.fieldOfView[enemy.pos] && getCloser( enemy.pos )) {
|
if (Level.fieldOfView[enemy.pos] && getCloser( enemy.pos )) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ready();
|
ready();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -774,20 +824,20 @@ public class Hero extends Char {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int attackProc( Char enemy, int damage ) {
|
public int attackProc( Char enemy, int damage ) {
|
||||||
if (belongings.weapon != null) {
|
KindOfWeapon wep = rangedWeapon != null ? rangedWeapon : belongings.weapon;
|
||||||
|
if (wep != null) {
|
||||||
|
|
||||||
KindOfWeapon weapon = belongings.weapon;
|
wep.proc( this, enemy, damage );
|
||||||
weapon.proc( this, enemy, damage );
|
|
||||||
|
|
||||||
switch (subClass) {
|
switch (subClass) {
|
||||||
case GLADIATOR:
|
case GLADIATOR:
|
||||||
if (weapon instanceof MeleeWeapon) {
|
if (wep instanceof MeleeWeapon) {
|
||||||
damage += Buff.affect( this, Combo.class ).hit( enemy, damage );
|
damage += Buff.affect( this, Combo.class ).hit( enemy, damage );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BATTLEMAGE:
|
case BATTLEMAGE:
|
||||||
if (weapon instanceof Wand) {
|
if (wep instanceof Wand) {
|
||||||
Wand wand = (Wand)weapon;
|
Wand wand = (Wand)wep;
|
||||||
if (wand.curCharges < wand.maxCharges && damage > 0) {
|
if (wand.curCharges < wand.maxCharges && damage > 0) {
|
||||||
|
|
||||||
wand.curCharges++;
|
wand.curCharges++;
|
||||||
|
@ -800,7 +850,7 @@ public class Hero extends Char {
|
||||||
damage += wand.curCharges;
|
damage += wand.curCharges;
|
||||||
}
|
}
|
||||||
case SNIPER:
|
case SNIPER:
|
||||||
if (usingRanged) {
|
if (rangedWeapon != null) {
|
||||||
Buff.prolong( enemy, SnipersMark.class, attackDelay() * 1.1f );
|
Buff.prolong( enemy, SnipersMark.class, attackDelay() * 1.1f );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -859,7 +909,6 @@ public class Hero extends Char {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkVisibleMobs() {
|
private void checkVisibleMobs() {
|
||||||
|
|
||||||
ArrayList<Mob> visible = new ArrayList<Mob>();
|
ArrayList<Mob> visible = new ArrayList<Mob>();
|
||||||
|
|
||||||
boolean newMob = false;
|
boolean newMob = false;
|
||||||
|
@ -886,7 +935,7 @@ public class Hero extends Char {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mob visibleEnemy( int index ) {
|
public Mob visibleEnemy( int index ) {
|
||||||
return visibleEnemies.get( index % visibleEnemies.size() );
|
return visibleEnemies.get(index % visibleEnemies.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean getCloser( final int target ) {
|
private boolean getCloser( final int target ) {
|
||||||
|
@ -926,8 +975,9 @@ public class Hero extends Char {
|
||||||
|
|
||||||
if (step != -1) {
|
if (step != -1) {
|
||||||
|
|
||||||
sprite.move( pos, step );
|
int oldPos = pos;
|
||||||
move( step );
|
move(step);
|
||||||
|
sprite.move(oldPos, pos);
|
||||||
spend( 1 / speed() );
|
spend( 1 / speed() );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -940,10 +990,10 @@ public class Hero extends Char {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handle( int cell ) {
|
public boolean handle( int cell ) {
|
||||||
|
|
||||||
if (cell == -1) {
|
if (cell == -1) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Char ch;
|
Char ch;
|
||||||
|
@ -956,8 +1006,8 @@ public class Hero extends Char {
|
||||||
} else
|
} else
|
||||||
if (Level.fieldOfView[cell] && (ch = Actor.findChar( cell )) instanceof Mob) {
|
if (Level.fieldOfView[cell] && (ch = Actor.findChar( cell )) instanceof Mob) {
|
||||||
|
|
||||||
if (ch instanceof Mob.NPC) {
|
if (ch instanceof NPC) {
|
||||||
curAction = new HeroAction.Interact( (Mob.NPC)ch );
|
curAction = new HeroAction.Interact( (NPC)ch );
|
||||||
} else {
|
} else {
|
||||||
curAction = new HeroAction.Attack( ch );
|
curAction = new HeroAction.Attack( ch );
|
||||||
}
|
}
|
||||||
|
@ -996,7 +1046,7 @@ public class Hero extends Char {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
act();
|
return act();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void earnExp( int exp ) {
|
public void earnExp( int exp ) {
|
||||||
|
@ -1091,6 +1141,9 @@ public class Hero extends Char {
|
||||||
if (((RingOfMight.Might)buff).level > 0) {
|
if (((RingOfMight.Might)buff).level > 0) {
|
||||||
HT += ((RingOfMight.Might) buff).level * 5;
|
HT += ((RingOfMight.Might) buff).level * 5;
|
||||||
}
|
}
|
||||||
|
} else if (buff instanceof Vertigo) {
|
||||||
|
GLog.w("Everything is spinning around you!");
|
||||||
|
interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (buff instanceof Light) {
|
else if (buff instanceof Light) {
|
||||||
|
@ -1202,18 +1255,17 @@ public class Hero extends Char {
|
||||||
|
|
||||||
if (!flying) {
|
if (!flying) {
|
||||||
|
|
||||||
if (Level.water[step]) {
|
if (Level.water[pos]) {
|
||||||
Sample.INSTANCE.play( Assets.SND_WATER, 1, 1, Random.Float( 0.8f, 1.25f ) );
|
Sample.INSTANCE.play( Assets.SND_WATER, 1, 1, Random.Float( 0.8f, 1.25f ) );
|
||||||
} else {
|
} else {
|
||||||
Sample.INSTANCE.play( Assets.SND_STEP );
|
Sample.INSTANCE.play( Assets.SND_STEP );
|
||||||
}
|
}
|
||||||
Dungeon.level.press(step, this);
|
Dungeon.level.press(pos, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMotionComplete() {
|
public void onMotionComplete() {
|
||||||
|
|
||||||
Dungeon.observe();
|
Dungeon.observe();
|
||||||
search( false );
|
search( false );
|
||||||
|
|
||||||
|
@ -1274,22 +1326,10 @@ public class Hero extends Char {
|
||||||
int positive = 0;
|
int positive = 0;
|
||||||
int negative = 0;
|
int negative = 0;
|
||||||
|
|
||||||
//holding onto this code for now as it may be useful in coding the Talisman of Foresight.
|
|
||||||
/*
|
|
||||||
for (Buff buff : buffs( RingOfDetection.Detection.class )) {
|
|
||||||
int bonus = ((RingOfDetection.Detection)buff).level;
|
|
||||||
if (bonus > positive) {
|
|
||||||
positive = bonus;
|
|
||||||
} else if (bonus < 0) {
|
|
||||||
negative += bonus;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
int distance = 1 + positive + negative;
|
int distance = 1 + positive + negative;
|
||||||
|
|
||||||
float level = intentional ? (2 * awareness - awareness * awareness) : awareness;
|
float level = intentional ? (2 * awareness - awareness * awareness) : awareness;
|
||||||
if (distance <= 0) {
|
if (distance <= 0) {
|
||||||
|
|
||||||
level /= 2 - distance;
|
level /= 2 - distance;
|
||||||
distance = 1;
|
distance = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.actors.hero;
|
package com.shatteredpixel.shatteredpixeldungeon.actors.hero;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.NPC;
|
||||||
|
|
||||||
|
|
||||||
public class HeroAction {
|
public class HeroAction {
|
||||||
|
@ -50,8 +50,8 @@ public class HeroAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Interact extends HeroAction {
|
public static class Interact extends HeroAction {
|
||||||
public Mob.NPC npc;
|
public NPC npc;
|
||||||
public Interact( Mob.NPC npc ) {
|
public Interact( NPC npc ) {
|
||||||
this.npc = npc;
|
this.npc = npc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,8 @@ public enum HeroClass {
|
||||||
|
|
||||||
hero.heroClass = this;
|
hero.heroClass = this;
|
||||||
|
|
||||||
|
initCommon( hero );
|
||||||
|
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case WARRIOR:
|
case WARRIOR:
|
||||||
initWarrior( hero );
|
initWarrior( hero );
|
||||||
|
@ -100,20 +102,37 @@ public enum HeroClass {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Badges.isUnlocked( masteryBadge() )) {
|
||||||
|
new TomeOfMastery().collect();
|
||||||
|
}
|
||||||
|
|
||||||
hero.updateAwareness();
|
hero.updateAwareness();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void initCommon( Hero hero ) {
|
||||||
|
(hero.belongings.armor = new ClothArmor()).identify();
|
||||||
|
new Food().identify().collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Badges.Badge masteryBadge() {
|
||||||
|
switch (this) {
|
||||||
|
case WARRIOR:
|
||||||
|
return Badges.Badge.MASTERY_WARRIOR;
|
||||||
|
case MAGE:
|
||||||
|
return Badges.Badge.MASTERY_MAGE;
|
||||||
|
case ROGUE:
|
||||||
|
return Badges.Badge.MASTERY_ROGUE;
|
||||||
|
case HUNTRESS:
|
||||||
|
return Badges.Badge.MASTERY_HUNTRESS;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static void initWarrior( Hero hero ) {
|
private static void initWarrior( Hero hero ) {
|
||||||
hero.STR = hero.STR + 1;
|
hero.STR = hero.STR + 1;
|
||||||
|
|
||||||
(hero.belongings.weapon = new ShortSword()).identify();
|
(hero.belongings.weapon = new ShortSword()).identify();
|
||||||
(hero.belongings.armor = new ClothArmor()).identify();
|
|
||||||
new Dart( 8 ).identify().collect();
|
new Dart( 8 ).identify().collect();
|
||||||
new Food().identify().collect();
|
|
||||||
|
|
||||||
if (Badges.isUnlocked( Badges.Badge.MASTERY_WARRIOR )) {
|
|
||||||
new TomeOfMastery().collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
Dungeon.quickslot = Dart.class;
|
Dungeon.quickslot = Dart.class;
|
||||||
|
|
||||||
|
@ -122,16 +141,10 @@ public enum HeroClass {
|
||||||
|
|
||||||
private static void initMage( Hero hero ) {
|
private static void initMage( Hero hero ) {
|
||||||
(hero.belongings.weapon = new Knuckles()).identify();
|
(hero.belongings.weapon = new Knuckles()).identify();
|
||||||
(hero.belongings.armor = new ClothArmor()).identify();
|
|
||||||
new Food().identify().collect();
|
|
||||||
|
|
||||||
WandOfMagicMissile wand = new WandOfMagicMissile();
|
WandOfMagicMissile wand = new WandOfMagicMissile();
|
||||||
wand.identify().collect();
|
wand.identify().collect();
|
||||||
|
|
||||||
if (Badges.isUnlocked( Badges.Badge.MASTERY_MAGE )) {
|
|
||||||
new TomeOfMastery().collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
Dungeon.quickslot = wand;
|
Dungeon.quickslot = wand;
|
||||||
|
|
||||||
new ScrollOfIdentify().setKnown();
|
new ScrollOfIdentify().setKnown();
|
||||||
|
@ -139,17 +152,13 @@ public enum HeroClass {
|
||||||
|
|
||||||
private static void initRogue( Hero hero ) {
|
private static void initRogue( Hero hero ) {
|
||||||
(hero.belongings.weapon = new Dagger()).identify();
|
(hero.belongings.weapon = new Dagger()).identify();
|
||||||
(hero.belongings.armor = new ClothArmor()).identify();
|
|
||||||
CloakOfShadows cloak = new CloakOfShadows();
|
CloakOfShadows cloak = new CloakOfShadows();
|
||||||
hero.belongings.misc1 = cloak;
|
hero.belongings.misc1 = cloak;
|
||||||
new Dart( 8 ).identify().collect();
|
|
||||||
new Food().identify().collect();
|
|
||||||
|
|
||||||
hero.belongings.misc1.activate( hero );
|
hero.belongings.misc1.activate( hero );
|
||||||
|
|
||||||
if (Badges.isUnlocked( Badges.Badge.MASTERY_ROGUE )) {
|
new Dart( 8 ).identify().collect();
|
||||||
new TomeOfMastery().collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
Dungeon.quickslot = cloak;
|
Dungeon.quickslot = cloak;
|
||||||
|
|
||||||
|
@ -161,14 +170,8 @@ public enum HeroClass {
|
||||||
hero.HP = (hero.HT -= 5);
|
hero.HP = (hero.HT -= 5);
|
||||||
|
|
||||||
(hero.belongings.weapon = new Dagger()).identify();
|
(hero.belongings.weapon = new Dagger()).identify();
|
||||||
(hero.belongings.armor = new ClothArmor()).identify();
|
|
||||||
Boomerang boomerang = new Boomerang();
|
Boomerang boomerang = new Boomerang();
|
||||||
boomerang.identify().collect();
|
boomerang.identify().collect();
|
||||||
new Food().identify().collect();
|
|
||||||
|
|
||||||
if (Badges.isUnlocked( Badges.Badge.MASTERY_HUNTRESS )) {
|
|
||||||
new TomeOfMastery().collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
Dungeon.quickslot = boomerang;
|
Dungeon.quickslot = boomerang;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ public enum HeroSubClass {
|
||||||
GLADIATOR( "gladiator",
|
GLADIATOR( "gladiator",
|
||||||
"A successful attack with a melee weapon allows the _Gladiator_ to start a combo, " +
|
"A successful attack with a melee weapon allows the _Gladiator_ to start a combo, " +
|
||||||
"in which every next successful hit inflicts more damage." ),
|
"in which every next successful hit inflicts more damage." ),
|
||||||
|
|
||||||
BERSERKER( "berserker",
|
BERSERKER( "berserker",
|
||||||
"When severely wounded, the _Berserker_ enters a state of wild fury " +
|
"When severely wounded, the _Berserker_ enters a state of wild fury " +
|
||||||
"significantly increasing his damage output." ),
|
"significantly increasing his damage output." ),
|
||||||
|
@ -34,14 +33,12 @@ public enum HeroSubClass {
|
||||||
WARLOCK( "warlock",
|
WARLOCK( "warlock",
|
||||||
"After killing an enemy the _Warlock_ consumes its soul. " +
|
"After killing an enemy the _Warlock_ consumes its soul. " +
|
||||||
"It heals his wounds and satisfies his hunger." ),
|
"It heals his wounds and satisfies his hunger." ),
|
||||||
|
|
||||||
BATTLEMAGE( "battlemage",
|
BATTLEMAGE( "battlemage",
|
||||||
"When fighting with a wand in his hands, the _Battlemage_ inflicts additional damage depending " +
|
"When fighting with a wand in his hands, the _Battlemage_ inflicts additional damage depending " +
|
||||||
"on the current number of charges. Every successful hit restores 1 charge to this wand." ),
|
"on the current number of charges. Every successful hit restores 1 charge to this wand." ),
|
||||||
|
|
||||||
ASSASSIN( "assassin",
|
ASSASSIN( "assassin",
|
||||||
"When performing a surprise attack, the _Assassin_ inflicts additional damage to his target." ),
|
"When performing a surprise attack, the _Assassin_ inflicts additional damage to his target." ),
|
||||||
|
|
||||||
FREERUNNER( "freerunner",
|
FREERUNNER( "freerunner",
|
||||||
"The _Freerunner_ can move almost twice faster, than most of the monsters. When he " +
|
"The _Freerunner_ can move almost twice faster, than most of the monsters. When he " +
|
||||||
"is running, the Freerunner is much harder to hit. For that he must be unencumbered and not starving." ),
|
"is running, the Freerunner is much harder to hit. For that he must be unencumbered and not starving." ),
|
||||||
|
@ -49,7 +46,6 @@ public enum HeroSubClass {
|
||||||
SNIPER( "sniper",
|
SNIPER( "sniper",
|
||||||
"_Snipers_ are able to detect weak points in an enemy's armor, " +
|
"_Snipers_ are able to detect weak points in an enemy's armor, " +
|
||||||
"effectively ignoring it when using a missile weapon." ),
|
"effectively ignoring it when using a missile weapon." ),
|
||||||
|
|
||||||
WARDEN( "warden",
|
WARDEN( "warden",
|
||||||
"Having a strong connection with forces of nature gives _Wardens_ an ability to gather dewdrops and " +
|
"Having a strong connection with forces of nature gives _Wardens_ an ability to gather dewdrops and " +
|
||||||
"seeds from plants. Also trampling a high grass grants them a temporary armor buff." );
|
"seeds from plants. Also trampling a high grass grants them a temporary armor buff." );
|
||||||
|
|
|
@ -246,7 +246,7 @@ public class King extends Mob {
|
||||||
|
|
||||||
EXP = 0;
|
EXP = 0;
|
||||||
|
|
||||||
state = State.WANDERING;
|
state = WANDERING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,6 +20,7 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
|
@ -31,7 +32,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Wound;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Wound;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfAccuracy;
|
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfAccuracy;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
|
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
|
||||||
|
@ -49,14 +49,12 @@ public abstract class Mob extends Char {
|
||||||
protected static final String TXT_RAGE = "#$%^";
|
protected static final String TXT_RAGE = "#$%^";
|
||||||
protected static final String TXT_EXP = "%+dEXP";
|
protected static final String TXT_EXP = "%+dEXP";
|
||||||
|
|
||||||
public enum State {
|
public AiState SLEEPEING = new Sleeping();
|
||||||
SLEEPING,
|
public AiState HUNTING = new Hunting();
|
||||||
HUNTING,
|
public AiState WANDERING = new Wandering();
|
||||||
WANDERING,
|
public AiState FLEEING = new Fleeing();
|
||||||
FLEEING,
|
public AiState PASSIVE = new Passive();
|
||||||
PASSIVE
|
public AiState state = SLEEPEING;
|
||||||
}
|
|
||||||
public State state = State.SLEEPING;
|
|
||||||
|
|
||||||
public Class<? extends CharSprite> spriteClass;
|
public Class<? extends CharSprite> spriteClass;
|
||||||
|
|
||||||
|
@ -91,11 +89,18 @@ public abstract class Mob extends Char {
|
||||||
|
|
||||||
super.storeInBundle( bundle );
|
super.storeInBundle( bundle );
|
||||||
|
|
||||||
bundle.put( STATE, state.toString() );
|
if (state == SLEEPEING) {
|
||||||
bundle.put( SEEN, enemySeen);
|
bundle.put( STATE, Sleeping.TAG );
|
||||||
if (state != State.SLEEPING) {
|
} else if (state == WANDERING) {
|
||||||
bundle.put( TARGET, target );
|
bundle.put( STATE, Wandering.TAG );
|
||||||
|
} else if (state == HUNTING) {
|
||||||
|
bundle.put( STATE, Hunting.TAG );
|
||||||
|
} else if (state == FLEEING) {
|
||||||
|
bundle.put( STATE, Fleeing.TAG );
|
||||||
|
} else if (state == PASSIVE) {
|
||||||
|
bundle.put( STATE, Passive.TAG );
|
||||||
}
|
}
|
||||||
|
bundle.put( TARGET, target );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -103,11 +108,20 @@ public abstract class Mob extends Char {
|
||||||
|
|
||||||
super.restoreFromBundle( bundle );
|
super.restoreFromBundle( bundle );
|
||||||
|
|
||||||
state = State.valueOf( bundle.getString( STATE ) );
|
String state = bundle.getString( STATE );
|
||||||
enemySeen = bundle.getBoolean( SEEN );
|
if (state.equals( Sleeping.TAG )) {
|
||||||
if (state != State.SLEEPING) {
|
this.state = SLEEPEING;
|
||||||
target = bundle.getInt( TARGET );
|
} else if (state.equals( Wandering.TAG )) {
|
||||||
|
this.state = WANDERING;
|
||||||
|
} else if (state.equals( Hunting.TAG )) {
|
||||||
|
this.state = HUNTING;
|
||||||
|
} else if (state.equals( Fleeing.TAG )) {
|
||||||
|
this.state = FLEEING;
|
||||||
|
} else if (state.equals( Passive.TAG )) {
|
||||||
|
this.state = PASSIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target = bundle.getInt( TARGET );
|
||||||
}
|
}
|
||||||
|
|
||||||
public CharSprite sprite() {
|
public CharSprite sprite() {
|
||||||
|
@ -124,7 +138,7 @@ public abstract class Mob extends Char {
|
||||||
|
|
||||||
super.act();
|
super.act();
|
||||||
|
|
||||||
boolean alertedNow = alerted;
|
boolean justAlerted = alerted;
|
||||||
alerted = false;
|
alerted = false;
|
||||||
|
|
||||||
sprite.hideAlert();
|
sprite.hideAlert();
|
||||||
|
@ -139,109 +153,7 @@ public abstract class Mob extends Char {
|
||||||
|
|
||||||
boolean enemyInFOV = enemy.isAlive() && Level.fieldOfView[enemy.pos] && enemy.invisible <= 0;
|
boolean enemyInFOV = enemy.isAlive() && Level.fieldOfView[enemy.pos] && enemy.invisible <= 0;
|
||||||
|
|
||||||
int oldPos = pos;
|
return state.act( enemyInFOV, justAlerted );
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
|
|
||||||
case SLEEPING:
|
|
||||||
if (enemyInFOV &&
|
|
||||||
Random.Int( distance( enemy ) + enemy.stealth() + (enemy.flying ? 2 : 0) ) == 0) {
|
|
||||||
|
|
||||||
enemySeen = true;
|
|
||||||
|
|
||||||
notice();
|
|
||||||
state = State.HUNTING;
|
|
||||||
target = enemy.pos;
|
|
||||||
|
|
||||||
spend( TIME_TO_WAKE_UP );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
enemySeen = false;
|
|
||||||
|
|
||||||
spend( TICK );
|
|
||||||
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case WANDERING:
|
|
||||||
if (enemyInFOV && (alertedNow || Random.Int( distance( enemy ) / 2 + enemy.stealth() ) == 0)) {
|
|
||||||
|
|
||||||
enemySeen = true;
|
|
||||||
|
|
||||||
notice();
|
|
||||||
state = State.HUNTING;
|
|
||||||
target = enemy.pos;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
enemySeen = false;
|
|
||||||
|
|
||||||
if (target != -1 && getCloser( target )) {
|
|
||||||
spend( 1 / speed() );
|
|
||||||
return moveSprite( oldPos, pos );
|
|
||||||
} else {
|
|
||||||
target = Dungeon.level.randomDestination();
|
|
||||||
spend( TICK );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case HUNTING:
|
|
||||||
enemySeen = enemyInFOV;
|
|
||||||
if (enemyInFOV && canAttack( enemy )) {
|
|
||||||
|
|
||||||
return doAttack( enemy );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (enemyInFOV) {
|
|
||||||
target = enemy.pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target != -1 && getCloser( target )) {
|
|
||||||
|
|
||||||
|
|
||||||
spend( 1 / speed() );
|
|
||||||
return moveSprite( oldPos, pos );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
spend( TICK );
|
|
||||||
state = State.WANDERING;
|
|
||||||
target = Dungeon.level.randomDestination(); // <--------
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case FLEEING:
|
|
||||||
enemySeen = enemyInFOV;
|
|
||||||
if (enemyInFOV) {
|
|
||||||
target = enemy.pos;
|
|
||||||
}
|
|
||||||
if (target != -1 && getFurther( target )) {
|
|
||||||
|
|
||||||
spend( 1 / speed() );
|
|
||||||
return moveSprite( oldPos, pos );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
spend( TICK );
|
|
||||||
nowhereToRun();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PASSIVE:
|
|
||||||
enemySeen = false;
|
|
||||||
spend( TICK );
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Char chooseEnemy() {
|
protected Char chooseEnemy() {
|
||||||
|
@ -272,14 +184,11 @@ public abstract class Mob extends Char {
|
||||||
return Dungeon.hero;
|
return Dungeon.hero;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void nowhereToRun() {
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean moveSprite( int from, int to ) {
|
protected boolean moveSprite( int from, int to ) {
|
||||||
|
|
||||||
if (sprite.isVisible() && (Dungeon.visible[from] || Dungeon.visible[to])) {
|
if (sprite.isVisible() && (Dungeon.visible[from] || Dungeon.visible[to])) {
|
||||||
sprite.move( from, to );
|
sprite.move( from, to );
|
||||||
return false;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
sprite.place( to );
|
sprite.place( to );
|
||||||
return true;
|
return true;
|
||||||
|
@ -293,11 +202,11 @@ public abstract class Mob extends Char {
|
||||||
if (sprite != null) {
|
if (sprite != null) {
|
||||||
sprite.showStatus( CharSprite.NEGATIVE, TXT_RAGE );
|
sprite.showStatus( CharSprite.NEGATIVE, TXT_RAGE );
|
||||||
}
|
}
|
||||||
state = State.HUNTING;
|
state = HUNTING;
|
||||||
} else if (buff instanceof Terror) {
|
} else if (buff instanceof Terror) {
|
||||||
state = State.FLEEING;
|
state = FLEEING;
|
||||||
} else if (buff instanceof Sleep) {
|
} else if (buff instanceof Sleep) {
|
||||||
state = State.SLEEPING;
|
state = SLEEPEING;
|
||||||
this.sprite().showSleep();
|
this.sprite().showSleep();
|
||||||
postpone( Sleep.SWS );
|
postpone( Sleep.SWS );
|
||||||
}
|
}
|
||||||
|
@ -308,7 +217,7 @@ public abstract class Mob extends Char {
|
||||||
super.remove( buff );
|
super.remove( buff );
|
||||||
if (buff instanceof Terror) {
|
if (buff instanceof Terror) {
|
||||||
sprite.showStatus( CharSprite.NEGATIVE, TXT_RAGE );
|
sprite.showStatus( CharSprite.NEGATIVE, TXT_RAGE );
|
||||||
state = State.HUNTING;
|
state = HUNTING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,8 +318,8 @@ public abstract class Mob extends Char {
|
||||||
|
|
||||||
Terror.recover( this );
|
Terror.recover( this );
|
||||||
|
|
||||||
if (state == State.SLEEPING) {
|
if (state == SLEEPEING) {
|
||||||
state = State.WANDERING;
|
state = WANDERING;
|
||||||
}
|
}
|
||||||
alerted = true;
|
alerted = true;
|
||||||
|
|
||||||
|
@ -501,8 +410,8 @@ public abstract class Mob extends Char {
|
||||||
|
|
||||||
notice();
|
notice();
|
||||||
|
|
||||||
if (state != State.HUNTING) {
|
if (state != HUNTING) {
|
||||||
state = State.WANDERING;
|
state = WANDERING;
|
||||||
}
|
}
|
||||||
target = cell;
|
target = cell;
|
||||||
}
|
}
|
||||||
|
@ -519,31 +428,177 @@ public abstract class Mob extends Char {
|
||||||
GLog.n( "%s: \"%s\" ", name, str );
|
GLog.n( "%s: \"%s\" ", name, str );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static abstract class NPC extends Mob {
|
public interface AiState {
|
||||||
|
public boolean act( boolean enemyInFOV, boolean justAlerted );
|
||||||
{
|
public String status();
|
||||||
HP = HT = 1;
|
|
||||||
EXP = 0;
|
|
||||||
|
|
||||||
hostile = false;
|
|
||||||
state = State.PASSIVE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void throwItem() {
|
private class Sleeping implements AiState {
|
||||||
Heap heap = Dungeon.level.heaps.get( pos );
|
|
||||||
if (heap != null) {
|
public static final String TAG = "SLEEPING";
|
||||||
int n;
|
|
||||||
do {
|
@Override
|
||||||
n = pos + Level.NEIGHBOURS8[Random.Int( 8 )];
|
public boolean act( boolean enemyInFOV, boolean justAlerted ) {
|
||||||
} while (!Level.passable[n] && !Level.avoid[n]);
|
if (enemyInFOV && Random.Int( distance( enemy ) + enemy.stealth() + (enemy.flying ? 2 : 0) ) == 0) {
|
||||||
Dungeon.level.drop( heap.pickUp(), n ).sprite.drop( pos );
|
|
||||||
|
enemySeen = true;
|
||||||
|
|
||||||
|
notice();
|
||||||
|
state = HUNTING;
|
||||||
|
target = enemy.pos;
|
||||||
|
|
||||||
|
if (Dungeon.isChallenged( Challenges.SWARM_INTELLIGENCE )) {
|
||||||
|
for (Mob mob : Dungeon.level.mobs) {
|
||||||
|
if (mob != Mob.this) {
|
||||||
|
mob.beckon( target );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spend( TIME_TO_WAKE_UP );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
enemySeen = false;
|
||||||
|
|
||||||
|
spend( TICK );
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String status() {
|
||||||
|
return String.format( "This %s is sleeping", name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Wandering implements AiState {
|
||||||
|
|
||||||
|
public static final String TAG = "WANDERING";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean act( boolean enemyInFOV, boolean justAlerted ) {
|
||||||
|
if (enemyInFOV && (justAlerted || Random.Int( distance( enemy ) / 2 + enemy.stealth() ) == 0)) {
|
||||||
|
|
||||||
|
enemySeen = true;
|
||||||
|
|
||||||
|
notice();
|
||||||
|
state = HUNTING;
|
||||||
|
target = enemy.pos;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
enemySeen = false;
|
||||||
|
|
||||||
|
int oldPos = pos;
|
||||||
|
if (target != -1 && getCloser( target )) {
|
||||||
|
spend( 1 / speed() );
|
||||||
|
return moveSprite( oldPos, pos );
|
||||||
|
} else {
|
||||||
|
target = Dungeon.level.randomDestination();
|
||||||
|
spend( TICK );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String status() {
|
||||||
|
return String.format( "This %s is wandering", name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Hunting implements AiState {
|
||||||
|
|
||||||
|
public static final String TAG = "HUNTING";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean act( boolean enemyInFOV, boolean justAlerted ) {
|
||||||
|
enemySeen = enemyInFOV;
|
||||||
|
if (enemyInFOV && canAttack( enemy )) {
|
||||||
|
|
||||||
|
return doAttack( enemy );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (enemyInFOV) {
|
||||||
|
target = enemy.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int oldPos = pos;
|
||||||
|
if (target != -1 && getCloser( target )) {
|
||||||
|
|
||||||
|
spend( 1 / speed() );
|
||||||
|
return moveSprite( oldPos, pos );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
spend( TICK );
|
||||||
|
state = WANDERING;
|
||||||
|
target = Dungeon.level.randomDestination();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beckon( int cell ) {
|
public String status() {
|
||||||
|
return String.format( "This %s is hunting", name );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public void interact();
|
protected class Fleeing implements AiState {
|
||||||
|
|
||||||
|
public static final String TAG = "FLEEING";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean act( boolean enemyInFOV, boolean justAlerted ) {
|
||||||
|
enemySeen = enemyInFOV;
|
||||||
|
if (enemyInFOV) {
|
||||||
|
target = enemy.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int oldPos = pos;
|
||||||
|
if (target != -1 && getFurther( target )) {
|
||||||
|
|
||||||
|
spend( 1 / speed() );
|
||||||
|
return moveSprite( oldPos, pos );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
spend( TICK );
|
||||||
|
nowhereToRun();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void nowhereToRun() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String status() {
|
||||||
|
return String.format( "This %s is fleeing", name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Passive implements AiState {
|
||||||
|
|
||||||
|
public static final String TAG = "PASSIVE";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean act( boolean enemyInFOV, boolean justAlerted ) {
|
||||||
|
enemySeen = false;
|
||||||
|
spend( TICK );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String status() {
|
||||||
|
return String.format( "This %s is passive", name );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ public class Scorpio extends Mob {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean getCloser( int target ) {
|
protected boolean getCloser( int target ) {
|
||||||
if (state == State.HUNTING) {
|
if (state == HUNTING) {
|
||||||
return enemySeen && getFurther( target );
|
return enemySeen && getFurther( target );
|
||||||
} else {
|
} else {
|
||||||
return super.getCloser( target );
|
return super.getCloser( target );
|
||||||
|
|
|
@ -45,24 +45,17 @@ public class Spinner extends Mob {
|
||||||
|
|
||||||
loot = new MysteryMeat();
|
loot = new MysteryMeat();
|
||||||
lootChance = 0.125f;
|
lootChance = 0.125f;
|
||||||
|
|
||||||
|
FLEEING = new Fleeing();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int damageRoll() {
|
public int damageRoll() {
|
||||||
return Random.NormalIntRange( 12, 16 );
|
return Random.NormalIntRange(12, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void nowhereToRun() {
|
public int attackSkill(Char target) {
|
||||||
if (buff( Terror.class ) == null) {
|
|
||||||
state = State.HUNTING;
|
|
||||||
} else {
|
|
||||||
super.nowhereToRun();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int attackSkill( Char target ) {
|
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,30 +68,30 @@ public class Spinner extends Mob {
|
||||||
protected boolean act() {
|
protected boolean act() {
|
||||||
boolean result = super.act();
|
boolean result = super.act();
|
||||||
|
|
||||||
if (state == State.FLEEING && buff( Terror.class ) == null &&
|
if (state == FLEEING && buff(Terror.class) == null &&
|
||||||
enemySeen && enemy.buff( Poison.class ) == null) {
|
enemySeen && enemy.buff(Poison.class) == null) {
|
||||||
|
|
||||||
state = State.HUNTING;
|
state = HUNTING;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int attackProc( Char enemy, int damage ) {
|
public int attackProc(Char enemy, int damage) {
|
||||||
if (Random.Int( 2 ) == 0) {
|
if (Random.Int(2) == 0) {
|
||||||
Buff.affect( enemy, Poison.class ).set( Random.Int( 5, 7 ) * Poison.durationFactor( enemy ) );
|
Buff.affect(enemy, Poison.class).set(Random.Int(7, 9) * Poison.durationFactor(enemy));
|
||||||
state = State.FLEEING;
|
state = FLEEING;
|
||||||
}
|
}
|
||||||
|
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void move( int step ) {
|
public void move(int step) {
|
||||||
if (state == State.FLEEING) {
|
if (state == FLEEING) {
|
||||||
GameScene.add( Blob.seed( pos, Random.Int( 5, 7 ), Web.class ) );
|
GameScene.add(Blob.seed(pos, Random.Int(5, 7), Web.class));
|
||||||
}
|
}
|
||||||
super.move( step );
|
super.move(step);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -109,8 +102,9 @@ public class Spinner extends Mob {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final HashSet<Class<?>> RESISTANCES = new HashSet<Class<?>>();
|
private static final HashSet<Class<?>> RESISTANCES = new HashSet<Class<?>>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
RESISTANCES.add( Poison.class );
|
RESISTANCES.add(Poison.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -119,12 +113,24 @@ public class Spinner extends Mob {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final HashSet<Class<?>> IMMUNITIES = new HashSet<Class<?>>();
|
private static final HashSet<Class<?>> IMMUNITIES = new HashSet<Class<?>>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
IMMUNITIES.add( Roots.class );
|
IMMUNITIES.add(Roots.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HashSet<Class<?>> immunities() {
|
public HashSet<Class<?>> immunities() {
|
||||||
return IMMUNITIES;
|
return IMMUNITIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class Fleeing extends Mob.Fleeing {
|
||||||
|
@Override
|
||||||
|
protected void nowhereToRun() {
|
||||||
|
if (buff(Terror.class) == null) {
|
||||||
|
state = HUNTING;
|
||||||
|
} else {
|
||||||
|
super.nowhereToRun();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class Statue extends Mob {
|
||||||
spriteClass = StatueSprite.class;
|
spriteClass = StatueSprite.class;
|
||||||
|
|
||||||
EXP = 0;
|
EXP = 0;
|
||||||
state = State.PASSIVE;
|
state = PASSIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Weapon weapon;
|
private Weapon weapon;
|
||||||
|
@ -106,8 +106,8 @@ public class Statue extends Mob {
|
||||||
@Override
|
@Override
|
||||||
public void damage( int dmg, Object src ) {
|
public void damage( int dmg, Object src ) {
|
||||||
|
|
||||||
if (state == State.PASSIVE) {
|
if (state == PASSIVE) {
|
||||||
state = State.HUNTING;
|
state = HUNTING;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.damage( dmg, src );
|
super.damage( dmg, src );
|
||||||
|
@ -137,7 +137,7 @@ public class Statue extends Mob {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean reset() {
|
public boolean reset() {
|
||||||
state = State.PASSIVE;
|
state = PASSIVE;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ public class Swarm extends Mob {
|
||||||
Swarm clone = split();
|
Swarm clone = split();
|
||||||
clone.HP = (HP - damage) / 2;
|
clone.HP = (HP - damage) / 2;
|
||||||
clone.pos = Random.element( candidates );
|
clone.pos = Random.element( candidates );
|
||||||
clone.state = State.HUNTING;
|
clone.state = clone.HUNTING;
|
||||||
|
|
||||||
if (Dungeon.level.map[clone.pos] == Terrain.DOOR) {
|
if (Dungeon.level.map[clone.pos] == Terrain.DOOR) {
|
||||||
Door.enter( clone.pos );
|
Door.enter( clone.pos );
|
||||||
|
|
|
@ -50,6 +50,8 @@ public class Thief extends Mob {
|
||||||
|
|
||||||
loot = MasterThievesArmband.class;
|
loot = MasterThievesArmband.class;
|
||||||
lootChance = 0.01f;
|
lootChance = 0.01f;
|
||||||
|
|
||||||
|
FLEEING = new Fleeing();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String ITEM = "item";
|
private static final String ITEM = "item";
|
||||||
|
@ -76,16 +78,6 @@ public class Thief extends Mob {
|
||||||
return 0.5f;
|
return 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void nowhereToRun() {
|
|
||||||
if (buff( Terror.class ) == null) {
|
|
||||||
sprite.showStatus( CharSprite.NEGATIVE, TXT_RAGE );
|
|
||||||
state = State.HUNTING;
|
|
||||||
} else {
|
|
||||||
super.nowhereToRun();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void die( Object cause ) {
|
public void die( Object cause ) {
|
||||||
|
|
||||||
|
@ -109,7 +101,7 @@ public class Thief extends Mob {
|
||||||
@Override
|
@Override
|
||||||
public int attackProc( Char enemy, int damage ) {
|
public int attackProc( Char enemy, int damage ) {
|
||||||
if (item == null && enemy instanceof Hero && steal( (Hero)enemy )) {
|
if (item == null && enemy instanceof Hero && steal( (Hero)enemy )) {
|
||||||
state = State.FLEEING;
|
state = FLEEING;
|
||||||
}
|
}
|
||||||
|
|
||||||
return damage;
|
return damage;
|
||||||
|
@ -117,7 +109,7 @@ public class Thief extends Mob {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int defenseProc(Char enemy, int damage) {
|
public int defenseProc(Char enemy, int damage) {
|
||||||
if (state == State.FLEEING) {
|
if (state == FLEEING) {
|
||||||
Dungeon.level.drop( new Gold(), pos ).sprite.drop();
|
Dungeon.level.drop( new Gold(), pos ).sprite.drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,4 +145,16 @@ public class Thief extends Mob {
|
||||||
|
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class Fleeing extends Mob.Fleeing {
|
||||||
|
@Override
|
||||||
|
protected void nowhereToRun() {
|
||||||
|
if (buff( Terror.class ) == null) {
|
||||||
|
sprite.showStatus( CharSprite.NEGATIVE, TXT_RAGE );
|
||||||
|
state = HUNTING;
|
||||||
|
} else {
|
||||||
|
super.nowhereToRun();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ public class Wraith extends Mob {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean reset() {
|
public boolean reset() {
|
||||||
state = State.WANDERING;
|
state = WANDERING;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ public class Wraith extends Mob {
|
||||||
Wraith w = new Wraith();
|
Wraith w = new Wraith();
|
||||||
w.adjustStats( Dungeon.depth );
|
w.adjustStats( Dungeon.depth );
|
||||||
w.pos = pos;
|
w.pos = pos;
|
||||||
w.state = State.HUNTING;
|
w.state = w.HUNTING;
|
||||||
GameScene.add( w, SPAWN_DELAY );
|
GameScene.add( w, SPAWN_DELAY );
|
||||||
|
|
||||||
w.sprite.alpha( 0 );
|
w.sprite.alpha( 0 );
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class Yog extends Mob {
|
||||||
|
|
||||||
EXP = 50;
|
EXP = 50;
|
||||||
|
|
||||||
state = State.PASSIVE;
|
state = PASSIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String TXT_DESC =
|
private static final String TXT_DESC =
|
||||||
|
@ -193,7 +193,7 @@ public class Yog extends Mob {
|
||||||
|
|
||||||
EXP = 0;
|
EXP = 0;
|
||||||
|
|
||||||
state = State.WANDERING;
|
state = WANDERING;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RottingFist() {
|
public RottingFist() {
|
||||||
|
@ -286,7 +286,7 @@ public class Yog extends Mob {
|
||||||
|
|
||||||
EXP = 0;
|
EXP = 0;
|
||||||
|
|
||||||
state = State.WANDERING;
|
state = WANDERING;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BurningFist() {
|
public BurningFist() {
|
||||||
|
@ -404,7 +404,7 @@ public class Yog extends Mob {
|
||||||
|
|
||||||
EXP = 0;
|
EXP = 0;
|
||||||
|
|
||||||
state = State.HUNTING;
|
state = HUNTING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -43,7 +43,7 @@ import com.shatteredpixel.shatteredpixeldungeon.windows.WndQuest;
|
||||||
import com.watabou.utils.Bundle;
|
import com.watabou.utils.Bundle;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
public class Blacksmith extends Mob.NPC {
|
public class Blacksmith extends NPC {
|
||||||
|
|
||||||
private static final String TXT_GOLD_1 =
|
private static final String TXT_GOLD_1 =
|
||||||
"Hey human! Wanna be useful, eh? Take dis pickaxe and mine me some _dark gold ore_, _15 pieces_ should be enough. " +
|
"Hey human! Wanna be useful, eh? Take dis pickaxe and mine me some _dark gold ore_, _15 pieces_ should be enough. " +
|
||||||
|
@ -168,7 +168,7 @@ public class Blacksmith extends Mob.NPC {
|
||||||
return "Select 2 different items, not the same item twice!";
|
return "Select 2 different items, not the same item twice!";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item1.isSimilar( item2 )) {
|
if (item1.getClass() != item2.getClass()) {
|
||||||
return "Select 2 items of the same type!";
|
return "Select 2 items of the same type!";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Fire;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Fire;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.StenchGas;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.StenchGas;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
|
||||||
|
@ -27,6 +28,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Poison;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Crab;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Crab;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Gnoll;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Gnoll;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Rat;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Rat;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClothArmor;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.food.MysteryMeat;
|
import com.shatteredpixel.shatteredpixeldungeon.items.food.MysteryMeat;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.quest.RatSkull;
|
import com.shatteredpixel.shatteredpixeldungeon.items.quest.RatSkull;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
|
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
|
||||||
|
@ -61,7 +63,7 @@ import com.shatteredpixel.shatteredpixeldungeon.windows.WndSadGhost;
|
||||||
import com.watabou.utils.Bundle;
|
import com.watabou.utils.Bundle;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
public class Ghost extends Mob.NPC {
|
public class Ghost extends NPC {
|
||||||
|
|
||||||
{
|
{
|
||||||
name = "sad ghost";
|
name = "sad ghost";
|
||||||
|
@ -69,7 +71,7 @@ public class Ghost extends Mob.NPC {
|
||||||
|
|
||||||
flying = true;
|
flying = true;
|
||||||
|
|
||||||
state = State.WANDERING;
|
state = WANDERING;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String TXT_RAT1 =
|
private static final String TXT_RAT1 =
|
||||||
|
@ -195,7 +197,6 @@ public class Ghost extends Mob.NPC {
|
||||||
txt_quest = TXT_CRAB1; break;
|
txt_quest = TXT_CRAB1; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
questBoss.state = Mob.State.WANDERING;
|
|
||||||
questBoss.pos = Dungeon.level.randomRespawnCell();
|
questBoss.pos = Dungeon.level.randomRespawnCell();
|
||||||
|
|
||||||
if (questBoss.pos != -1) {
|
if (questBoss.pos != -1) {
|
||||||
|
@ -353,6 +354,10 @@ public class Ghost extends Mob.NPC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO this is silly, why trap the player with bad armour? Just remove the button from the window.
|
||||||
|
if (Dungeon.isChallenged( Challenges.NO_ARMOR ))
|
||||||
|
armor = (Armor)new ClothArmor().degrade();
|
||||||
|
|
||||||
weapon.identify();
|
weapon.identify();
|
||||||
armor.identify();
|
armor.identify();
|
||||||
}
|
}
|
||||||
|
@ -386,6 +391,8 @@ public class Ghost extends Mob.NPC {
|
||||||
defenseSkill = 4;
|
defenseSkill = 4;
|
||||||
|
|
||||||
EXP = 4;
|
EXP = 4;
|
||||||
|
|
||||||
|
state = WANDERING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -445,6 +452,8 @@ public class Ghost extends Mob.NPC {
|
||||||
|
|
||||||
EXP = 5;
|
EXP = 5;
|
||||||
|
|
||||||
|
state = WANDERING;
|
||||||
|
|
||||||
loot = Generator.random(CurareDart.class);
|
loot = Generator.random(CurareDart.class);
|
||||||
lootChance = 1f;
|
lootChance = 1f;
|
||||||
}
|
}
|
||||||
|
@ -489,7 +498,7 @@ public class Ghost extends Mob.NPC {
|
||||||
@Override
|
@Override
|
||||||
protected boolean getCloser( int target ) {
|
protected boolean getCloser( int target ) {
|
||||||
combo = 0; //if he's moving, he isn't attacking, reset combo.
|
combo = 0; //if he's moving, he isn't attacking, reset combo.
|
||||||
if (state == State.HUNTING) {
|
if (state == HUNTING) {
|
||||||
return enemySeen && getFurther( target );
|
return enemySeen && getFurther( target );
|
||||||
} else {
|
} else {
|
||||||
return super.getCloser( target );
|
return super.getCloser( target );
|
||||||
|
@ -573,6 +582,7 @@ public class Ghost extends Mob.NPC {
|
||||||
|
|
||||||
EXP = 6;
|
EXP = 6;
|
||||||
|
|
||||||
|
state = WANDERING;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean moving = true;
|
private boolean moving = true;
|
||||||
|
|
|
@ -38,7 +38,7 @@ import com.shatteredpixel.shatteredpixeldungeon.windows.WndQuest;
|
||||||
import com.watabou.utils.Bundle;
|
import com.watabou.utils.Bundle;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
public class Imp extends Mob.NPC {
|
public class Imp extends NPC {
|
||||||
|
|
||||||
{
|
{
|
||||||
name = "ambitious imp";
|
name = "ambitious imp";
|
||||||
|
|
|
@ -21,6 +21,8 @@ import java.util.HashSet;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||||
|
@ -29,13 +31,13 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.MirrorSprite;
|
||||||
import com.watabou.utils.Bundle;
|
import com.watabou.utils.Bundle;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
public class MirrorImage extends Mob.NPC {
|
public class MirrorImage extends NPC {
|
||||||
|
|
||||||
{
|
{
|
||||||
name = "mirror image";
|
name = "mirror image";
|
||||||
spriteClass = MirrorSprite.class;
|
spriteClass = MirrorSprite.class;
|
||||||
|
|
||||||
state = State.HUNTING;
|
state = HUNTING;
|
||||||
|
|
||||||
enemy = DUMMY;
|
enemy = DUMMY;
|
||||||
}
|
}
|
||||||
|
@ -135,4 +137,15 @@ public class MirrorImage extends Mob.NPC {
|
||||||
Dungeon.hero.spend( 1 / Dungeon.hero.speed() );
|
Dungeon.hero.spend( 1 / Dungeon.hero.speed() );
|
||||||
Dungeon.hero.busy();
|
Dungeon.hero.busy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final HashSet<Class<?>> IMMUNITIES = new HashSet<Class<?>>();
|
||||||
|
static {
|
||||||
|
IMMUNITIES.add( ToxicGas.class );
|
||||||
|
IMMUNITIES.add( Burning.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HashSet<Class<?>> immunities() {
|
||||||
|
return IMMUNITIES;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Pixel Dungeon
|
||||||
|
* Copyright (C) 2012-2014 Oleg Dolya
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||||
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
|
public abstract class NPC extends Mob {
|
||||||
|
|
||||||
|
{
|
||||||
|
HP = HT = 1;
|
||||||
|
EXP = 0;
|
||||||
|
|
||||||
|
hostile = false;
|
||||||
|
state = PASSIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void throwItem() {
|
||||||
|
Heap heap = Dungeon.level.heaps.get( pos );
|
||||||
|
if (heap != null) {
|
||||||
|
int n;
|
||||||
|
do {
|
||||||
|
n = pos + Level.NEIGHBOURS8[Random.Int( 8 )];
|
||||||
|
} while (!Level.passable[n] && !Level.avoid[n]);
|
||||||
|
Dungeon.level.drop( heap.pickUp(), n ).sprite.drop( pos );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beckon( int cell ) {
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public void interact();
|
||||||
|
}
|
|
@ -24,13 +24,13 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.RatKingSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.RatKingSprite;
|
||||||
|
|
||||||
public class RatKing extends Mob.NPC {
|
public class RatKing extends NPC {
|
||||||
|
|
||||||
{
|
{
|
||||||
name = "rat king";
|
name = "rat king";
|
||||||
spriteClass = RatKingSprite.class;
|
spriteClass = RatKingSprite.class;
|
||||||
|
|
||||||
state = State.SLEEPING;
|
state = SLEEPEING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -64,10 +64,10 @@ public class RatKing extends Mob.NPC {
|
||||||
@Override
|
@Override
|
||||||
public void interact() {
|
public void interact() {
|
||||||
sprite.turnTo( pos, Dungeon.hero.pos );
|
sprite.turnTo( pos, Dungeon.hero.pos );
|
||||||
if (state == State.SLEEPING) {
|
if (state == SLEEPEING) {
|
||||||
notice();
|
notice();
|
||||||
yell( "I'm not sleeping!" );
|
yell( "I'm not sleeping!" );
|
||||||
state = State.WANDERING;
|
state = WANDERING;
|
||||||
} else {
|
} else {
|
||||||
yell( "What is it? I have no time for this nonsense. My kingdom won't rule itself!" );
|
yell( "What is it? I have no time for this nonsense. My kingdom won't rule itself!" );
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.ShopkeeperSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
|
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTradeItem;
|
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTradeItem;
|
||||||
|
|
||||||
public class Shopkeeper extends Mob.NPC {
|
public class Shopkeeper extends NPC {
|
||||||
|
|
||||||
public static final String TXT_THIEF = "Thief, Thief!";
|
public static final String TXT_THIEF = "Thief, Thief!";
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ import com.shatteredpixel.shatteredpixeldungeon.windows.WndWandmaker;
|
||||||
import com.watabou.utils.Bundle;
|
import com.watabou.utils.Bundle;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
public class Wandmaker extends Mob.NPC {
|
public class Wandmaker extends NPC {
|
||||||
|
|
||||||
{
|
{
|
||||||
name = "old wandmaker";
|
name = "old wandmaker";
|
||||||
|
|
Loading…
Reference in New Issue
Block a user