v0.3.0: added wand of transfusion
This commit is contained in:
parent
610cffcb9e
commit
edadf3f38e
Binary file not shown.
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
@ -64,6 +64,12 @@ public class Beam extends Image {
|
|||
super(s, e, Effects.Type.LIGHT_RAY, 1f);
|
||||
}
|
||||
}
|
||||
|
||||
public static class HealthRay extends Beam{
|
||||
public HealthRay(PointF s, PointF e){
|
||||
super(s, e, Effects.Type.HEALTH_RAY, 0.75f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
|
|
@ -28,7 +28,8 @@ public class Effects {
|
|||
WOUND,
|
||||
EXCLAMATION,
|
||||
DEATH_RAY,
|
||||
LIGHT_RAY
|
||||
LIGHT_RAY,
|
||||
HEALTH_RAY
|
||||
};
|
||||
|
||||
public static Image get( Type type ) {
|
||||
|
@ -52,6 +53,9 @@ public class Effects {
|
|||
case LIGHT_RAY:
|
||||
icon.frame(icon.texture.uvRect(16, 23, 32, 31));
|
||||
break;
|
||||
case HEALTH_RAY:
|
||||
icon.frame(icon.texture.uvRect(16, 30, 32, 38));
|
||||
break;
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ package com.shatteredpixel.shatteredpixeldungeon.effects.particles;
|
|||
import com.watabou.noosa.particles.Emitter;
|
||||
import com.watabou.noosa.particles.PixelParticle;
|
||||
import com.watabou.noosa.particles.Emitter.Factory;
|
||||
import com.watabou.utils.PointF;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class BloodParticle extends PixelParticle.Shrinking {
|
||||
|
||||
|
@ -29,6 +31,17 @@ public class BloodParticle extends PixelParticle.Shrinking {
|
|||
((BloodParticle)emitter.recycle( BloodParticle.class )).reset( x, y );
|
||||
}
|
||||
};
|
||||
|
||||
public static final Emitter.Factory BURST = new Factory() {
|
||||
@Override
|
||||
public void emit( Emitter emitter, int index, float x, float y ) {
|
||||
((BloodParticle)emitter.recycle( BloodParticle.class )).resetBurst( x, y );
|
||||
}
|
||||
@Override
|
||||
public boolean lightMode() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
public BloodParticle() {
|
||||
super();
|
||||
|
@ -50,6 +63,18 @@ public class BloodParticle extends PixelParticle.Shrinking {
|
|||
size = 4;
|
||||
speed.set( 0 );
|
||||
}
|
||||
|
||||
public void resetBurst( float x, float y ) {
|
||||
revive();
|
||||
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
||||
speed.polar( Random.Float(PointF.PI2), Random.Float( 16, 32 ) );
|
||||
size = 5;
|
||||
|
||||
left = 0.5f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
|
|
@ -127,10 +127,10 @@ public class Generator {
|
|||
WandOfFrost.class,
|
||||
WandOfPrismaticLight.class,
|
||||
//WandOfWarding.class,
|
||||
//WandOfTransfusion.class,
|
||||
WandOfTransfusion.class,
|
||||
//WandOfCorruption.class,
|
||||
WandOfRegrowth.class };
|
||||
Category.WAND.probs = new float[]{ 4, 4, 4, 4, 4, 3, /*3,*/ 3, 3, /*3, 3, 3,*/ 3 };
|
||||
Category.WAND.probs = new float[]{ 4, 4, 4, 4, 4, 3, /*3,*/ 3, 3, /*3,*/ 3, /*3,*/ 3 };
|
||||
|
||||
Category.WEAPON.classes = new Class<?>[]{
|
||||
Dagger.class,
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.DungeonTilemap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ResultDescriptions;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.*;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Ghost;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Beam;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BloodParticle;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.LeafParticle;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.Utils;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.utils.Callback;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Created by debenhame on 13/05/2015.
|
||||
*/
|
||||
public class WandOfTransfusion extends Wand {
|
||||
|
||||
{
|
||||
name = "Wand of Transfusion";
|
||||
image = ItemSpriteSheet.WAND_TRANSFUSION;
|
||||
|
||||
collisionProperties = Ballistica.PROJECTILE;
|
||||
}
|
||||
|
||||
private boolean freeCharge = false;
|
||||
|
||||
//FIXME: this is sloppy
|
||||
private static HashSet<Class> undeadMobs = new HashSet<Class>(Arrays.asList(
|
||||
//Any Location
|
||||
Wraith.class,
|
||||
//Sewers
|
||||
Ghost.FetidRat.class,
|
||||
//Prison
|
||||
Skeleton.class,
|
||||
//City
|
||||
Warlock.class, Monk.class, Senior.class,
|
||||
King.class, King.Undead.class,
|
||||
//Halls
|
||||
Succubus.class,
|
||||
Yog.RottingFist.class
|
||||
));
|
||||
|
||||
@Override
|
||||
protected void onZap(Ballistica beam) {
|
||||
|
||||
for (int c : beam.subPath(0, beam.dist))
|
||||
CellEmitter.center(c).burst( BloodParticle.BURST, 1 );
|
||||
|
||||
int cell = beam.collisionPos;
|
||||
|
||||
Char ch = Actor.findChar(cell);
|
||||
Heap heap = Dungeon.level.heaps.get(cell);
|
||||
|
||||
//this wand does a bunch of different things depending on what it targets.
|
||||
|
||||
//if we find a character..
|
||||
if (ch != null && ch instanceof Mob){
|
||||
|
||||
//heals an ally, or charmed/corrupted enemy
|
||||
//TODO: add corruption here
|
||||
if (((Mob) ch).ally || ch.buff(Charm.class) != null){
|
||||
|
||||
int missingHP = ch.HT - ch.HP;
|
||||
//heals 30%+3%*lvl missing HP.
|
||||
int healing = (int)Math.ceil((missingHP * (0.30f+(0.03f*level))));
|
||||
ch.HP += healing;
|
||||
ch.sprite.emitter().burst(Speck.factory(Speck.HEALING), 1 + level / 2);
|
||||
ch.sprite.showStatus(CharSprite.POSITIVE, "+%dHP", healing);
|
||||
|
||||
//harms the undead
|
||||
} else if (undeadMobs.contains(ch.getClass())){
|
||||
|
||||
//deals 30%+5%*lvl total HP.
|
||||
int damage = (int) Math.ceil(ch.HT*(0.3f+(0.05f*level)));
|
||||
ch.damage(damage, this);
|
||||
ch.sprite.emitter().start(ShadowParticle.UP, 0.05f, 10 + level);
|
||||
Sample.INSTANCE.play(Assets.SND_BURNING);
|
||||
|
||||
//charms an enemy
|
||||
} else {
|
||||
|
||||
float duration = 5+level;
|
||||
Buff.affect(ch, Charm.class, Charm.durationFactor(ch) * duration).object = curUser.id();
|
||||
|
||||
duration *= Random.Float(0.75f, 1f);
|
||||
Buff.affect(curUser, Charm.class, Charm.durationFactor(ch) * duration).object = curUser.id();
|
||||
|
||||
ch.sprite.centerEmitter().start( Speck.factory( Speck.HEART ), 0.2f, 5 );
|
||||
curUser.sprite.centerEmitter().start( Speck.factory( Speck.HEART ), 0.2f, 5 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
//if we find an item...
|
||||
} else if (heap != null && heap.type == Heap.Type.HEAP){
|
||||
Item item = heap.peek();
|
||||
|
||||
//30% + 10%*lvl chance to uncurse the item and reset it to base level if degraded.
|
||||
if (item != null && Random.Float() <= 0.3f+level*0.1f){
|
||||
if (item.cursed){
|
||||
item.cursed = false;
|
||||
CellEmitter.get(cell).start( ShadowParticle.UP, 0.05f, 10 );
|
||||
Sample.INSTANCE.play(Assets.SND_BURNING);
|
||||
}
|
||||
|
||||
int lvldiffFromBase = item.level - (item instanceof Ring ? 1 : 0);
|
||||
if (lvldiffFromBase < 0){
|
||||
item.upgrade(-lvldiffFromBase);
|
||||
CellEmitter.get(cell).start(Speck.factory(Speck.UP), 0.2f, 3);
|
||||
Sample.INSTANCE.play(Assets.SND_EVOKE);
|
||||
}
|
||||
}
|
||||
|
||||
//if we find some trampled grass...
|
||||
} else if (Dungeon.level.map[cell] == Terrain.GRASS) {
|
||||
|
||||
//regrow one grass tile, suuuuuper useful...
|
||||
Dungeon.level.set(cell, Terrain.HIGH_GRASS);
|
||||
GameScene.updateMap(cell);
|
||||
CellEmitter.get( cell ).burst(LeafParticle.LEVEL_SPECIFIC, 4);
|
||||
|
||||
//If we find embers...
|
||||
} else if (Dungeon.level.map[cell] == Terrain.EMBERS) {
|
||||
|
||||
//30% + 3%*lvl chance to grow a random plant, or just regrow grass.
|
||||
if (Random.Float() <= 0.3f+level*0.03f) {
|
||||
Dungeon.level.plant((Plant.Seed) Generator.random(Generator.Category.SEED), cell);
|
||||
CellEmitter.get( cell ).burst(LeafParticle.LEVEL_SPECIFIC, 8);
|
||||
GameScene.updateMap(cell);
|
||||
} else{
|
||||
Dungeon.level.set(cell, Terrain.HIGH_GRASS);
|
||||
GameScene.updateMap(cell);
|
||||
CellEmitter.get( cell ).burst(LeafParticle.LEVEL_SPECIFIC, 4);
|
||||
}
|
||||
|
||||
} else
|
||||
return; //don't damage the hero if we can't find a target;
|
||||
|
||||
if (!freeCharge) {
|
||||
damageHero();
|
||||
} else {
|
||||
freeCharge = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//this wand costs health too
|
||||
private void damageHero(){
|
||||
// 15% of max hp
|
||||
int damage = (int)Math.ceil(curUser.HT*0.15f);
|
||||
curUser.damage(damage, this);
|
||||
|
||||
if (!curUser.isAlive()){
|
||||
Dungeon.fail( Utils.format(ResultDescriptions.ITEM, name) );
|
||||
GLog.n("You killed yourself with your own Wand of Transfusion...");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int initialCharges() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHit(MagesStaff staff, Char attacker, Char defender, int damage) {
|
||||
// lvl 0 - 10%
|
||||
// lvl 1 - 18%
|
||||
// lvl 2 - 25%
|
||||
if (Random.Int( level + 10 ) >= 9){
|
||||
//grants a free use of the staff
|
||||
freeCharge = true;
|
||||
GLog.p("Your staff is charged with the life energy of your enemy!");
|
||||
attacker.sprite.emitter().burst(BloodParticle.BURST, 20);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fx(Ballistica beam, Callback callback) {
|
||||
curUser.sprite.parent.add(
|
||||
new Beam.HealthRay(curUser.sprite.center(), DungeonTilemap.tileCenterToWorld(beam.collisionPos)));
|
||||
callback.call();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String desc() {
|
||||
return "A fairly plainly shaped wand, it stands out due to its magenta hue and pitch black gem at the tip.\n" +
|
||||
"\n" +
|
||||
"This wand will take some of your life energy and blast it at a target. This effect is very versatile: " +
|
||||
"allies will be healed, enemies will be temporarily charmed, and hostile undead will take considerable damage. " +
|
||||
"The life force effect can also be potent at dispelling curses as well. " +
|
||||
"The life energy drain is significant though, using this wand will deal damage to you in addition to consuming charges.";
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user