v0.8.0: implement DM-200s (with a WIP sprite)
This commit is contained in:
parent
fbb62337fe
commit
259b5b03c4
|
@ -112,14 +112,16 @@ public class Bestiary {
|
||||||
Bat.class,
|
Bat.class,
|
||||||
Brute.class, Brute.class,
|
Brute.class, Brute.class,
|
||||||
Shaman.random(), Shaman.random(),
|
Shaman.random(), Shaman.random(),
|
||||||
Spinner.class, Spinner.class));
|
Spinner.class, Spinner.class,
|
||||||
|
DM200.class));
|
||||||
case 14: case 15:
|
case 14: case 15:
|
||||||
//1x bat, 1x brute, 2x shaman, 2x spinner, 2x DM-300
|
//1x bat, 1x brute, 2x shaman, 2x spinner, 2x DM-300
|
||||||
return new ArrayList<>(Arrays.asList(
|
return new ArrayList<>(Arrays.asList(
|
||||||
Bat.class,
|
Bat.class,
|
||||||
Brute.class,
|
Brute.class,
|
||||||
Shaman.random(), Shaman.random(),
|
Shaman.random(), Shaman.random(),
|
||||||
Spinner.class, Spinner.class));
|
Spinner.class, Spinner.class,
|
||||||
|
DM200.class, DM200.class));
|
||||||
|
|
||||||
// City
|
// City
|
||||||
case 16:
|
case 16:
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
/*
|
||||||
|
* 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.actors.Char;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.DM200Sprite;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||||
|
import com.watabou.utils.Bundle;
|
||||||
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
|
public class DM200 extends Mob {
|
||||||
|
|
||||||
|
{
|
||||||
|
spriteClass = DM200Sprite.class;
|
||||||
|
|
||||||
|
HP = HT = 80;
|
||||||
|
defenseSkill = 8;
|
||||||
|
|
||||||
|
EXP = 9;
|
||||||
|
maxLvl = 17;
|
||||||
|
|
||||||
|
//TODO loot?
|
||||||
|
|
||||||
|
properties.add(Property.INORGANIC);
|
||||||
|
properties.add(Property.LARGE);
|
||||||
|
|
||||||
|
HUNTING = new Hunting();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int damageRoll() {
|
||||||
|
return Random.NormalIntRange( 10, 30 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int attackSkill( Char target ) {
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int drRoll() {
|
||||||
|
return Random.NormalIntRange(0, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int ventCooldown = 0;
|
||||||
|
|
||||||
|
private static final String VENT_COOLDOWN = "vent_cooldown";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeInBundle(Bundle bundle) {
|
||||||
|
super.storeInBundle(bundle);
|
||||||
|
bundle.put(VENT_COOLDOWN, ventCooldown);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreFromBundle(Bundle bundle) {
|
||||||
|
super.restoreFromBundle(bundle);
|
||||||
|
ventCooldown = bundle.getInt( VENT_COOLDOWN );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean act() {
|
||||||
|
ventCooldown--;
|
||||||
|
return super.act();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onZapComplete(){
|
||||||
|
zap();
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void zap( ){
|
||||||
|
spend( TICK );
|
||||||
|
ventCooldown = 30;
|
||||||
|
|
||||||
|
Ballistica trajectory = new Ballistica(pos, enemy.pos, Ballistica.STOP_TARGET);
|
||||||
|
|
||||||
|
for (int i : trajectory.subPath(0, trajectory.dist)){
|
||||||
|
GameScene.add(Blob.seed(i, 20, ToxicGas.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
GLog.w(Messages.get(this, "vent"));
|
||||||
|
GameScene.add(Blob.seed(trajectory.collisionPos, 100, ToxicGas.class));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Hunting extends Mob.Hunting{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean act(boolean enemyInFOV, boolean justAlerted) {
|
||||||
|
if (!enemyInFOV || canAttack(enemy)) {
|
||||||
|
return super.act(enemyInFOV, justAlerted);
|
||||||
|
} else {
|
||||||
|
enemySeen = true;
|
||||||
|
target = enemy.pos;
|
||||||
|
|
||||||
|
int oldPos = pos;
|
||||||
|
|
||||||
|
if (ventCooldown <= 0 && Random.Int(100/distance(enemy)) == 0){
|
||||||
|
if (sprite != null && (sprite.visible || enemy.sprite.visible)) {
|
||||||
|
sprite.zap( enemy.pos );
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
zap();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (getCloser( target )) {
|
||||||
|
spend( 1 / speed() );
|
||||||
|
return moveSprite( oldPos, pos );
|
||||||
|
|
||||||
|
} else if (ventCooldown <= 0) {
|
||||||
|
if (sprite != null && (sprite.visible || enemy.sprite.visible)) {
|
||||||
|
sprite.zap( enemy.pos );
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
zap();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
spend( TICK );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -66,6 +66,7 @@ public class MagicMissile extends Emitter {
|
||||||
public static final int SHAMAN_RED = 11;
|
public static final int SHAMAN_RED = 11;
|
||||||
public static final int SHAMAN_BLUE = 12;
|
public static final int SHAMAN_BLUE = 12;
|
||||||
public static final int SHAMAN_PURPLE = 13;
|
public static final int SHAMAN_PURPLE = 13;
|
||||||
|
public static final int TOXIC_VENT = 14;
|
||||||
|
|
||||||
public static final int FIRE_CONE = 100;
|
public static final int FIRE_CONE = 100;
|
||||||
public static final int FOLIAGE_CONE = 101;
|
public static final int FOLIAGE_CONE = 101;
|
||||||
|
@ -162,6 +163,10 @@ public class MagicMissile extends Emitter {
|
||||||
size( 2 );
|
size( 2 );
|
||||||
pour( ShamanParticle.PURPLE, 0.01f );
|
pour( ShamanParticle.PURPLE, 0.01f );
|
||||||
break;
|
break;
|
||||||
|
case TOXIC_VENT:
|
||||||
|
size( 10 );
|
||||||
|
pour( Speck.factory(Speck.TOXIC), 0.02f );
|
||||||
|
break;
|
||||||
|
|
||||||
case FIRE_CONE:
|
case FIRE_CONE:
|
||||||
size( 10 );
|
size( 10 );
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* 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.sprites;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM200;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Shaman;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
|
||||||
|
import com.watabou.noosa.TextureFilm;
|
||||||
|
import com.watabou.noosa.audio.Sample;
|
||||||
|
import com.watabou.utils.Callback;
|
||||||
|
|
||||||
|
//TODO currently just uses DM-300's sprite scaled to 80%
|
||||||
|
public class DM200Sprite extends MobSprite {
|
||||||
|
|
||||||
|
public DM200Sprite () {
|
||||||
|
super();
|
||||||
|
|
||||||
|
texture( Assets.DM300 );
|
||||||
|
|
||||||
|
TextureFilm frames = new TextureFilm( texture, 22, 20 );
|
||||||
|
|
||||||
|
idle = new Animation( 10, true );
|
||||||
|
idle.frames( frames, 0, 1 );
|
||||||
|
|
||||||
|
run = new Animation( 10, true );
|
||||||
|
run.frames( frames, 2, 3 );
|
||||||
|
|
||||||
|
attack = new Animation( 15, false );
|
||||||
|
attack.frames( frames, 4, 5, 6, 0 );
|
||||||
|
|
||||||
|
zap = attack.clone();
|
||||||
|
|
||||||
|
die = new Animation( 20, false );
|
||||||
|
die.frames( frames, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 8 );
|
||||||
|
|
||||||
|
play( idle );
|
||||||
|
scale.set( 0.8f );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void zap( int cell ) {
|
||||||
|
|
||||||
|
turnTo( ch.pos , cell );
|
||||||
|
play( zap );
|
||||||
|
|
||||||
|
MagicMissile.boltFromChar( parent,
|
||||||
|
MagicMissile.TOXIC_VENT,
|
||||||
|
this,
|
||||||
|
cell,
|
||||||
|
new Callback() {
|
||||||
|
@Override
|
||||||
|
public void call() {
|
||||||
|
((DM200)ch).onZapComplete();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
Sample.INSTANCE.play( Assets.SND_PUFF );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -485,6 +485,10 @@ actors.mobs.dm100.name=DM-100
|
||||||
actors.mobs.dm100.zap_kill=The lightning bolt killed you...
|
actors.mobs.dm100.zap_kill=The lightning bolt killed you...
|
||||||
actors.mobs.dm100.desc=The DM-100 is an early model of dwarven 'defense machine' which was designed to protect dwarven miners in the caves below. Their electrical shocks proved too weak however, and so they were gifted to the human prison above. The warden initially deemed them too cruel to use, but as the prisoners became more unruly they became a necessity.
|
actors.mobs.dm100.desc=The DM-100 is an early model of dwarven 'defense machine' which was designed to protect dwarven miners in the caves below. Their electrical shocks proved too weak however, and so they were gifted to the human prison above. The warden initially deemed them too cruel to use, but as the prisoners became more unruly they became a necessity.
|
||||||
|
|
||||||
|
actors.mobs.dm200.name=DM-200
|
||||||
|
actors.mobs.dm200.vent=The DM-200 fires a toxic jet of exhaust at you!
|
||||||
|
actors.mobs.dm200.desc=The DM-200 is the second generation of dwarven 'defense machine', which was designed to protect dwarven miners in the caves and city below. They are much larger and bulkier than their predecessors, and attack with devastating hydraulic fists.\n\nTheir increased size is also their primary weakness, as they are unable to fit into the narrow tunnels and doorways of the dungeon. The dwarves were able to compensate for the DM-200's lack of mobility by allowing them to vent their toxic exhaust fumes at distant enemies, or enemies they cannot reach.
|
||||||
|
|
||||||
actors.mobs.dm300.name=DM-300
|
actors.mobs.dm300.name=DM-300
|
||||||
actors.mobs.dm300.notice=Unauthorised personnel detected.
|
actors.mobs.dm300.notice=Unauthorised personnel detected.
|
||||||
actors.mobs.dm300.defeated=Mission failed. Shutting down.
|
actors.mobs.dm300.defeated=Mission failed. Shutting down.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user