v0.7.5: added code for new Tengu abilities
This commit is contained in:
parent
5b8125a659
commit
f309f249e0
Binary file not shown.
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
@ -26,25 +26,49 @@ import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||||
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.Char;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Electricity;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Fire;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor;
|
||||||
|
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.BlobEmitter;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.FloatingText;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Lightning;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BlastParticle;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlameParticle;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SmokeParticle;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SparkParticle;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.TomeOfMastery;
|
import com.shatteredpixel.shatteredpixeldungeon.items.TomeOfMastery;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon;
|
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.bombs.Bomb;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.NewPrisonBossLevel;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.NewPrisonBossLevel;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
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.ItemSprite;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.TenguSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.TenguSprite;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.BossHealthBar;
|
import com.shatteredpixel.shatteredpixeldungeon.ui.BossHealthBar;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
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.PointF;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
//TODO currently has attack/defence stats for testing, need to add those
|
//TODO currently has attack/defence stats for testing, need to add those
|
||||||
public class NewTengu extends Mob {
|
public class NewTengu extends Mob {
|
||||||
|
|
||||||
|
@ -88,12 +112,7 @@ public class NewTengu extends Mob {
|
||||||
public void damage(int dmg, Object src) {
|
public void damage(int dmg, Object src) {
|
||||||
NewPrisonBossLevel.State state = ((NewPrisonBossLevel)Dungeon.level).state();
|
NewPrisonBossLevel.State state = ((NewPrisonBossLevel)Dungeon.level).state();
|
||||||
|
|
||||||
int hpBracket;
|
int hpBracket = 20;
|
||||||
if (state == NewPrisonBossLevel.State.FIGHT_START){
|
|
||||||
hpBracket = 20;
|
|
||||||
} else {
|
|
||||||
hpBracket = 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
int beforeHitHP = HP;
|
int beforeHitHP = HP;
|
||||||
super.damage(dmg, src);
|
super.damage(dmg, src);
|
||||||
|
@ -131,7 +150,7 @@ public class NewTengu extends Mob {
|
||||||
|
|
||||||
//phase 1 of the fight is over
|
//phase 1 of the fight is over
|
||||||
if (state == NewPrisonBossLevel.State.FIGHT_START && HP <= HT/2){
|
if (state == NewPrisonBossLevel.State.FIGHT_START && HP <= HT/2){
|
||||||
HP = (HT/2)-1;
|
HP = (HT/2);
|
||||||
yell(Messages.get(this, "interesting"));
|
yell(Messages.get(this, "interesting"));
|
||||||
((NewPrisonBossLevel)Dungeon.level).progress();
|
((NewPrisonBossLevel)Dungeon.level).progress();
|
||||||
BossHealthBar.bleed(true);
|
BossHealthBar.bleed(true);
|
||||||
|
@ -202,7 +221,7 @@ public class NewTengu extends Mob {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
newPos = ((NewPrisonBossLevel)Dungeon.level).randomTenguCellPos();
|
newPos = ((NewPrisonBossLevel)Dungeon.level).randomTenguCellPos();
|
||||||
} while ( (level.distance(newPos, enemy.pos) <= 2 || Actor.findChar(newPos) != null));
|
} while ( (level.distance(newPos, enemy.pos) < 3 || Actor.findChar(newPos) != null));
|
||||||
|
|
||||||
if (level.heroFOV[pos]) CellEmitter.get( pos ).burst( Speck.factory( Speck.WOOL ), 6 );
|
if (level.heroFOV[pos]) CellEmitter.get( pos ).burst( Speck.factory( Speck.WOOL ), 6 );
|
||||||
|
|
||||||
|
@ -217,15 +236,15 @@ public class NewTengu extends Mob {
|
||||||
float fill = 0.9f - 0.5f*((HP-80)/80f);
|
float fill = 0.9f - 0.5f*((HP-80)/80f);
|
||||||
level.placeTrapsInTenguCell(fill);
|
level.placeTrapsInTenguCell(fill);
|
||||||
|
|
||||||
return;
|
//otherwise, jump in a larger possible area, as the room is bigger
|
||||||
|
|
||||||
//otherwise.. TODO!
|
|
||||||
} else {
|
} else {
|
||||||
do {
|
do {
|
||||||
newPos = Random.Int(level.length());
|
newPos = Random.Int(level.length());
|
||||||
} while (
|
} while (
|
||||||
level.solid[newPos] ||
|
level.solid[newPos] ||
|
||||||
level.distance(newPos, enemy.pos) < 6 ||
|
level.distance(newPos, enemy.pos) < 5 ||
|
||||||
|
level.distance(newPos, enemy.pos) > 7 ||
|
||||||
|
level.distance(newPos, pos) < 6 ||
|
||||||
Actor.findChar(newPos) != null);
|
Actor.findChar(newPos) != null);
|
||||||
|
|
||||||
if (level.heroFOV[pos]) CellEmitter.get( pos ).burst( Speck.factory( Speck.WOOL ), 6 );
|
if (level.heroFOV[pos]) CellEmitter.get( pos ).burst( Speck.factory( Speck.WOOL ), 6 );
|
||||||
|
@ -312,4 +331,453 @@ public class NewTengu extends Mob {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************************
|
||||||
|
//***** Tengu abilities. These are expressed in game logic as buffs, blobs, and items *****
|
||||||
|
//*****************************************************************************************
|
||||||
|
|
||||||
|
//******************
|
||||||
|
//***Bomb Ability***
|
||||||
|
//******************
|
||||||
|
|
||||||
|
public static class BombAbility extends Buff {
|
||||||
|
|
||||||
|
public int bombPos;
|
||||||
|
private int timer = 3;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean act() {
|
||||||
|
|
||||||
|
PointF p = DungeonTilemap.raisedTileCenterToWorld(bombPos);
|
||||||
|
if (timer == 3) {
|
||||||
|
FloatingText.show(p.x, p.y, bombPos, "3...", CharSprite.NEUTRAL);
|
||||||
|
PathFinder.buildDistanceMap( bombPos, BArray.not( Dungeon.level.solid, null ), 2 );
|
||||||
|
for (int i = 0; i < PathFinder.distance.length; i++) {
|
||||||
|
if (PathFinder.distance[i] < Integer.MAX_VALUE) {
|
||||||
|
GameScene.add(Blob.seed(i, 4, BombBlob.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (timer == 2){
|
||||||
|
FloatingText.show(p.x, p.y, bombPos, "2...", CharSprite.WARNING);
|
||||||
|
} else if (timer == 1){
|
||||||
|
FloatingText.show(p.x, p.y, bombPos, "1...", CharSprite.NEGATIVE);
|
||||||
|
} else {
|
||||||
|
Heap h = Dungeon.level.heaps.get(bombPos);
|
||||||
|
if (h != null){
|
||||||
|
for (Item i : h.items.toArray(new Item[0])){
|
||||||
|
if (i instanceof BombItem){
|
||||||
|
h.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
detach();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer--;
|
||||||
|
spend(TICK);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String BOMB_POS = "bomb_pos";
|
||||||
|
private static final String TIMER = "timer";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeInBundle(Bundle bundle) {
|
||||||
|
super.storeInBundle(bundle);
|
||||||
|
bundle.put( BOMB_POS, bombPos );
|
||||||
|
bundle.put( TIMER, timer );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreFromBundle(Bundle bundle) {
|
||||||
|
super.restoreFromBundle(bundle);
|
||||||
|
bombPos = bundle.getInt( BOMB_POS );
|
||||||
|
timer = bundle.getInt( TIMER );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BombBlob extends Blob {
|
||||||
|
{
|
||||||
|
actPriority = BUFF_PRIO - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void evolve() {
|
||||||
|
|
||||||
|
boolean exploded = false;
|
||||||
|
|
||||||
|
int cell;
|
||||||
|
for (int i = area.left; i < area.right; i++){
|
||||||
|
for (int j = area.top; j < area.bottom; j++){
|
||||||
|
cell = i + j* Dungeon.level.width();
|
||||||
|
off[cell] = cur[cell] > 0 ? cur[cell] - 1 : 0;
|
||||||
|
|
||||||
|
if (off[cell] > 0) {
|
||||||
|
volume += off[cell];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur[cell] > 0 && off[cell] == 0){
|
||||||
|
|
||||||
|
Char ch = Actor.findChar(cell);
|
||||||
|
if (ch != null){
|
||||||
|
int dmg = Random.NormalIntRange(5 + Dungeon.depth, 10 + Dungeon.depth*2);
|
||||||
|
dmg -= ch.drRoll();
|
||||||
|
|
||||||
|
if (dmg > 0) {
|
||||||
|
ch.damage(dmg, Bomb.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == Dungeon.hero && !ch.isAlive()) {
|
||||||
|
Dungeon.fail(NewTengu.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Dungeon.level.heroFOV[cell]) {
|
||||||
|
exploded = true;
|
||||||
|
CellEmitter.center(cell).burst(BlastParticle.FACTORY, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exploded){
|
||||||
|
Sample.INSTANCE.play(Assets.SND_BLAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void use(BlobEmitter emitter) {
|
||||||
|
super.use(emitter);
|
||||||
|
|
||||||
|
emitter.pour( SmokeParticle.FACTORY, 0.1f );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String tileDesc() {
|
||||||
|
return Messages.get(this, "desc");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BombItem extends Item {
|
||||||
|
|
||||||
|
{
|
||||||
|
dropsDownHeap = true;
|
||||||
|
|
||||||
|
image = ItemSpriteSheet.TENGU_BOMB;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doPickUp( Hero hero ) {
|
||||||
|
GLog.w( Messages.get(this, "cant_pickup") );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO change for when tengu throws this
|
||||||
|
@Override
|
||||||
|
protected void onThrow(int cell) {
|
||||||
|
super.onThrow(cell);
|
||||||
|
Buff.append(curUser, BombAbility.class).bombPos = cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemSprite.Glowing glowing() {
|
||||||
|
return new ItemSprite.Glowing( 0xFF0000, 0.5f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************
|
||||||
|
//***Fire Ability***
|
||||||
|
//******************
|
||||||
|
|
||||||
|
public static class FireAbility extends Buff {
|
||||||
|
|
||||||
|
public int direction;
|
||||||
|
private int[] curCells;
|
||||||
|
|
||||||
|
HashSet<Integer> toCells = new HashSet<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean act() {
|
||||||
|
|
||||||
|
if (curCells == null){
|
||||||
|
curCells = new int[1];
|
||||||
|
curCells[0] = target.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
toCells.clear();
|
||||||
|
|
||||||
|
for (Integer c : curCells){
|
||||||
|
spreadFromCell( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Integer c : curCells){
|
||||||
|
toCells.remove(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toCells.isEmpty()){
|
||||||
|
detach();
|
||||||
|
} else {
|
||||||
|
curCells = new int[toCells.size()];
|
||||||
|
int i = 0;
|
||||||
|
for (Integer c : toCells){
|
||||||
|
GameScene.add(Blob.seed(c, 2, FireBlob.class));
|
||||||
|
curCells[i] = c;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spend(TICK);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spreadFromCell( int cell ){
|
||||||
|
if (!Dungeon.level.solid[cell + PathFinder.CIRCLE8[left(direction)]]){
|
||||||
|
toCells.add(cell + PathFinder.CIRCLE8[left(direction)]);
|
||||||
|
}
|
||||||
|
if (!Dungeon.level.solid[cell + PathFinder.CIRCLE8[direction]]){
|
||||||
|
toCells.add(cell + PathFinder.CIRCLE8[direction]);
|
||||||
|
}
|
||||||
|
if (!Dungeon.level.solid[cell + PathFinder.CIRCLE8[right(direction)]]){
|
||||||
|
toCells.add(cell + PathFinder.CIRCLE8[right(direction)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int left(int direction){
|
||||||
|
return direction == 0 ? 7 : direction-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int right(int direction){
|
||||||
|
return direction == 7 ? 0 : direction+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String DIRECTION = "direction";
|
||||||
|
private static final String CUR_CELLS = "cur_cells";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeInBundle(Bundle bundle) {
|
||||||
|
super.storeInBundle(bundle);
|
||||||
|
bundle.put( DIRECTION, direction );
|
||||||
|
bundle.put( CUR_CELLS, curCells );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreFromBundle(Bundle bundle) {
|
||||||
|
super.restoreFromBundle(bundle);
|
||||||
|
direction = bundle.getInt( DIRECTION );
|
||||||
|
curCells = bundle.getIntArray( CUR_CELLS );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FireBlob extends Blob {
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
actPriority = BUFF_PRIO - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void evolve() {
|
||||||
|
|
||||||
|
boolean observe = false;
|
||||||
|
boolean burned = false;
|
||||||
|
|
||||||
|
int cell;
|
||||||
|
for (int i = area.left; i < area.right; i++){
|
||||||
|
for (int j = area.top; j < area.bottom; j++){
|
||||||
|
cell = i + j* Dungeon.level.width();
|
||||||
|
off[cell] = cur[cell] > 0 ? cur[cell] - 1 : 0;
|
||||||
|
|
||||||
|
if (off[cell] > 0) {
|
||||||
|
volume += off[cell];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur[cell] > 0 && off[cell] == 0){
|
||||||
|
Fire.burn( cell );
|
||||||
|
|
||||||
|
if (Dungeon.level.flamable[cell]){
|
||||||
|
Dungeon.level.destroy( cell );
|
||||||
|
|
||||||
|
observe = true;
|
||||||
|
GameScene.updateMap( cell );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Dungeon.level.heroFOV[cell]){
|
||||||
|
burned = true;
|
||||||
|
CellEmitter.get(cell).start(FlameParticle.FACTORY, 0.03f, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (observe) {
|
||||||
|
Dungeon.observe();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (burned){
|
||||||
|
Sample.INSTANCE.play(Assets.SND_BURNING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void use(BlobEmitter emitter) {
|
||||||
|
super.use(emitter);
|
||||||
|
|
||||||
|
emitter.pour( Speck.factory( Speck.STEAM ), 0.2f );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String tileDesc() {
|
||||||
|
return Messages.get(this, "desc");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*********************
|
||||||
|
//***Shocker Ability***
|
||||||
|
//*********************
|
||||||
|
|
||||||
|
public static class ShockerAbility extends Buff {
|
||||||
|
|
||||||
|
public int shockerPos;
|
||||||
|
private Boolean shockingOrdinals = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean act() {
|
||||||
|
|
||||||
|
if (shockingOrdinals == null){
|
||||||
|
shockingOrdinals = Random.Int(2) == 1;
|
||||||
|
|
||||||
|
spreadblob();
|
||||||
|
} else if (shockingOrdinals){
|
||||||
|
|
||||||
|
target.sprite.parent.add(new Lightning(shockerPos - 1 - Dungeon.level.width(), shockerPos + 1 + Dungeon.level.width(), null));
|
||||||
|
target.sprite.parent.add(new Lightning(shockerPos - 1 + Dungeon.level.width(), shockerPos + 1 - Dungeon.level.width(), null));
|
||||||
|
|
||||||
|
if (Dungeon.level.distance(Dungeon.hero.pos, shockerPos) <= 1){
|
||||||
|
Sample.INSTANCE.play( Assets.SND_LIGHTNING );
|
||||||
|
}
|
||||||
|
|
||||||
|
shockingOrdinals = false;
|
||||||
|
spreadblob();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
target.sprite.parent.add(new Lightning(shockerPos - Dungeon.level.width(), shockerPos + Dungeon.level.width(), null));
|
||||||
|
target.sprite.parent.add(new Lightning(shockerPos - 1, shockerPos + 1, null));
|
||||||
|
|
||||||
|
if (Dungeon.level.distance(Dungeon.hero.pos, shockerPos) <= 1){
|
||||||
|
Sample.INSTANCE.play( Assets.SND_LIGHTNING );
|
||||||
|
}
|
||||||
|
|
||||||
|
shockingOrdinals = true;
|
||||||
|
spreadblob();
|
||||||
|
}
|
||||||
|
|
||||||
|
spend(TICK);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spreadblob(){
|
||||||
|
GameScene.add(Blob.seed(shockerPos, 1, ShockerBlob.class));
|
||||||
|
for (int i = shockingOrdinals ? 0 : 1; i < PathFinder.CIRCLE8.length; i += 2){
|
||||||
|
if (!Dungeon.level.solid[shockerPos+PathFinder.CIRCLE8[i]]) {
|
||||||
|
GameScene.add(Blob.seed(shockerPos + PathFinder.CIRCLE8[i], 2, ShockerBlob.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String SHOCKER_POS = "shocker_pos";
|
||||||
|
private static final String SHOCKING_ORDINALS = "shocking_ordinals";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeInBundle(Bundle bundle) {
|
||||||
|
super.storeInBundle(bundle);
|
||||||
|
bundle.put( SHOCKER_POS, shockerPos );
|
||||||
|
bundle.put( SHOCKING_ORDINALS, shockingOrdinals );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreFromBundle(Bundle bundle) {
|
||||||
|
super.restoreFromBundle(bundle);
|
||||||
|
shockerPos = bundle.getInt( SHOCKER_POS );
|
||||||
|
shockingOrdinals = bundle.getBoolean( SHOCKING_ORDINALS );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ShockerBlob extends Blob {
|
||||||
|
|
||||||
|
{
|
||||||
|
actPriority = BUFF_PRIO - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void evolve() {
|
||||||
|
|
||||||
|
int cell;
|
||||||
|
for (int i = area.left; i < area.right; i++){
|
||||||
|
for (int j = area.top; j < area.bottom; j++){
|
||||||
|
cell = i + j* Dungeon.level.width();
|
||||||
|
off[cell] = cur[cell] > 0 ? cur[cell] - 1 : 0;
|
||||||
|
|
||||||
|
if (off[cell] > 0) {
|
||||||
|
volume += off[cell];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur[cell] > 0 && off[cell] == 0){
|
||||||
|
|
||||||
|
Char ch = Actor.findChar(cell);
|
||||||
|
if (ch != null){
|
||||||
|
ch.damage(2 + Dungeon.depth, Electricity.class);
|
||||||
|
|
||||||
|
if (ch == Dungeon.hero && !ch.isAlive()) {
|
||||||
|
Dungeon.fail(NewTengu.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void use(BlobEmitter emitter) {
|
||||||
|
super.use(emitter);
|
||||||
|
|
||||||
|
emitter.pour( SparkParticle.STATIC, 0.10f );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String tileDesc() {
|
||||||
|
return Messages.get(this, "desc");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ShockerItem extends Item {
|
||||||
|
|
||||||
|
{
|
||||||
|
dropsDownHeap = true;
|
||||||
|
|
||||||
|
image = ItemSpriteSheet.TENGU_SHOCKER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doPickUp( Hero hero ) {
|
||||||
|
GLog.w( Messages.get(this, "cant_pickup") );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO change for when tengu throws this
|
||||||
|
@Override
|
||||||
|
protected void onThrow(int cell) {
|
||||||
|
super.onThrow(cell);
|
||||||
|
Buff.append(curUser, ShockerAbility.class).shockerPos = cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemSprite.Glowing glowing() {
|
||||||
|
return new ItemSprite.Glowing( 0xFFFFFF, 0.5f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,7 +271,7 @@ public class Speck extends Image {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STEAM:
|
case STEAM:
|
||||||
speed.y = -Random.Float( 20, 30 );
|
speed.y = -Random.Float( 10, 15 );
|
||||||
angularSpeed = Random.Float( +180 );
|
angularSpeed = Random.Float( +180 );
|
||||||
angle = Random.Float( 360 );
|
angle = Random.Float( 360 );
|
||||||
lifespan = 1f;
|
lifespan = 1f;
|
||||||
|
|
|
@ -36,7 +36,18 @@ public class SparkParticle extends PixelParticle {
|
||||||
@Override
|
@Override
|
||||||
public boolean lightMode() {
|
public boolean lightMode() {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static final Emitter.Factory STATIC = new Factory() {
|
||||||
|
@Override
|
||||||
|
public void emit( Emitter emitter, int index, float x, float y ) {
|
||||||
|
((SparkParticle)emitter.recycle( SparkParticle.class )).resetStatic( x, y );
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean lightMode() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public SparkParticle() {
|
public SparkParticle() {
|
||||||
|
@ -58,6 +69,15 @@ public class SparkParticle extends PixelParticle {
|
||||||
speed.polar( -Random.Float( 3.1415926f ), Random.Float( 20, 40 ) );
|
speed.polar( -Random.Float( 3.1415926f ), Random.Float( 20, 40 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void resetStatic( float x, float y){
|
||||||
|
reset(x, y);
|
||||||
|
|
||||||
|
left = lifespan = Random.Float( 0.25f, 0.5f );
|
||||||
|
|
||||||
|
acc.set( 0, 0 );
|
||||||
|
speed.set( 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
super.update();
|
super.update();
|
||||||
|
|
|
@ -429,9 +429,7 @@ public class NewPrisonBossLevel extends Level {
|
||||||
cleanMapState();
|
cleanMapState();
|
||||||
|
|
||||||
tengu.state = tengu.HUNTING;
|
tengu.state = tengu.HUNTING;
|
||||||
do {
|
tengu.pos = (arena.left + arena.width()/2) + width()*(arena.top+2);
|
||||||
tengu.pos = Random.Int(length());
|
|
||||||
} while (solid[tengu.pos] || distance(tengu.pos, Dungeon.hero.pos) < 6);
|
|
||||||
GameScene.add(tengu);
|
GameScene.add(tengu);
|
||||||
tengu.notice();
|
tengu.notice();
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,9 @@ public class ItemSpriteSheet {
|
||||||
|
|
||||||
public static final int GUIDE_PAGE = UNCOLLECTIBLE+6;
|
public static final int GUIDE_PAGE = UNCOLLECTIBLE+6;
|
||||||
public static final int ALCH_PAGE = UNCOLLECTIBLE+7;
|
public static final int ALCH_PAGE = UNCOLLECTIBLE+7;
|
||||||
|
|
||||||
|
public static final int TENGU_BOMB = UNCOLLECTIBLE+9;
|
||||||
|
public static final int TENGU_SHOCKER = UNCOLLECTIBLE+10;
|
||||||
static{
|
static{
|
||||||
assignItemRect(GOLD, 15, 13);
|
assignItemRect(GOLD, 15, 13);
|
||||||
assignItemRect(DEWDROP, 10, 10);
|
assignItemRect(DEWDROP, 10, 10);
|
||||||
|
@ -90,6 +93,9 @@ public class ItemSpriteSheet {
|
||||||
|
|
||||||
assignItemRect(GUIDE_PAGE, 10, 11);
|
assignItemRect(GUIDE_PAGE, 10, 11);
|
||||||
assignItemRect(ALCH_PAGE, 10, 11);
|
assignItemRect(ALCH_PAGE, 10, 11);
|
||||||
|
|
||||||
|
assignItemRect(TENGU_BOMB, 10, 10);
|
||||||
|
assignItemRect(TENGU_SHOCKER, 10, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int CONTAINERS = xy(1, 3); //16 slots
|
private static final int CONTAINERS = xy(1, 3); //16 slots
|
||||||
|
|
|
@ -590,6 +590,18 @@ actors.mobs.newtengu.defeated=Free at last...
|
||||||
actors.mobs.newtengu.rankings_desc=Assassinated by the Tengu
|
actors.mobs.newtengu.rankings_desc=Assassinated by the Tengu
|
||||||
actors.mobs.newtengu.desc=A famous and enigmatic assassin, named for the mask grafted to his face.\n\nTengu is held down with large clasps on his wrists and knees, though he seems to have gotten rid of his chains long ago.\n\nHe will try to use traps, deceptive magic, and precise attacks to eliminate the only thing stopping his escape: you.
|
actors.mobs.newtengu.desc=A famous and enigmatic assassin, named for the mask grafted to his face.\n\nTengu is held down with large clasps on his wrists and knees, though he seems to have gotten rid of his chains long ago.\n\nHe will try to use traps, deceptive magic, and precise attacks to eliminate the only thing stopping his escape: you.
|
||||||
|
|
||||||
|
actors.mobs.newtengu$bombability$bombblob.desc=A cloud of superheated smoke is billowing here. Watch out, it's going to explode!
|
||||||
|
actors.mobs.newtengu$bombability$bombitem.name=Smoke Bomb
|
||||||
|
actors.mobs.newtengu$bombability$bombitem.cant_pickup=It's stuck to the ground, you can't move it!
|
||||||
|
actors.mobs.newtengu$bombability$bombitem.desc=Tengu has thrown a strange looking smoke bomb here, which is billowing a thick hot smoke. It's making a loud ticking noise, as if its counting down to an explosion!\n\nThe bomb has anchored itself to the ground, so you can't pick it up.
|
||||||
|
|
||||||
|
actors.mobs.newtengu$fireability$fireblob.desc=Tengu has thrown a fine powder that seems to be catching into steam here, it's about to ignite!
|
||||||
|
|
||||||
|
actors.mobs.newtengu$shockerability$shockerblob.desc=Electrical energy is building here, anything standing on this tile will be shocked next turn!
|
||||||
|
actors.mobs.newtengu$shockerability$shockeritem.name=Shocker
|
||||||
|
actors.mobs.newtengu$shockerability$shockeritem.cant_pickup=It's putting out too much electricity, you can't grab it!
|
||||||
|
actors.mobs.newtengu$shockerability$shockeritem.desc=Tengu has thrown a curious machine here, which seems to be made of robot parts. The machine is constantly arcing electricity around it, but it seems to be going in a predictable pattern.\n\nWith all the electricity arcing around it, there's no way you can pick this up.
|
||||||
|
|
||||||
actors.mobs.oldtengu.name=Tengu
|
actors.mobs.oldtengu.name=Tengu
|
||||||
actors.mobs.oldtengu.notice_mine=You're mine, %s!
|
actors.mobs.oldtengu.notice_mine=You're mine, %s!
|
||||||
actors.mobs.oldtengu.notice_face=Face me, %s!
|
actors.mobs.oldtengu.notice_face=Face me, %s!
|
||||||
|
|
Loading…
Reference in New Issue
Block a user