diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/VaultLaser.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/VaultLaser.java new file mode 100644 index 000000000..219680fed --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/VaultLaser.java @@ -0,0 +1,122 @@ +package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs; + +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.effects.Beam; +import com.shatteredpixel.shatteredpixeldungeon.effects.TargetedCell; +import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; +import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; +import com.shatteredpixel.shatteredpixeldungeon.sprites.WardSprite; +import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; +import com.watabou.utils.Bundle; + +public class VaultLaser extends NPC { + + { + spriteClass = WardSprite.class; + + properties.add(Char.Property.IMMOVABLE); + } + + public int[] laserDirs; + public int laserDirIdx; + + public int initialLaserCooldown; + public int cooldown; + + @Override + protected boolean act() { + + cooldown--; + if (cooldown <= 0){ + + Ballistica beam = new Ballistica(pos, laserDirs[laserDirIdx], Ballistica.STOP_SOLID); + boolean visible = false; + for (int cell : beam.subPath(1, beam.dist)){ + if (Dungeon.level.heroFOV[cell]){ + visible = true; + } + if (Actor.findChar(cell) == Dungeon.hero){ + Dungeon.hero.sprite.showStatus(CharSprite.NEGATIVE, "!!!"); + } + } + if (visible){ + sprite.parent.add(new Beam.DeathRay(sprite.center(), DungeonTilemap.raisedTileCenterToWorld(beam.collisionPos))); + } + + laserDirIdx++; + if (laserDirIdx >= laserDirs.length){ + laserDirIdx = 0; + } + cooldown = initialLaserCooldown; + + } + + if (cooldown == 1){ + + Ballistica nextBeam = new Ballistica(pos, laserDirs[laserDirIdx], Ballistica.STOP_SOLID); + for (int cell : nextBeam.subPath(1, nextBeam.dist)){ + if (Dungeon.level.heroFOV[cell]) { + sprite.parent.add(new TargetedCell(cell, 0xFF0000)); + } + } + + } + + throwItems(); + + spend(TICK); + return true; + } + + @Override + public boolean isImmune(Class effect) { + return true; + } + + @Override + public boolean isInvulnerable(Class effect) { + return true; + } + + @Override + public boolean reset() { + return true; + } + + @Override + public boolean interact(Char c) { + return true; + } + + private static final String LASER_DIRS = "laser_dirs"; + private static final String LASER_DIR_IDX = "laser_dir_idx"; + private static final String INITIAL_COOLDOWN = "initial_cooldown"; + private static final String COOLDOWN = "cooldown"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(LASER_DIRS, laserDirs); + bundle.put(LASER_DIR_IDX, laserDirIdx); + bundle.put(INITIAL_COOLDOWN, initialLaserCooldown); + bundle.put(COOLDOWN, cooldown); + } + + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + laserDirs = bundle.getIntArray(LASER_DIRS); + laserDirIdx = bundle.getInt(LASER_DIR_IDX); + initialLaserCooldown = bundle.getInt(INITIAL_COOLDOWN); + cooldown = bundle.getInt(COOLDOWN); + } + + @Override + public CharSprite sprite() { + WardSprite sprite = (WardSprite) super.sprite(); + sprite.linkVisuals(this); + return sprite; + } +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/VaultLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/VaultLevel.java index 5ef2ac801..e66aa4d3b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/VaultLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/VaultLevel.java @@ -44,6 +44,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultCr import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultEnemyCenterRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultEntranceRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultFinalRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultLasersRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultLongRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultQuadrantsRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultRingRoom; @@ -71,6 +72,7 @@ public class VaultLevel extends CityLevel { initRooms.add(new VaultRingsRoom()); initRooms.add(new VaultSimpleEnemyTreasureRoom()); initRooms.add(new AlternatingTrapsRoom()); + initRooms.add(new VaultLasersRoom()); } initRooms.add(new VaultLongRoom()); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultEntranceRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultEntranceRoom.java index 6491b5612..76af382be 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultEntranceRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultEntranceRoom.java @@ -1,16 +1,13 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; -import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob; -import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.VaultFlameTraps; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.VaultLaser; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; -import com.shatteredpixel.shatteredpixeldungeon.levels.VaultLevel; import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.entrance.EntranceRoom; import com.watabou.utils.Point; public class VaultEntranceRoom extends StandardRoom { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultLasersRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultLasersRoom.java new file mode 100644 index 000000000..f3223cd22 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultLasersRoom.java @@ -0,0 +1,72 @@ +package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault; + +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.VaultLaser; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; +import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom; +import com.watabou.utils.Random; + +public class VaultLasersRoom extends StandardRoom { + + @Override + public float[] sizeCatProbs() { + return new float[]{0, 1, 0}; + } + + @Override + public void paint(Level level) { + Painter.fill(level, this, Terrain.WALL); + Painter.fill(level, this, 2, Terrain.EMPTY); + + for (Room.Door door : connected.values()) { + Painter.drawInside(level, this, door, 2, Terrain.EMPTY); + door.set(Room.Door.Type.REGULAR); + } + + for (int x = left+2; x <= right-2; x++){ + if (level.map[x + (top+1)*level.width()] == Terrain.WALL + && level.map[x + (bottom-1)*level.width()] == Terrain.WALL){ + VaultLaser laser = new VaultLaser(); + if (Random.Int(2) == 0){ + int cell = x + level.width()*(top+1); + Painter.set(level, cell, Terrain.PEDESTAL); + laser.laserDirs = new int[]{cell+level.width()}; + laser.pos = cell; + } else { + int cell = x + level.width()*(bottom-1); + Painter.set(level, cell, Terrain.PEDESTAL); + laser.laserDirs = new int[]{cell-level.width()}; + laser.pos = cell; + } + laser.initialLaserCooldown = Random.IntRange(3, 7); + laser.cooldown = Random.IntRange(1, laser.initialLaserCooldown); + level.mobs.add(laser); + } + } + + for (int y = top+2; y <= bottom-2; y++){ + if (level.map[left+1 + (y)*level.width()] == Terrain.WALL + && level.map[right-1 + (y)*level.width()] == Terrain.WALL){ + VaultLaser laser = new VaultLaser(); + if (Random.Int(2) == 0){ + int cell = left+1 + level.width()*y; + Painter.set(level, cell, Terrain.PEDESTAL); + laser.laserDirs = new int[]{cell+1}; + laser.pos = cell; + } else { + int cell = right-1 + level.width()*y; + Painter.set(level, cell, Terrain.PEDESTAL); + laser.laserDirs = new int[]{cell-1}; + laser.pos = cell; + } + laser.initialLaserCooldown = Random.IntRange(3, 7); + laser.cooldown = Random.IntRange(1, laser.initialLaserCooldown); + level.mobs.add(laser); + } + } + + } + +}