v2.3.0: added fungal spinners, with WIP visuals and bare mechanics

This commit is contained in:
Evan Debenham
2023-12-18 14:50:01 -05:00
parent 8b96d29e8a
commit bc4663e81d
7 changed files with 190 additions and 6 deletions

View File

@@ -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.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.
actors.mobs.ghoul.name=dwarven ghoul
actors.mobs.ghoul.desc=As dwarven society slowly began to collapse, and the current king of the dwarves seized absolute power, those who were weak or who resisted him were not treated well. As the king grew more adept at wielding dark magic, he bent these dwarves to his will, and now they make up the footsoldiers of his army.\n\nGhouls are not especially strong on their own, but always travel in groups and are much harder to kill in large numbers. _When a ghoul is defeated, it will rise again after a few turns as long as another ghoul is nearby._

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

View File

@@ -321,5 +321,6 @@ public class Assets {
public static final String GNOLL_GUARD= "sprites/gnoll_guard.png";
public static final String GNOLL_SAPPER= "sprites/gnoll_sapper.png";
public static final String GNOLL_GEOMANCER = "sprites/gnoll_geomancer.png";
public static final String FUNGAL_SPINNER = "sprites/fungal_spinner.png";
}
}

View File

@@ -0,0 +1,74 @@
/*
* 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 <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Regrowth;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.FungalSpinnerSprite;
import com.watabou.utils.PathFinder;
public class FungalSpinner extends Spinner {
{
spriteClass = FungalSpinnerSprite.class;
HP = HT = 40;
defenseSkill = 16;
EXP = 7;
maxLvl = -2;
}
@Override
protected void applyWebToCell(int cell) {
GameScene.add(Blob.seed(cell, 40, Regrowth.class));
}
@Override
public void damage(int dmg, Object src) {
int grassCells = 0;
for (int i : PathFinder.NEIGHBOURS9) {
if (Dungeon.level.map[pos+i] == Terrain.FURROWED_GRASS
|| Dungeon.level.map[pos+i] == Terrain.HIGH_GRASS){
grassCells++;
}
}
//first adjacent grass cell reduces damage taken by 30%, each one after reduces by another 10%
if (grassCells > 0) dmg = Math.round(dmg * (8-grassCells)/10f);
super.damage(dmg, src);
}
@Override
public int attackProc(Char enemy, int damage) {
return damage; //does not apply poison
}
{
immunities.add(Regrowth.class);
}
}

View File

@@ -191,9 +191,9 @@ public class Spinner extends Mob {
int leftPos = enemy.pos + PathFinder.CIRCLE8[left(i)];
int rightPos = enemy.pos + PathFinder.CIRCLE8[right(i)];
if (Dungeon.level.passable[leftPos]) GameScene.add(Blob.seed(leftPos, 20, Web.class));
if (Dungeon.level.passable[webPos]) GameScene.add(Blob.seed(webPos, 20, Web.class));
if (Dungeon.level.passable[rightPos])GameScene.add(Blob.seed(rightPos, 20, Web.class));
if (Dungeon.level.passable[leftPos]) applyWebToCell(leftPos);
if (Dungeon.level.passable[webPos]) applyWebToCell(webPos);
if (Dungeon.level.passable[rightPos])applyWebToCell(rightPos);
webCoolDown = 10;
@@ -203,6 +203,10 @@ public class Spinner extends Mob {
}
next();
}
protected void applyWebToCell(int cell){
GameScene.add(Blob.seed(cell, 20, Web.class));
}
private int left(int direction){
return direction == 0 ? 7 : direction-1;

View File

@@ -28,9 +28,9 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
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.FungalSpinner;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.GnollGuard;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Spinner;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
@@ -152,7 +152,7 @@ public class MiningLevel extends CavesLevel {
case Blacksmith.Quest.GNOLL:
return new GnollGuard();
case Blacksmith.Quest.FUNGI:
return new Spinner();
return new FungalSpinner();
}
}

View File

@@ -0,0 +1,102 @@
/*
* 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 <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.sprites;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Spinner;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.watabou.noosa.MovieClip;
import com.watabou.noosa.TextureFilm;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Callback;
public class FungalSpinnerSprite extends MobSprite {
public FungalSpinnerSprite() {
super();
perspectiveRaise = 0f;
texture( Assets.Sprites.FUNGAL_SPINNER );
TextureFilm frames = new TextureFilm( texture, 16, 16 );
idle = new MovieClip.Animation( 10, true );
idle.frames( frames, 0, 0, 0, 0, 0, 1, 0, 1 );
run = new MovieClip.Animation( 15, true );
run.frames( frames, 0, 2, 0, 3 );
attack = new MovieClip.Animation( 12, false );
attack.frames( frames, 0, 4, 5, 0 );
zap = attack.clone();
die = new MovieClip.Animation( 12, false );
die.frames( frames, 6, 7, 8, 9 );
play( idle );
}
@Override
public void link(Char ch) {
super.link(ch);
if (parent != null) {
parent.sendToBack(this);
if (aura != null){
parent.sendToBack(aura);
}
}
renderShadow = false;
}
public void zap( int cell ) {
super.zap( cell );
MagicMissile.boltFromChar( parent,
MagicMissile.FOLIAGE,
this,
cell,
new Callback() {
@Override
public void call() {
((Spinner)ch).shootWeb();
}
} );
Sample.INSTANCE.play( Assets.Sounds.MISS );
}
@Override
public void onComplete( MovieClip.Animation anim ) {
if (anim == zap) {
play( run );
}
super.onComplete( anim );
}
@Override
public int blood() {
return 0xFF88CC44;
}
}