v2.5.0: added 3 common and 2 uncommon cursed wand effects

This commit is contained in:
Evan Debenham
2024-08-16 15:23:54 -04:00
parent 92905ae81c
commit 1b90092ad8
3 changed files with 130 additions and 3 deletions

View File

@@ -73,6 +73,7 @@ public class MagicMissile extends Emitter {
public static final int TOXIC_VENT = 14;
public static final int ELMO = 15;
public static final int POISON = 16;
public static final int BUBBLES = 17;
public static final int MAGIC_MISS_CONE = 100;
public static final int FROST_CONE = 101;
@@ -191,6 +192,10 @@ public class MagicMissile extends Emitter {
size( 3 );
pour( PoisonParticle.MISSILE, 0.01f );
break;
case BUBBLES:
size( 10 );
pour( Speck.factory(Speck.BUBBLE), 0.02f );
break;
case MAGIC_MISS_CONE:
size( 10 );

View File

@@ -76,7 +76,12 @@ import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfSir
import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.WondrousResin;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.BurningTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ChillingTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.CursingTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FlockTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GeyserTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ShockingTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.SummoningTrap;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.ConeAOE;
@@ -185,6 +190,9 @@ public class CursedWand {
COMMON_EFFECTS.add(new SpawnRegrowth());
COMMON_EFFECTS.add(new RandomTeleport());
COMMON_EFFECTS.add(new RandomGas());
COMMON_EFFECTS.add(new RandomAreaEffect());
COMMON_EFFECTS.add(new Bubbles());
COMMON_EFFECTS.add(new RandomWand());
}
public static CursedEffect randomCommonEffect(){
@@ -281,6 +289,90 @@ public class CursedWand {
}
}
public static class RandomAreaEffect extends CursedEffect {
@Override
public boolean effect(Item origin, Char user, Ballistica bolt, boolean positiveOnly) {
tryForWandProc(Actor.findChar(bolt.collisionPos), origin);
if (Actor.findChar(bolt.collisionPos) == null){
Dungeon.level.pressCell(bolt.collisionPos);
}
switch (Random.Int(3)) {
case 0: default:
new BurningTrap().set(bolt.collisionPos).activate();
return true;
case 1:
new ChillingTrap().set(bolt.collisionPos).activate();
return true;
case 2:
new ShockingTrap().set(bolt.collisionPos).activate();
return true;
}
}
}
public static class Bubbles extends CursedEffect {
@Override
public void FX(Item origin, Char user, Ballistica bolt, Callback callback) {
MagicMissile.boltFromChar(user.sprite.parent,
MagicMissile.BUBBLES,
user.sprite,
bolt.collisionPos,
callback);
Sample.INSTANCE.play( Assets.Sounds.ZAP );
}
@Override
public boolean effect(Item origin, Char user, Ballistica bolt, boolean positiveOnly) {
if (Actor.findChar(bolt.collisionPos) == null){
Dungeon.level.pressCell(bolt.collisionPos);
}
tryForWandProc(Actor.findChar(bolt.collisionPos), origin);
for (int i : PathFinder.NEIGHBOURS9){
if (!Dungeon.level.solid[bolt.collisionPos+i]){
CellEmitter.get(bolt.collisionPos+i).start(Speck.factory(Speck.BUBBLE), 0.25f, 40);
}
}
return true;
}
}
public static class RandomWand extends CursedEffect {
private Wand wand;
@Override
public boolean valid(Item origin, Char user, Ballistica bolt, boolean positiveOnly) {
//TODO we have this limit atm because some wands are coded to depend on their fx logic
// and chaos elementals trigger the effect directly, with no FX first
return super.valid(origin, user, bolt, positiveOnly) && user instanceof Hero;
}
@Override
public void FX(Item origin, Char user, Ballistica bolt, Callback callback) {
if (wand == null){
wand = (Wand)Generator.randomUsingDefaults(Generator.Category.WAND);
}
wand.fx(bolt, callback);
}
@Override
public boolean effect(Item origin, Char user, Ballistica bolt, boolean positiveOnly) {
if (wand == null){
wand = (Wand)Generator.randomUsingDefaults(Generator.Category.WAND);
}
if (origin instanceof Wand){
wand.upgrade(origin.level());
} else {
wand.upgrade(Dungeon.scalingDepth()/5);
}
wand.levelKnown = false;
wand.onZap(bolt);
wand = null;
return true;
}
}
//************************
//*** Uncommon Effects ***
//************************
@@ -291,6 +383,8 @@ public class CursedWand {
UNCOMMON_EFFECTS.add(new HealthTransfer());
UNCOMMON_EFFECTS.add(new Explosion());
UNCOMMON_EFFECTS.add(new LightningBolt());
UNCOMMON_EFFECTS.add(new Geyser());
UNCOMMON_EFFECTS.add(new SummonSheep());
}
public static CursedEffect randomUncommonEffect(){
@@ -324,6 +418,7 @@ public class CursedWand {
@Override
public boolean effect(Item origin, Char user, Ballistica bolt, boolean positiveOnly) {
if (valid(origin, user, bolt, positiveOnly)) {
tryForWandProc(Actor.findChar(bolt.collisionPos), origin);
Dungeon.level.plant((Plant.Seed) Generator.randomUsingDefaults(Generator.Category.SEED), bolt.collisionPos);
return true;
} else {
@@ -433,6 +528,8 @@ public class CursedWand {
}
}
tryForWandProc(Actor.findChar(bolt.collisionPos), origin);
for (Char ch : affected){
if (ch instanceof Hero) {
Buff.prolong(ch, Recharging.class, Recharging.DURATION/3f);
@@ -461,6 +558,27 @@ public class CursedWand {
}
}
public static class Geyser extends CursedEffect{
@Override
public boolean effect(Item origin, Char user, Ballistica bolt, boolean positiveOnly) {
tryForWandProc(Actor.findChar(bolt.collisionPos), origin);
GeyserTrap geyser = new GeyserTrap();
geyser.pos = bolt.collisionPos;
geyser.source = origin == null ? user : origin;
geyser.activate();
return true;
}
}
public static class SummonSheep extends CursedEffect{
@Override
public boolean effect(Item origin, Char user, Ballistica bolt, boolean positiveOnly) {
tryForWandProc(Actor.findChar(bolt.collisionPos), origin);
new FlockTrap().set(bolt.collisionPos).activate();
return true;
}
}
//********************
//*** Rare Effects ***
//********************
@@ -604,6 +722,8 @@ public class CursedWand {
boolean[] fieldOfView = new boolean[Dungeon.level.length()];
ShadowCaster.castShadow(c.x, c.y, Dungeon.level.width(), fieldOfView, Dungeon.level.solid, 3);
tryForWandProc(Actor.findChar(bolt.collisionPos), origin);
for (int i = 0; i < Dungeon.level.length(); i++){
if (fieldOfView[i] && !Dungeon.level.solid[i]){
//does not directly harm allies
@@ -688,6 +808,8 @@ public class CursedWand {
}
}
tryForWandProc(Actor.findChar(bolt.collisionPos), origin);
for (Char ch : affectedChars){
//positive only does not harm allies
if (positiveOnly && ch.alignment == Char.Alignment.ALLY){

View File

@@ -29,8 +29,8 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.journal.Bestiary;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.watabou.utils.BArray;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.BArray;
import com.watabou.utils.PathFinder;
import java.util.ArrayList;
@@ -72,10 +72,10 @@ public class FlockTrap extends Trap {
t.activate();
}
Dungeon.level.occupyCell(sheep);
Sample.INSTANCE.play(Assets.Sounds.PUFF);
Sample.INSTANCE.play(Assets.Sounds.SHEEP);
}
}
Sample.INSTANCE.play(Assets.Sounds.PUFF);
Sample.INSTANCE.play(Assets.Sounds.SHEEP);
}
}