From be29c81ef3c5997141ee9bd0a01be4a4905291ae Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Mon, 18 Dec 2023 15:07:34 -0500 Subject: [PATCH] v2.3.0: added fungal sentries, with WIP visuals and bare mechanics --- .../assets/messages/actors/actors.properties | 3 + .../src/main/assets/sprites/fungal_sentry.png | Bin 0 -> 199 bytes .../shatteredpixeldungeon/Assets.java | 21 ++-- .../actors/mobs/FungalSentry.java | 117 ++++++++++++++++++ .../effects/MagicMissile.java | 8 +- .../levels/rooms/quest/MineLargeRoom.java | 8 +- .../sprites/FungalSentrySprite.java | 98 +++++++++++++++ 7 files changed, 241 insertions(+), 14 deletions(-) create mode 100644 core/src/main/assets/sprites/fungal_sentry.png create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/FungalSentry.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/FungalSentrySprite.java diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index 90be78731..5462bc4c1 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -1202,6 +1202,9 @@ actors.mobs.eye.desc=Evil Eyes are floating balls of pent up demonic energy. Whi actors.mobs.fetidrat.name=fetid rat actors.mobs.fetidrat.desc=Something is clearly wrong with this rat. Its greasy black fur and rotting skin are very different from the healthy rats you've seen previously. Its pale green eyes make it seem especially menacing.\n\nThe rat carries a cloud of horrible stench with it, it's overpoweringly strong up close.\n\nDark ooze dribbles from the rat's mouth, it eats through the floor but seems to dissolve in water. +actors.mobs.fungalsentry.name=fungal sentry +actors.mobs.fungalsentry.desc=This especially tall mushroom acts as a point of defense for the larger fungal network living in this cave.\n\nIt is immobile, but will shoot precise blasts of poison at anything that gets within its line of sight. While the impact of these blasts is fairly weak, _they can stack up deadly amounts of poison very quickly._ While it can be killed, it's probably best to avoid it. + actors.mobs.fungalspinner.name=fungal spinner actors.mobs.fungalspinner.desc=This cave spinner appears to be being controlled by a parasitic fungus. The fungus has also changed its abilities, replacing its web and venom sacks with fungal growth.\n\nThe fungal spinner will spit plant life at you instead of webs, spreading fungal vegetation and potentially rooting you. While it can't poison, the fungal spinner will gain substantial damage resistance if it is adjacent to any mushrooms. diff --git a/core/src/main/assets/sprites/fungal_sentry.png b/core/src/main/assets/sprites/fungal_sentry.png new file mode 100644 index 0000000000000000000000000000000000000000..5a323833770ee82a8c85ab68d8dae0a87e350acf GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^4M42G!VDxecyh&nluCe4h%1mz$+O#eEipRPEN-_; z&+H)oX1lmpGZQZ@O$oVRf4lnL_=WmWGlA+DOM?7@862M7NCR>LJzX3_Dj46MxyaCv zAi(@U^AA_BhhnSdoI@f(K>EopkynZO-x+HTJjy=o{=eDvoyf`v2QRIu#f@HPJ6N;Y rdt(^P6(qM9%f) + */ + +package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; + +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Poison; +import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; +import com.shatteredpixel.shatteredpixeldungeon.sprites.FungalSentrySprite; +import com.watabou.utils.Random; + +public class FungalSentry extends Mob { + + { + spriteClass = FungalSentrySprite.class; + + HP = HT = 200; + defenseSkill = 12; + + EXP = 10; + maxLvl = -2; + + state = WANDERING = new Waiting(); + + properties.add(Property.IMMOVABLE); + properties.add(Property.MINIBOSS); + } + + @Override + public boolean reset() { + return true; + } + + @Override + protected boolean getCloser(int target) { + return false; + } + + @Override + protected boolean getFurther(int target) { + return false; + } + + @Override + public int damageRoll() { + return Random.NormalIntRange(5, 10); + } + + @Override + //TODO attack is a little permissive atm? + protected boolean canAttack( Char enemy ) { + return super.canAttack(enemy) + || new Ballistica( pos, enemy.pos, Ballistica.MAGIC_BOLT).collisionPos == enemy.pos; + } + + //TODO if we want to allow them to be literally killed, probably should give them a heal if hero is out of FOV, or similar + + @Override + public int attackProc(Char enemy, int damage) { + Buff.affect(enemy, Poison.class).extend(6); + return super.attackProc(enemy, damage); + } + + @Override + public int attackSkill( Char target ) { + return 50; + } + + { + immunities.add( ToxicGas.class ); + immunities.add( Poison.class ); + } + + private class Waiting extends Mob.Wandering{ + + @Override + public boolean act( boolean enemyInFOV, boolean justAlerted ) { + //always notices the hero + if (enemyInFOV) { + + return noticeEnemy(); + + } else { + + return continueWandering(); + + } + } + + @Override + protected boolean noticeEnemy() { + spend(TICK); + return super.noticeEnemy(); + } + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/MagicMissile.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/MagicMissile.java index 5b807ff30..4a9561f44 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/MagicMissile.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/MagicMissile.java @@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.particles.CorrosionParti import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlameParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.LeafParticle; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.PoisonParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.PurpleParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.RainbowParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle; @@ -66,12 +67,12 @@ public class MagicMissile extends Emitter { public static final int RAINBOW = 8; public static final int EARTH = 9; public static final int WARD = 10; - public static final int SHAMAN_RED = 11; public static final int SHAMAN_BLUE = 12; public static final int SHAMAN_PURPLE = 13; public static final int TOXIC_VENT = 14; public static final int ELMO = 15; + public static final int POISON = 16; public static final int MAGIC_MISS_CONE = 100; public static final int FROST_CONE = 101; @@ -166,7 +167,6 @@ public class MagicMissile extends Emitter { size( 4 ); pour( WardParticle.FACTORY, 0.01f ); break; - case SHAMAN_RED: size( 2 ); pour( ShamanParticle.RED, 0.01f ); @@ -187,6 +187,10 @@ public class MagicMissile extends Emitter { size( 5 ); pour( ElmoParticle.FACTORY, 0.01f ); break; + case POISON: + size( 3 ); + pour( PoisonParticle.MISSILE, 0.01f ); + break; case MAGIC_MISS_CONE: size( 10 ); 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 4cc96866a..c28059625 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 @@ -22,9 +22,9 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CrystalGuardian; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.FungalSentry; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.GnollGuard; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.GnollSapper; -import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.RotLasher; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; @@ -199,11 +199,15 @@ public class MineLargeRoom extends CaveRoom { } Point p = center(); - RotLasher m = new RotLasher(); //placeholder enemy + FungalSentry m = new FungalSentry(); m.pos = level.pointToCell(p); level.mobs.add(m); Painter.set(level, p, Terrain.GRASS); + //no high grass directly above the sentry + p.y--; + Painter.set(level, p, Terrain.GRASS); + } else { Painter.fillEllipse(level, this, 3, Terrain.EMPTY); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/FungalSentrySprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/FungalSentrySprite.java new file mode 100644 index 000000000..a160147f6 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/FungalSentrySprite.java @@ -0,0 +1,98 @@ +/* + * 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.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.watabou.noosa.TextureFilm; +import com.watabou.utils.Callback; + +public class FungalSentrySprite extends CharSprite { + + private int cellToAttack; + + public FungalSentrySprite(){ + super(); + + texture(Assets.Sprites.FUNGAL_SENTRY ); + + TextureFilm frames = new TextureFilm( texture, 18, 18 ); + + idle = new Animation( 0, true ); + idle.frames( frames, 0); + + run = new Animation( 0, true ); + run.frames( frames, 0); + + attack = new Animation( 24, false ); + attack.frames( frames, 0 ); + + zap = attack.clone(); + + die = new Animation( 12, false ); + die.frames( frames, 0 ); + + play( idle ); + + } + + //TODO blood + + @Override + public void attack( int cell ) { + if (!Dungeon.level.adjacent( cell, ch.pos )) { + + cellToAttack = cell; + zap(cell); + + } else { + + super.attack( cell ); + + } + } + + @Override + public void onComplete( Animation anim ) { + if (anim == zap) { + idle(); + + MagicMissile.boltFromChar(parent, MagicMissile.POISON, this, cellToAttack, new Callback() { + @Override + public void call() { + ch.onAttackComplete(); + } + } ); + } else { + super.onComplete( anim ); + } + } + + public class ScorpioShot extends Item { + { + image = ItemSpriteSheet.FISHING_SPEAR; + } + } + +}