v0.8.0: added in a basic implementation for rare mimics

This commit is contained in:
Evan Debenham 2019-12-09 15:22:32 -05:00
parent 208a954dc0
commit d96351c682
7 changed files with 230 additions and 23 deletions

View File

@ -0,0 +1,87 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2019 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.Artifact;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.MimicSprite;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
public class CrystalMimic extends Mimic {
{
spriteClass = MimicSprite.Crystal.class;
}
@Override
public String name() {
if (alignment == Alignment.NEUTRAL){
return Messages.get(Heap.class, "crystal_chest");
} else {
return super.name();
}
}
@Override
public String description() {
if (alignment == Alignment.NEUTRAL){
//TODO variable based on contents
for (Item i : items){
if (i instanceof Artifact){
return Messages.get(Heap.class, "crystal_chest_desc", Messages.get(Heap.class, "artifact"));
} else if (i instanceof Ring){
return Messages.get(Heap.class, "crystal_chest_desc", Messages.get(Heap.class, "ring"));
} else if (i instanceof Wand){
return Messages.get(Heap.class, "crystal_chest_desc", Messages.get(Heap.class, "wand"));
}
}
return Messages.get(Heap.class, "locked_chest_desc");
} else {
return super.description();
}
}
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, 1, 1.25f);
}
}
//TODO different AI
}

View File

@ -0,0 +1,76 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2019 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.MimicSprite;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
//TODO should enhance the reward from these a bit, as they are much harder
public class GoldenMimic extends Mimic {
{
spriteClass = MimicSprite.Golden.class;
}
@Override
public String name() {
if (alignment == Alignment.NEUTRAL){
return Messages.get(Heap.class, "locked_chest");
} else {
return super.name();
}
}
@Override
public String description() {
if (alignment == Alignment.NEUTRAL){
return Messages.get(Heap.class, "locked_chest_desc");
} else {
return super.description();
}
}
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, 1, 0.85f);
}
}
@Override
public void adjustStats(int level) {
super.adjustStats((int)Math.ceil(level*1.5f));
}
}

View File

@ -219,12 +219,28 @@ public class Mimic extends Mob {
}
public static Mimic spawnAt( int pos, Item item ){
return spawnAt( pos, Arrays.asList(item));
return spawnAt( pos, Arrays.asList(item), Mimic.class);
}
public static Mimic spawnAt( int pos, Item item, Class mimicType ){
return spawnAt( pos, Arrays.asList(item), mimicType);
}
public static Mimic spawnAt( int pos, List<Item> items ) {
return spawnAt( pos, items, Mimic.class);
}
public static Mimic spawnAt( int pos, List<Item> items, Class mimicType ) {
Mimic m;
if (mimicType == GoldenMimic.class){
m = new GoldenMimic();
} else if (mimicType == CrystalMimic.class) {
m = new CrystalMimic();
} else {
m = new Mimic();
}
Mimic m = new Mimic();
m.items = new ArrayList<>( items );
m.adjustStats( Dungeon.depth );
m.pos = pos;

View File

@ -37,8 +37,8 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Recharging;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.GoldenMimic;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Sheep;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
@ -366,23 +366,22 @@ public class CursedWand {
afterZap.call();
break;
//superpowered mimic
//golden mimic
case 1:
cursedFX(user, bolt, new Callback() {
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>(), GoldenMimic.class);
if (mimic != null) {
mimic.stopHiding();
mimic.alignment = Char.Alignment.ENEMY;
mimic.adjustStats(Dungeon.depth + 10);
mimic.HP = mimic.HT;
Item reward;
do {
reward = Generator.random(Random.oneOf(Generator.Category.WEAPON, Generator.Category.ARMOR,
Generator.Category.RING, Generator.Category.WAND));
} while (reward.level() < 1);
Sample.INSTANCE.play(Assets.SND_MIMIC, 1, 1, 0.5f);
//play vfx/sfx manually as mimic isn't in the scene yet
Sample.INSTANCE.play(Assets.SND_MIMIC, 1, 0.85f);
CellEmitter.get(mimic.pos).burst(Speck.factory(Speck.STAR), 10);
mimic.items.clear();
mimic.items.add(reward);
GameScene.add(mimic);

View File

@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels;
import com.shatteredpixel.shatteredpixeldungeon.Bones;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.GoldenMimic;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
@ -306,18 +307,20 @@ public abstract class RegularLevel extends Level {
}
type = Heap.Type.CHEST;
break;
default:
type = Heap.Type.HEAP;
}
//TODO gold mimics
if ((toDrop instanceof Artifact && Random.Int(2) == 0) ||
(toDrop.isUpgradable() && Random.Int(4 - toDrop.level()) == 0)){
if (Random.Int(5) == 0 && findMob(cell) == null){
mobs.add(Mimic.spawnAt(cell, toDrop, GoldenMimic.class));
} else {
Heap dropped = drop(toDrop, cell);
if (heaps.get(cell) == dropped) {
dropped.type = Heap.Type.LOCKED_CHEST;
addItemToSpawn(new GoldenKey(Dungeon.depth));
}
}
} else {
Heap dropped = drop( toDrop, cell );
dropped.type = type;

View File

@ -23,6 +23,8 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CrystalMimic;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
@ -55,7 +57,11 @@ public class VaultRoom extends SpecialRoom {
i1 = prize( level );
i2 = prize( level );
level.drop( i1, c ).type = Heap.Type.CRYSTAL_CHEST;
if (Random.Int(10) == 0){
level.mobs.add(Mimic.spawnAt(c + PathFinder.NEIGHBOURS8[Random.Int(8)], i2, CrystalMimic.class));
} else {
level.drop(i2, c + PathFinder.NEIGHBOURS8[Random.Int(8)]).type = Heap.Type.CRYSTAL_CHEST;
}
level.addItemToSpawn( new CrystalKey( Dungeon.depth ) );
entrance().set( Door.Type.LOCKED );

View File

@ -29,27 +29,33 @@ public class MimicSprite extends MobSprite {
private Animation hiding;
protected int texOffset(){
return 0;
}
public MimicSprite() {
super();
int c = texOffset();
texture( Assets.MIMIC );
TextureFilm frames = new TextureFilm( texture, 16, 16 );
hiding = new Animation( 1, true );
hiding.frames( frames, 0, 0, 0, 0, 0, 0, 1);
hiding.frames( frames, 0+c, 0+c, 0+c, 0+c, 0+c, 0+c, 1+c);
idle = new Animation( 5, true );
idle.frames( frames, 2, 2, 2, 3, 3 );
idle.frames( frames, 2+c, 2+c, 2+c, 3+c, 3+c );
run = new Animation( 10, true );
run.frames( frames, 2, 3, 4, 5, 5, 4, 3 );
run.frames( frames, 2+c, 3+c, 4+c, 5+c, 5+c, 4+c, 3+c );
attack = new Animation( 10, false );
attack.frames( frames, 2, 6, 7, 8 );
attack.frames( frames, 2+c, 6+c, 7+c, 8+c );
die = new Animation( 5, false );
die.frames( frames, 9, 10, 11 );
die.frames( frames, 9+c, 10+c, 11+c );
play( idle );
}
@ -75,4 +81,18 @@ public class MimicSprite extends MobSprite {
super.showSleep();
}
public static class Golden extends MimicSprite{
@Override
protected int texOffset() {
return 16;
}
}
public static class Crystal extends MimicSprite{
@Override
protected int texOffset() {
return 32;
}
}
}