From 4c86cba1cf29669f11a823914ef228e3624d08d3 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Mon, 18 Sep 2023 15:02:37 -0400 Subject: [PATCH] v2.2.0: early incomplete implementations for crystal enemies --- .../assets/messages/actors/actors.properties | 9 ++ .../main/assets/sprites/crystal_guardian.png | Bin 0 -> 2696 bytes .../src/main/assets/sprites/crystal_spire.png | Bin 0 -> 340 bytes core/src/main/assets/sprites/crystal_wisp.png | Bin 0 -> 1016 bytes .../shatteredpixeldungeon/Assets.java | 3 + .../shatteredpixeldungeon/Dungeon.java | 2 + .../shatteredpixeldungeon/actors/Char.java | 5 + .../actors/mobs/CrystalGuardian.java | 123 ++++++++++++++++++ .../actors/mobs/CrystalSpire.java | 71 ++++++++++ .../actors/mobs/CrystalWisp.java | 73 +++++++++++ .../levels/MiningLevel.java | 18 ++- .../levels/rooms/quest/MineGiantRoom.java | 9 ++ .../levels/rooms/quest/MineLargeRoom.java | 10 +- .../sprites/CrystalGuardianSprite.java | 89 +++++++++++++ .../sprites/CrystalSpireSprite.java | 95 ++++++++++++++ .../sprites/CrystalWispSprite.java | 90 +++++++++++++ .../ui/AttackIndicator.java | 5 + .../windows/WndInfoMob.java | 2 +- 18 files changed, 592 insertions(+), 12 deletions(-) create mode 100644 core/src/main/assets/sprites/crystal_guardian.png create mode 100644 core/src/main/assets/sprites/crystal_spire.png create mode 100644 core/src/main/assets/sprites/crystal_wisp.png create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalGuardian.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalSpire.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalWisp.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalGuardianSprite.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalSpireSprite.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalWispSprite.java diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index 4846074cc..4fb71a069 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -1111,11 +1111,20 @@ actors.mobs.causticslime.desc=This slime seems to have been tainted by the dark actors.mobs.crab.name=sewer crab actors.mobs.crab.desc=These huge crabs are at the top of the food chain in the sewers. They are extremely fast and their thick carapace can withstand heavy blows. +actors.mobs.crystalguardian.name=crystal guardian +actors.mobs.crystalguardian.desc=TODO + actors.mobs.crystalmimic.name=crystal mimic actors.mobs.crystalmimic.ate=The mimic ate your %s! actors.mobs.crystalmimic.escaped=The crystal mimic has escaped! actors.mobs.crystalmimic.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.\n\nCrystal mimics are trickier than their regular cousins, and prefer to avoid conflict while stealing loot. They will attempt to sprint away once discovered, and have the ability to reposition enemies when they attack. +actors.mobs.crystalspire.name=crystal spire +actors.mobs.crystalspire.desc=TODO + +actors.mobs.crystalwisp.name=crystal wisp +actors.mobs.crystalwisp.desc=TODO + actors.mobs.demonspawner.name=demon spawner actors.mobs.demonspawner.on_death=The demonic energy here seems to lessen as the spawner dies. actors.mobs.demonspawner.desc=This twisting amalgam of dwarven flesh is responsible for creating ripper demons from the dwarves that have died in this region. Clearly the demons see no issue with using every resource they can against their enemies.\n\nWhile visually terrifying, demon spawners have no means of moving or directly defending themselves. Their considerable mass makes them hard to kill quickly however, and they will spawn ripper demons more quickly when they are under threat.\n\n_Demon spawners seem to be connected to some central source of demonic power. Killing them may weaken it._ diff --git a/core/src/main/assets/sprites/crystal_guardian.png b/core/src/main/assets/sprites/crystal_guardian.png new file mode 100644 index 0000000000000000000000000000000000000000..204103269068e824b4e71708266595c4bbd11bda GIT binary patch literal 2696 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 literal 0 HcmV?d00001 diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java index d0e0de3ae..dc750045b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java @@ -314,5 +314,8 @@ public class Assets { public static final String NINJA_LOG= "sprites/ninja_log.png"; public static final String SPIRIT_HAWK= "sprites/spirit_hawk.png"; public static final String RED_SENTRY= "sprites/red_sentry.png"; + public static final String CRYSTAL_WISP= "sprites/crystal_wisp.png"; + public static final String CRYSTAL_GUARDIAN= "sprites/crystal_guardian.png"; + public static final String CRYSTAL_SPIRE= "sprites/crystal_spire.png"; } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java index a03a0c6ad..9fd298a5d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java @@ -987,6 +987,8 @@ public class Dungeon { BArray.and( passable, Dungeon.level.openSpace, passable ); } + ch.modifyPassable(passable); + if (chars) { for (Char c : Actor.chars()) { if (vis[c.pos]) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java index 562236685..188875381 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java @@ -1015,6 +1015,11 @@ public abstract class Char extends Actor { public int distance( Char other ) { return Dungeon.level.distance( pos, other.pos ); } + + public boolean[] modifyPassable( boolean[] passable){ + //do nothing by default, but some chars can pass over terrain that others can't + return passable; + } public void onMotionComplete() { //Does nothing by default diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalGuardian.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalGuardian.java new file mode 100644 index 000000000..082e89a45 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalGuardian.java @@ -0,0 +1,123 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2023 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; + +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import com.shatteredpixel.shatteredpixeldungeon.sprites.CrystalGuardianSprite; +import com.watabou.utils.Bundle; +import com.watabou.utils.PathFinder; +import com.watabou.utils.Random; + +public class CrystalGuardian extends Mob{ + + { + HP = HT = 1; + spriteClass = CrystalGuardianSprite.class; + + SLEEPING = new Sleeping(); + state = SLEEPING; + } + + public CrystalGuardian(){ + super(); + switch (Random.Int(3)){ + case 0: default: + spriteClass = CrystalGuardianSprite.Blue.class; + break; + case 1: + spriteClass = CrystalGuardianSprite.Green.class; + break; + case 2: + spriteClass = CrystalGuardianSprite.Red.class; + break; + } + } + + @Override + public float spawningWeight() { + return 0; + } + + @Override + public float speed() { + if (Dungeon.level.openSpace[pos]) { + return super.speed(); + } else { + return super.speed()/4f; + } + } + + @Override + public void beckon(int cell) { + super.beckon(cell); + + //If we are still penned into our starting area, break out of it + PathFinder.buildDistanceMap(cell, Dungeon.level.passable); + if (PathFinder.distance[pos] == Integer.MAX_VALUE){ + boolean[] passable = Dungeon.level.passable.clone(); + for (int i = 0; i < Dungeon.level.length(); i++){ + passable[i] = passable[i] || Dungeon.level.map[i] == Terrain.MINE_CRYSTAL; + } + PathFinder.Path p = PathFinder.find(pos, cell, passable); + if (p != null) { + for (int i : p) { + if (Dungeon.level.map[i] == Terrain.MINE_CRYSTAL) { + Level.set(i, Terrain.EMPTY); + GameScene.updateMap(i); + } + } + } + } + } + + protected class Sleeping extends Mob.Sleeping{ + + @Override + protected void awaken(boolean enemyInFOV) { + if (enemyInFOV){ + //do not wake up if we see an enemy we can't actually reach + PathFinder.buildDistanceMap(enemy.pos, Dungeon.level.passable); + if (PathFinder.distance[pos] == Integer.MAX_VALUE){ + return; + } + } + super.awaken(enemyInFOV); + } + } + + public static final String SPRITE = "sprite"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(SPRITE, spriteClass); + } + + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + spriteClass = bundle.getClass(SPRITE); + } +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalSpire.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalSpire.java new file mode 100644 index 000000000..683c01a5f --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalSpire.java @@ -0,0 +1,71 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2023 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; + +import com.shatteredpixel.shatteredpixeldungeon.sprites.CrystalSpireSprite; +import com.watabou.utils.Bundle; +import com.watabou.utils.Random; + +public class CrystalSpire extends Mob { + + { + HP = HT = 1; + spriteClass = CrystalSpireSprite.class; + + state = PASSIVE; + } + + public CrystalSpire(){ + super(); + switch (Random.Int(3)){ + case 0: default: + spriteClass = CrystalSpireSprite.Blue.class; + break; + case 1: + spriteClass = CrystalSpireSprite.Green.class; + break; + case 2: + spriteClass = CrystalSpireSprite.Red.class; + break; + } + } + + @Override + public float spawningWeight() { + return 0; + } + + public static final String SPRITE = "sprite"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(SPRITE, spriteClass); + } + + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + spriteClass = bundle.getClass(SPRITE); + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalWisp.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalWisp.java new file mode 100644 index 000000000..99ef1f84d --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalWisp.java @@ -0,0 +1,73 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2023 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; + +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; +import com.shatteredpixel.shatteredpixeldungeon.sprites.CrystalWispSprite; +import com.watabou.utils.Bundle; +import com.watabou.utils.Random; + +public class CrystalWisp extends Mob{ + + { + HP = HT = 1; + spriteClass = CrystalWispSprite.class; + } + + public CrystalWisp(){ + super(); + switch (Random.Int(3)){ + case 0: default: + spriteClass = CrystalWispSprite.Blue.class; + break; + case 1: + spriteClass = CrystalWispSprite.Green.class; + break; + case 2: + spriteClass = CrystalWispSprite.Red.class; + break; + } + } + + @Override + public boolean[] modifyPassable(boolean[] passable) { + for (int i = 0; i < Dungeon.level.length(); i++){ + passable[i] = passable[i] || Dungeon.level.map[i] == Terrain.MINE_CRYSTAL; + } + return passable; + } + + public static final String SPRITE = "sprite"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(SPRITE, spriteClass); + } + + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + spriteClass = bundle.getClass(SPRITE); + } +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/MiningLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/MiningLevel.java index 767228e95..a07abea03 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/MiningLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/MiningLevel.java @@ -23,8 +23,9 @@ package com.shatteredpixel.shatteredpixeldungeon.levels; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Bones; -import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bat; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CrystalWisp; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith; import com.shatteredpixel.shatteredpixeldungeon.items.Generator; @@ -132,15 +133,12 @@ public class MiningLevel extends CavesLevel { @Override public Mob createMob() { - return null; - } - - @Override - protected void createMobs() { - } - - public Actor addRespawner() { - return null; + switch (Blacksmith.Quest.Type()){ + default: + return new Bat(); + case Blacksmith.Quest.CRYSTAL: + return new CrystalWisp(); + } } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/MineGiantRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/MineGiantRoom.java index e34931194..bddc2a300 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/MineGiantRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/MineGiantRoom.java @@ -21,11 +21,13 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CrystalSpire; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith; 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.standard.CaveRoom; +import com.watabou.utils.Point; public class MineGiantRoom extends CaveRoom { @@ -49,6 +51,13 @@ public class MineGiantRoom extends CaveRoom { for (int i = 0; i < (width()-8)*(height()-8)/3; i ++){ Painter.set(level, random(4), Terrain.MINE_CRYSTAL); } + + Point p = center(); + CrystalSpire m = new CrystalSpire(); + m.pos = level.pointToCell(p); + level.mobs.add(m); + Painter.set(level, p, Terrain.EMPTY); + } else { Painter.fillEllipse(level, this, 3, Terrain.EMPTY); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/MineLargeRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/MineLargeRoom.java index f249d1b00..9b80ca853 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/MineLargeRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/MineLargeRoom.java @@ -21,11 +21,13 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CrystalGuardian; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith; 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.standard.CaveRoom; +import com.watabou.utils.Point; public class MineLargeRoom extends CaveRoom { @@ -36,7 +38,6 @@ public class MineLargeRoom extends CaveRoom { @Override protected float fill() { - int scale = Math.min(width()*height(), 18*18); return 0.55f; } @@ -51,6 +52,13 @@ public class MineLargeRoom extends CaveRoom { for (int i = 0; i < (width()-8)*(height()-8)/5; i ++){ Painter.set(level, random(4), Terrain.MINE_CRYSTAL); } + + Point p = random(5); + CrystalGuardian m = new CrystalGuardian(); + m.pos = level.pointToCell(p); + level.mobs.add(m); + Painter.set(level, p, Terrain.EMPTY); + } else { Painter.fillEllipse(level, this, 3, Terrain.EMPTY); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalGuardianSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalGuardianSprite.java new file mode 100644 index 000000000..889e16c6e --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalGuardianSprite.java @@ -0,0 +1,89 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2023 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.sprites; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.watabou.noosa.MovieClip; +import com.watabou.noosa.TextureFilm; + +public abstract class CrystalGuardianSprite extends MobSprite { + + public CrystalGuardianSprite() { + super(); + + texture( Assets.Sprites.CRYSTAL_GUARDIAN ); + + TextureFilm frames = new TextureFilm( texture, 12, 15 ); + + int c = texOffset(); + + idle = new MovieClip.Animation( 2, true ); + idle.frames( frames, 0+c, 0+c, 0+c, 0+c, 0+c, 1+c, 1+c ); + + run = new MovieClip.Animation( 15, true ); + run.frames( frames, 2+c, 3+c, 4+c, 5+c, 6+c, 7+c ); + + attack = new MovieClip.Animation( 12, false ); + attack.frames( frames, 8+c, 9+c, 10+c ); + + die = new MovieClip.Animation( 5, false ); + die.frames( frames, 11+c, 12+c, 13+c, 14+c, 15+c, 15+c ); + + play( idle ); + } + + protected abstract int texOffset(); + + public static class Blue extends CrystalGuardianSprite { + @Override + protected int texOffset() { + return 0; + } + @Override + public int blood() { + return 0xFF8EE3FF; + } + } + + public static class Green extends CrystalGuardianSprite { + @Override + protected int texOffset() { + return 21; + } + @Override + public int blood() { + return 0xFF85FFC8; + } + } + + public static class Red extends CrystalGuardianSprite { + @Override + protected int texOffset() { + return 42; + } + @Override + public int blood() { + return 0xFFFFBB33; + } + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalSpireSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalSpireSprite.java new file mode 100644 index 000000000..e05ebd33f --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalSpireSprite.java @@ -0,0 +1,95 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2023 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.sprites; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.watabou.noosa.TextureFilm; + +public abstract class CrystalSpireSprite extends MobSprite { + + { + perspectiveRaise = 7 / 16f; //7 pixels + } + + public CrystalSpireSprite(){ + texture( Assets.Sprites.CRYSTAL_SPIRE ); + + TextureFilm frames = new TextureFilm( texture, 30, 45 ); + + int c = texOffset(); + + idle = new Animation(1, true); + idle.frames( frames, 0+c ); + + run = idle.clone(); + attack = idle.clone(); + zap = idle.clone(); + + die = new Animation(1, false); + die.frames( frames, 0+c ); + + play(idle); + } + + @Override + public void link(Char ch) { + super.link(ch); + renderShadow = false; + } + + protected abstract int texOffset(); + + public static class Blue extends CrystalSpireSprite { + @Override + protected int texOffset() { + return 0; + } + @Override + public int blood() { + return 0xFF8EE3FF; + } + } + + public static class Green extends CrystalSpireSprite { + @Override + protected int texOffset() { + return 1; + } + @Override + public int blood() { + return 0xFF85FFC8; + } + } + + public static class Red extends CrystalSpireSprite { + @Override + protected int texOffset() { + return 2; + } + @Override + public int blood() { + return 0xFFFFBB33; + } + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalWispSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalWispSprite.java new file mode 100644 index 000000000..829a89c3a --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalWispSprite.java @@ -0,0 +1,90 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2023 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.sprites; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.watabou.noosa.TextureFilm; + +public abstract class CrystalWispSprite extends MobSprite { + + public CrystalWispSprite() { + super(); + + int c = texOffset(); + + texture( Assets.Sprites.CRYSTAL_WISP ); + + TextureFilm frames = new TextureFilm( texture, 12, 14 ); + + idle = new Animation( 4, true ); + idle.frames( frames, c+0, c+1, c+0, c+2 ); + + run = new Animation( 12, true ); + run.frames( frames, c+0, c+1, c+0, c+3 ); + + attack = new Animation( 15, false ); + attack.frames( frames, c+4, c+5, c+6 ); + + zap = attack.clone(); + + die = new Animation( 15, false ); + die.frames( frames, c+7, c+8, c+9, c+10, c+11, c+12, c+13, c+12 ); + + play( idle ); + } + + protected abstract int texOffset(); + + public static class Blue extends CrystalWispSprite { + @Override + protected int texOffset() { + return 0; + } + @Override + public int blood() { + return 0xFF8EE3FF; + } + } + + public static class Green extends CrystalWispSprite { + @Override + protected int texOffset() { + return 14; + } + @Override + public int blood() { + return 0xFF85FFC8; + } + } + + public static class Red extends CrystalWispSprite { + @Override + protected int texOffset() { + return 28; + } + @Override + public int blood() { + return 0xFFFFBB33; + } + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/AttackIndicator.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/AttackIndicator.java index 672bc0c53..81a9140ce 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/AttackIndicator.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/AttackIndicator.java @@ -155,6 +155,11 @@ public class AttackIndicator extends Tag { sprite.idle(); sprite.paused = true; sprite.visible = bg.visible; + + if (sprite.width() > 20 || sprite.height() > 20){ + sprite.scale.set(PixelScene.align(20f/Math.max(sprite.width(), sprite.height()))); + } + add( sprite ); layout(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoMob.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoMob.java index 02c5de262..0496deb12 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoMob.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoMob.java @@ -87,7 +87,7 @@ public class WndInfoMob extends WndTitledMessage { buffs.setPos(name.right(), name.bottom() - BuffIndicator.SIZE_SMALL-2); - height = health.bottom(); + height = Math.max(image.y + image.height(), health.bottom()); } } }