v0.8.0: reworked mimics:
- evasion reduced slightly - now have armor equal to depth/2 - damage increased by ~50% - no longer give exp (same as other floor-independent mobs) - now are visually different from chests, can be preemptively attacked - will inflict bonus damage to the hero if they try to open them.
This commit is contained in:
parent
13d17234ec
commit
0351ad6475
Binary file not shown.
Before Width: | Height: | Size: 751 B After Width: | Height: | Size: 2.9 KiB |
|
@ -31,17 +31,22 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Gold;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Gold;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRetribution;
|
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRetribution;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfPsionicBlast;
|
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfPsionicBlast;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.MimicSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.MimicSprite;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||||
import com.watabou.noosa.audio.Sample;
|
import com.watabou.noosa.audio.Sample;
|
||||||
import com.watabou.utils.Bundle;
|
import com.watabou.utils.Bundle;
|
||||||
import com.watabou.utils.PathFinder;
|
import com.watabou.utils.PathFinder;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -53,6 +58,12 @@ public class Mimic extends Mob {
|
||||||
spriteClass = MimicSprite.class;
|
spriteClass = MimicSprite.class;
|
||||||
|
|
||||||
properties.add(Property.DEMONIC);
|
properties.add(Property.DEMONIC);
|
||||||
|
|
||||||
|
EXP = 0;
|
||||||
|
|
||||||
|
//mimics are neutral when hidden
|
||||||
|
alignment = Alignment.NEUTRAL;
|
||||||
|
state = PASSIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Item> items;
|
public ArrayList<Item> items;
|
||||||
|
@ -75,24 +86,111 @@ public class Mimic extends Mob {
|
||||||
}
|
}
|
||||||
adjustStats( bundle.getInt( LEVEL ) );
|
adjustStats( bundle.getInt( LEVEL ) );
|
||||||
super.restoreFromBundle(bundle);
|
super.restoreFromBundle(bundle);
|
||||||
|
if (state != PASSIVE && alignment == Alignment.NEUTRAL){
|
||||||
|
alignment = Alignment.ENEMY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
if (alignment == Alignment.NEUTRAL){
|
||||||
|
return Messages.get(Heap.class, "chest");
|
||||||
|
} else {
|
||||||
|
return super.name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String description() {
|
||||||
|
if (alignment == Alignment.NEUTRAL){
|
||||||
|
return Messages.get(Heap.class, "chest_desc");
|
||||||
|
} else {
|
||||||
|
return super.description();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSprite sprite() {
|
||||||
|
MimicSprite sprite = (MimicSprite) super.sprite();
|
||||||
|
if (alignment == Alignment.NEUTRAL) sprite.hideMimic();
|
||||||
|
return sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean interact() {
|
||||||
|
if (alignment != Alignment.NEUTRAL){
|
||||||
|
return super.interact();
|
||||||
|
}
|
||||||
|
stopHiding();
|
||||||
|
doAttack(Dungeon.hero);
|
||||||
|
Dungeon.hero.busy();
|
||||||
|
Dungeon.hero.sprite.operate(pos);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttackComplete() {
|
||||||
|
super.onAttackComplete();
|
||||||
|
if (alignment == Alignment.NEUTRAL){
|
||||||
|
alignment = Alignment.ENEMY;
|
||||||
|
Dungeon.hero.spendAndNext(1f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void damage(int dmg, Object src) {
|
||||||
|
if (state == PASSIVE){
|
||||||
|
alignment = Alignment.ENEMY;
|
||||||
|
stopHiding();
|
||||||
|
}
|
||||||
|
super.damage(dmg, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopHiding(){
|
||||||
|
state = HUNTING;
|
||||||
|
if (Dungeon.level.heroFOV[pos] && Actor.chars().contains(this)) {
|
||||||
|
enemy = Dungeon.hero;
|
||||||
|
target = Dungeon.hero.pos;
|
||||||
|
enemySeen = true;
|
||||||
|
GLog.w(Messages.get(this, "reveal") );
|
||||||
|
CellEmitter.get(pos).burst(Speck.factory(Speck.STAR), 10);
|
||||||
|
Sample.INSTANCE.play(Assets.SND_MIMIC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int damageRoll() {
|
public int damageRoll() {
|
||||||
return Random.NormalIntRange( HT / 10, HT / 4 );
|
if (alignment == Alignment.NEUTRAL){
|
||||||
|
return Random.NormalIntRange( 2*level, 2 + 3*level);
|
||||||
|
} else {
|
||||||
|
return Random.NormalIntRange( 1 + level, 2 + 2*level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int drRoll() {
|
||||||
|
return Random.NormalIntRange(0, 1 + level/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beckon( int cell ) {
|
||||||
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int attackSkill( Char target ) {
|
public int attackSkill( Char target ) {
|
||||||
return 9 + level;
|
if (target != null && alignment == Alignment.NEUTRAL){
|
||||||
|
return INFINITE_ACCURACY;
|
||||||
|
} else {
|
||||||
|
return 9 + level;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void adjustStats( int level ) {
|
public void adjustStats( int level ) {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
|
|
||||||
HP = HT = (1 + level) * 6;
|
HP = HT = (1 + level) * 6;
|
||||||
EXP = 2 + 2 * (level - 1) / 5;
|
defenseSkill = 2 + level/2;
|
||||||
defenseSkill = attackSkill( null ) / 2;
|
|
||||||
|
|
||||||
enemySeen = true;
|
enemySeen = true;
|
||||||
}
|
}
|
||||||
|
@ -120,42 +218,16 @@ public class Mimic extends Mob {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Mimic spawnAt( int pos, Item item ){
|
||||||
|
return spawnAt( pos, Arrays.asList(item));
|
||||||
|
}
|
||||||
|
|
||||||
public static Mimic spawnAt( int pos, List<Item> items ) {
|
public static Mimic spawnAt( int pos, List<Item> items ) {
|
||||||
if (Dungeon.level.pit[pos]) return null;
|
|
||||||
Char ch = Actor.findChar( pos );
|
|
||||||
if (ch != null) {
|
|
||||||
ArrayList<Integer> candidates = new ArrayList<>();
|
|
||||||
for (int n : PathFinder.NEIGHBOURS8) {
|
|
||||||
int cell = pos + n;
|
|
||||||
if ((Dungeon.level.passable[cell] || Dungeon.level.avoid[cell]) && Actor.findChar( cell ) == null) {
|
|
||||||
candidates.add( cell );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (candidates.size() > 0) {
|
|
||||||
int newPos = Random.element( candidates );
|
|
||||||
Actor.addDelayed( new Pushing( ch, ch.pos, newPos ), -1 );
|
|
||||||
|
|
||||||
ch.pos = newPos;
|
|
||||||
Dungeon.level.occupyCell(ch );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Mimic m = new Mimic();
|
Mimic m = new Mimic();
|
||||||
m.items = new ArrayList<>( items );
|
m.items = new ArrayList<>( items );
|
||||||
m.adjustStats( Dungeon.depth );
|
m.adjustStats( Dungeon.depth );
|
||||||
m.pos = pos;
|
m.pos = pos;
|
||||||
m.state = m.HUNTING;
|
|
||||||
GameScene.add( m, 1 );
|
|
||||||
|
|
||||||
m.sprite.turnTo( pos, Dungeon.hero.pos );
|
|
||||||
|
|
||||||
if (Dungeon.level.heroFOV[m.pos]) {
|
|
||||||
CellEmitter.get( pos ).burst( Speck.factory( Speck.STAR ), 10 );
|
|
||||||
Sample.INSTANCE.play( Assets.SND_MIMIC );
|
|
||||||
}
|
|
||||||
|
|
||||||
//generate an extra reward for killing the mimic
|
//generate an extra reward for killing the mimic
|
||||||
Item reward = null;
|
Item reward = null;
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class Heap implements Bundlable {
|
||||||
TOMB,
|
TOMB,
|
||||||
SKELETON,
|
SKELETON,
|
||||||
REMAINS,
|
REMAINS,
|
||||||
MIMIC
|
MIMIC //remains for pre-0.8.0 compatibility. There are converted to mimics on level load
|
||||||
}
|
}
|
||||||
public Type type = Type.HEAP;
|
public Type type = Type.HEAP;
|
||||||
|
|
||||||
|
@ -87,11 +87,7 @@ public class Heap implements Bundlable {
|
||||||
public void open( Hero hero ) {
|
public void open( Hero hero ) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MIMIC:
|
case MIMIC:
|
||||||
if (Mimic.spawnAt(pos, items) != null) {
|
type = Type.CHEST;
|
||||||
destroy();
|
|
||||||
} else {
|
|
||||||
type = Type.CHEST;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case TOMB:
|
case TOMB:
|
||||||
Wraith.spawnAround( hero.pos );
|
Wraith.spawnAround( hero.pos );
|
||||||
|
@ -207,15 +203,6 @@ public class Heap implements Bundlable {
|
||||||
|
|
||||||
public void burn() {
|
public void burn() {
|
||||||
|
|
||||||
if (type == Type.MIMIC) {
|
|
||||||
Mimic m = Mimic.spawnAt( pos, items );
|
|
||||||
if (m != null) {
|
|
||||||
Buff.affect( m, Burning.class ).reignite( m );
|
|
||||||
m.sprite.emitter().burst( FlameParticle.FACTORY, 5 );
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type != Type.HEAP) {
|
if (type != Type.HEAP) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -285,7 +272,7 @@ public class Heap implements Bundlable {
|
||||||
for (Item item : items.toArray( new Item[0] )) {
|
for (Item item : items.toArray( new Item[0] )) {
|
||||||
|
|
||||||
if (item instanceof Potion) {
|
if (item instanceof Potion) {
|
||||||
items.remove( item );
|
items.remove(item);
|
||||||
((Potion) item).shatter(pos);
|
((Potion) item).shatter(pos);
|
||||||
|
|
||||||
} else if (item instanceof Bomb) {
|
} else if (item instanceof Bomb) {
|
||||||
|
@ -313,14 +300,6 @@ public class Heap implements Bundlable {
|
||||||
|
|
||||||
public void freeze() {
|
public void freeze() {
|
||||||
|
|
||||||
if (type == Type.MIMIC) {
|
|
||||||
Mimic m = Mimic.spawnAt( pos, items );
|
|
||||||
if (m != null) {
|
|
||||||
Buff.prolong( m, Frost.class, Frost.duration( m ) * Random.Float( 1.0f, 1.5f ) );
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type != Type.HEAP) {
|
if (type != Type.HEAP) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,16 +52,6 @@ public class Noisemaker extends Bomb {
|
||||||
mob.beckon( cell );
|
mob.beckon( cell );
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Heap heap : Dungeon.level.heaps.valueList()) {
|
|
||||||
if (heap.type == Heap.Type.MIMIC) {
|
|
||||||
Mimic m = Mimic.spawnAt( heap.pos, heap.items );
|
|
||||||
if (m != null) {
|
|
||||||
m.beckon( cell );
|
|
||||||
heap.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Trigger extends Buff {
|
public static class Trigger extends Buff {
|
||||||
|
|
|
@ -51,16 +51,6 @@ public class ScrollOfRage extends Scroll {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Heap heap : Dungeon.level.heaps.valueList()) {
|
|
||||||
if (heap.type == Heap.Type.MIMIC) {
|
|
||||||
Mimic m = Mimic.spawnAt( heap.pos, heap.items );
|
|
||||||
if (m != null) {
|
|
||||||
m.beckon( curUser.pos );
|
|
||||||
heap.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GLog.w( Messages.get(this, "roar") );
|
GLog.w( Messages.get(this, "roar") );
|
||||||
setKnown();
|
setKnown();
|
||||||
|
|
||||||
|
|
|
@ -370,8 +370,11 @@ public class CursedWand {
|
||||||
case 1:
|
case 1:
|
||||||
cursedFX(user, bolt, new Callback() {
|
cursedFX(user, bolt, new Callback() {
|
||||||
public void call() {
|
public void call() {
|
||||||
|
//TODO make this a gold mimic instead of boosting stats artificially
|
||||||
Mimic mimic = Mimic.spawnAt(bolt.collisionPos, new ArrayList<Item>());
|
Mimic mimic = Mimic.spawnAt(bolt.collisionPos, new ArrayList<Item>());
|
||||||
if (mimic != null) {
|
if (mimic != null) {
|
||||||
|
mimic.stopHiding();
|
||||||
|
mimic.alignment = Char.Alignment.ENEMY;
|
||||||
mimic.adjustStats(Dungeon.depth + 10);
|
mimic.adjustStats(Dungeon.depth + 10);
|
||||||
mimic.HP = mimic.HT;
|
mimic.HP = mimic.HT;
|
||||||
Item reward;
|
Item reward;
|
||||||
|
@ -382,6 +385,7 @@ public class CursedWand {
|
||||||
Sample.INSTANCE.play(Assets.SND_MIMIC, 1, 1, 0.5f);
|
Sample.INSTANCE.play(Assets.SND_MIMIC, 1, 1, 0.5f);
|
||||||
mimic.items.clear();
|
mimic.items.clear();
|
||||||
mimic.items.add(reward);
|
mimic.items.add(reward);
|
||||||
|
GameScene.add(mimic);
|
||||||
} else {
|
} else {
|
||||||
GLog.i(Messages.get(CursedWand.class, "nothing"));
|
GLog.i(Messages.get(CursedWand.class, "nothing"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bestiary;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bestiary;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Sheep;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Sheep;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlowParticle;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlowParticle;
|
||||||
|
@ -375,6 +376,14 @@ public abstract class Level implements Bundlable {
|
||||||
|
|
||||||
buildFlagMaps();
|
buildFlagMaps();
|
||||||
cleanWalls();
|
cleanWalls();
|
||||||
|
|
||||||
|
//compat with pre-0.8.0 saves
|
||||||
|
for (Heap h : heaps.valueList()){
|
||||||
|
if (h.type == Heap.Type.MIMIC){
|
||||||
|
heaps.remove(h.pos);
|
||||||
|
mobs.add(Mimic.spawnAt(h.pos, h.items));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Bones;
|
import com.shatteredpixel.shatteredpixeldungeon.Bones;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||||
|
@ -277,6 +278,16 @@ public abstract class RegularLevel extends Level {
|
||||||
int nItems = 3 + Random.chances(new float[]{6, 3, 1});
|
int nItems = 3 + Random.chances(new float[]{6, 3, 1});
|
||||||
|
|
||||||
for (int i=0; i < nItems; i++) {
|
for (int i=0; i < nItems; i++) {
|
||||||
|
|
||||||
|
Item toDrop = Generator.random();
|
||||||
|
if (toDrop == null) continue;
|
||||||
|
|
||||||
|
int cell = randomDropCell();
|
||||||
|
if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) {
|
||||||
|
map[cell] = Terrain.GRASS;
|
||||||
|
losBlocking[cell] = false;
|
||||||
|
}
|
||||||
|
|
||||||
Heap.Type type = null;
|
Heap.Type type = null;
|
||||||
switch (Random.Int( 20 )) {
|
switch (Random.Int( 20 )) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -289,21 +300,17 @@ public abstract class RegularLevel extends Level {
|
||||||
type = Heap.Type.CHEST;
|
type = Heap.Type.CHEST;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
type = Dungeon.depth > 1 ? Heap.Type.MIMIC : Heap.Type.CHEST;
|
if (Dungeon.depth > 1 && findMob(cell) == null){
|
||||||
|
mobs.add(Mimic.spawnAt(cell, toDrop));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
type = Heap.Type.CHEST;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
type = Heap.Type.HEAP;
|
type = Heap.Type.HEAP;
|
||||||
}
|
}
|
||||||
int cell = randomDropCell();
|
|
||||||
if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) {
|
|
||||||
map[cell] = Terrain.GRASS;
|
|
||||||
losBlocking[cell] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Item toDrop = Generator.random();
|
|
||||||
|
|
||||||
if (toDrop == null) continue;
|
|
||||||
|
|
||||||
|
//TODO gold mimics
|
||||||
if ((toDrop instanceof Artifact && Random.Int(2) == 0) ||
|
if ((toDrop instanceof Artifact && Random.Int(2) == 0) ||
|
||||||
(toDrop.isUpgradable() && Random.Int(4 - toDrop.level()) == 0)){
|
(toDrop.isUpgradable() && Random.Int(4 - toDrop.level()) == 0)){
|
||||||
Heap dropped = drop( toDrop, cell );
|
Heap dropped = drop( toDrop, cell );
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special;
|
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Gold;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Gold;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.keys.IronKey;
|
import com.shatteredpixel.shatteredpixeldungeon.items.keys.IronKey;
|
||||||
|
@ -47,7 +48,11 @@ public class TreasuryRoom extends SpecialRoom {
|
||||||
do {
|
do {
|
||||||
pos = level.pointToCell(random());
|
pos = level.pointToCell(random());
|
||||||
} while (level.map[pos] != Terrain.EMPTY || level.heaps.get( pos ) != null);
|
} while (level.map[pos] != Terrain.EMPTY || level.heaps.get( pos ) != null);
|
||||||
level.drop( new Gold().random(), pos ).type = (Random.Int(20) == 0 && heapType == Heap.Type.CHEST ? Heap.Type.MIMIC : heapType);
|
if (heapType == Heap.Type.CHEST && Random.Int(5 ) == 0){
|
||||||
|
level.mobs.add(Mimic.spawnAt(pos, new Gold().random()));
|
||||||
|
} else {
|
||||||
|
level.drop( new Gold().random(), pos ).type = heapType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (heapType == Heap.Type.HEAP) {
|
if (heapType == Heap.Type.HEAP) {
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard;
|
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Gold;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Gold;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
|
@ -56,7 +57,7 @@ public class SuspiciousChestRoom extends EmptyRoom {
|
||||||
Painter.set(level, center, Terrain.PEDESTAL);
|
Painter.set(level, center, Terrain.PEDESTAL);
|
||||||
|
|
||||||
if (Random.Int(3) == 0) {
|
if (Random.Int(3) == 0) {
|
||||||
level.drop(i, center).type = Heap.Type.MIMIC;
|
level.mobs.add(Mimic.spawnAt(center, i));
|
||||||
} else {
|
} else {
|
||||||
level.drop(i, center).type = Heap.Type.CHEST;
|
level.drop(i, center).type = Heap.Type.CHEST;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.traps;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Acidic;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Acidic;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Albino;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Albino;
|
||||||
|
@ -121,8 +122,10 @@ public class DistortionTrap extends Trap{
|
||||||
mob = new Piranha();
|
mob = new Piranha();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
Mimic.spawnAt(point, new ArrayList<>());
|
mob = Mimic.spawnAt(point, new ArrayList<>());
|
||||||
continue; //mimics spawn themselves, no need to do more
|
((Mimic)mob).stopHiding();
|
||||||
|
mob.alignment = Char.Alignment.ENEMY;
|
||||||
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
mob = Statue.random();
|
mob = Statue.random();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -22,10 +22,13 @@
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.sprites;
|
package com.shatteredpixel.shatteredpixeldungeon.sprites;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
import com.watabou.noosa.TextureFilm;
|
import com.watabou.noosa.TextureFilm;
|
||||||
|
|
||||||
public class MimicSprite extends MobSprite {
|
public class MimicSprite extends MobSprite {
|
||||||
|
|
||||||
|
private Animation hiding;
|
||||||
|
|
||||||
public MimicSprite() {
|
public MimicSprite() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
@ -33,23 +36,43 @@ public class MimicSprite extends MobSprite {
|
||||||
|
|
||||||
TextureFilm frames = new TextureFilm( texture, 16, 16 );
|
TextureFilm frames = new TextureFilm( texture, 16, 16 );
|
||||||
|
|
||||||
|
hiding = new Animation( 1, true );
|
||||||
|
hiding.frames( frames, 0, 0, 0, 0, 0, 0, 1);
|
||||||
|
|
||||||
idle = new Animation( 5, true );
|
idle = new Animation( 5, true );
|
||||||
idle.frames( frames, 0, 0, 0, 1, 1 );
|
idle.frames( frames, 2, 2, 2, 3, 3 );
|
||||||
|
|
||||||
run = new Animation( 10, true );
|
run = new Animation( 10, true );
|
||||||
run.frames( frames, 0, 1, 2, 3, 3, 2, 1 );
|
run.frames( frames, 2, 3, 4, 5, 5, 4, 3 );
|
||||||
|
|
||||||
attack = new Animation( 10, false );
|
attack = new Animation( 10, false );
|
||||||
attack.frames( frames, 0, 4, 5, 6 );
|
attack.frames( frames, 2, 6, 7, 8 );
|
||||||
|
|
||||||
die = new Animation( 5, false );
|
die = new Animation( 5, false );
|
||||||
die.frames( frames, 7, 8, 9 );
|
die.frames( frames, 9, 10, 11 );
|
||||||
|
|
||||||
play( idle );
|
play( idle );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int blood() {
|
public void linkVisuals(Char ch) {
|
||||||
return 0xFFcb9700;
|
super.linkVisuals(ch);
|
||||||
|
if (ch.alignment == Char.Alignment.NEUTRAL) {
|
||||||
|
hideMimic();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void hideMimic(){
|
||||||
|
play(hiding);
|
||||||
|
hideSleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void showSleep() {
|
||||||
|
if (curAnim == hiding){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.showSleep();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -553,7 +553,8 @@ actors.mobs.king$undead.rankings_desc=Fell Before the King of Dwarves
|
||||||
actors.mobs.king$undead.desc=These undead dwarves, risen by the will of the King of Dwarves, were members of his court. They appear as skeletons with a stunning amount of facial hair.
|
actors.mobs.king$undead.desc=These undead dwarves, risen by the will of the King of Dwarves, were members of his court. They appear as skeletons with a stunning amount of facial hair.
|
||||||
|
|
||||||
actors.mobs.mimic.name=mimic
|
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.mimic.reveal=That chest is a 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, in order to lure in unsuspecting adventurers. Mimics have a nasty bite, but often hold more treasure than a regular chest.
|
||||||
|
|
||||||
actors.mobs.necromancer.name=necromancer
|
actors.mobs.necromancer.name=necromancer
|
||||||
actors.mobs.necromancer.desc=These apprentice dark mages have flocked to the prison, as it is the perfect place to practise their evil craft.\n\nNecromancers will summon and empower skeletons to fight for them. Killing the necromancer will also kill the skeleton it summons.
|
actors.mobs.necromancer.desc=These apprentice dark mages have flocked to the prison, as it is the perfect place to practise their evil craft.\n\nNecromancers will summon and empower skeletons to fight for them. Killing the necromancer will also kill the skeleton it summons.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user