v0.7.4: initial implementation for wand of warding
This commit is contained in:
parent
b8490b5b29
commit
545cda0bba
BIN
core/src/main/assets/wards.png
Normal file
BIN
core/src/main/assets/wards.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 279 B |
|
@ -97,6 +97,7 @@ public class Assets {
|
|||
public static final String ROT_LASH = "rot_lasher.png";
|
||||
public static final String ROT_HEART= "rot_heart.png";
|
||||
public static final String GUARD = "guard.png";
|
||||
public static final String WARDS = "wards.png";
|
||||
|
||||
public static final String ITEMS = "items.png";
|
||||
public static final String TERRAIN_FEATURES = "terrain_features.png";
|
||||
|
|
|
@ -131,6 +131,10 @@ public abstract class Char extends Actor {
|
|||
Dungeon.level.updateFieldOfView( this, fieldOfView );
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canInteract( Hero h ){
|
||||
return Dungeon.level.adjacent( pos, h.pos );
|
||||
}
|
||||
|
||||
//swaps places by default
|
||||
public boolean interact(){
|
||||
|
|
|
@ -630,7 +630,7 @@ public class Hero extends Char {
|
|||
|
||||
Char ch = action.ch;
|
||||
|
||||
if (Dungeon.level.adjacent( pos, ch.pos )) {
|
||||
if (ch.canInteract(this)) {
|
||||
|
||||
ready();
|
||||
sprite.turnTo( pos, ch.pos );
|
||||
|
|
|
@ -59,6 +59,7 @@ public class MagicMissile extends Emitter {
|
|||
public static final int SHADOW = 7;
|
||||
public static final int RAINBOW = 8;
|
||||
public static final int EARTH = 9;
|
||||
public static final int WARD = 10;
|
||||
|
||||
public static final int FIRE_CONE = 100;
|
||||
public static final int FOLIAGE_CONE = 101;
|
||||
|
@ -138,6 +139,10 @@ public class MagicMissile extends Emitter {
|
|||
size( 4 );
|
||||
pour( EarthParticle.FACTORY, 0.01f );
|
||||
break;
|
||||
case WARD:
|
||||
size( 4 );
|
||||
pour( WardParticle.FACTORY, 0.01f );
|
||||
break;
|
||||
|
||||
case FIRE_CONE:
|
||||
size( 10 );
|
||||
|
@ -416,26 +421,37 @@ public class MagicMissile extends Emitter {
|
|||
am = (1 - left / lifespan) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ColdParticle extends PixelParticle.Shrinking {
|
||||
|
||||
public static class WardParticle extends PixelParticle.Shrinking {
|
||||
|
||||
public static final Emitter.Factory FACTORY = new Factory() {
|
||||
@Override
|
||||
public void emit( Emitter emitter, int index, float x, float y ) {
|
||||
((ColdParticle)emitter.recycle( ColdParticle.class )).reset( x, y );
|
||||
((WardParticle)emitter.recycle( WardParticle.class )).reset( x, y );
|
||||
}
|
||||
@Override
|
||||
public boolean lightMode() {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
public static final Emitter.Factory UP = new Factory() {
|
||||
@Override
|
||||
public void emit( Emitter emitter, int index, float x, float y ) {
|
||||
((WardParticle)emitter.recycle( WardParticle.class )).resetUp( x, y );
|
||||
}
|
||||
@Override
|
||||
public boolean lightMode() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
public ColdParticle() {
|
||||
public WardParticle() {
|
||||
super();
|
||||
|
||||
lifespan = 0.6f;
|
||||
|
||||
color( 0x2244FF );
|
||||
color( 0x8822FF );
|
||||
}
|
||||
|
||||
public void reset( float x, float y ) {
|
||||
|
@ -447,6 +463,12 @@ public class MagicMissile extends Emitter {
|
|||
left = lifespan;
|
||||
size = 8;
|
||||
}
|
||||
|
||||
public void resetUp( float x, float y){
|
||||
reset(x, y);
|
||||
|
||||
speed.set( Random.Float( -8, +8 ), Random.Float( -32, -48 ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
|
|
@ -106,10 +106,12 @@ import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfDisintegration
|
|||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfFireblast;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfFrost;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfLightning;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfLivingEarth;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfMagicMissile;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfPrismaticLight;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfRegrowth;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfTransfusion;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfWarding;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.AssassinsBlade;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.BattleAxe;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Crossbow;
|
||||
|
@ -296,8 +298,7 @@ public class Generator {
|
|||
StoneOfShock.class
|
||||
};
|
||||
STONE.probs = new float[]{ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
|
||||
|
||||
//TODO: add last ones when implemented
|
||||
|
||||
WAND.classes = new Class<?>[]{
|
||||
WandOfMagicMissile.class,
|
||||
WandOfLightning.class,
|
||||
|
@ -305,14 +306,14 @@ public class Generator {
|
|||
WandOfFireblast.class,
|
||||
WandOfCorrosion.class,
|
||||
WandOfBlastWave.class,
|
||||
//WandOfLivingEarth.class,
|
||||
WandOfLivingEarth.class,
|
||||
WandOfFrost.class,
|
||||
WandOfPrismaticLight.class,
|
||||
//WandOfWarding.class,
|
||||
WandOfWarding.class,
|
||||
WandOfTransfusion.class,
|
||||
WandOfCorruption.class,
|
||||
WandOfRegrowth.class };
|
||||
WAND.probs = new float[]{ 5, 4, 4, 4, 4, 3, /*3,*/ 3, 3, /*3,*/ 3, 3, 3 };
|
||||
WAND.probs = new float[]{ 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3 };
|
||||
|
||||
//see generator.randomWeapon
|
||||
WEAPON.classes = new Class<?>[]{};
|
||||
|
|
|
@ -111,6 +111,21 @@ public abstract class Wand extends Item {
|
|||
|
||||
public abstract void onHit( MagesStaff staff, Char attacker, Char defender, int damage);
|
||||
|
||||
public boolean tryToZap( Hero owner ){
|
||||
|
||||
if (owner.buff(MagicImmune.class) != null){
|
||||
GLog.w( Messages.get(this, "no_magic") );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( curCharges >= (cursed ? 1 : chargesPerCast())){
|
||||
return true;
|
||||
} else {
|
||||
GLog.w(Messages.get(this, "fizzles"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collect( Bag container ) {
|
||||
if (super.collect( container )) {
|
||||
|
@ -411,9 +426,6 @@ public abstract class Wand extends Item {
|
|||
if (target == curUser.pos || cell == curUser.pos) {
|
||||
GLog.i( Messages.get(Wand.class, "self_target") );
|
||||
return;
|
||||
} else if (curUser.buff(MagicImmune.class) != null){
|
||||
GLog.w( Messages.get(Wand.class, "no_magic") );
|
||||
return;
|
||||
}
|
||||
|
||||
curUser.sprite.zap(cell);
|
||||
|
@ -424,7 +436,7 @@ public abstract class Wand extends Item {
|
|||
else
|
||||
QuickSlotButton.target(Actor.findChar(cell));
|
||||
|
||||
if (curWand.curCharges >= (curWand.cursed ? 1 : curWand.chargesPerCast())) {
|
||||
if (curWand.tryToZap(curUser)) {
|
||||
|
||||
curUser.busy();
|
||||
Invisibility.dispel();
|
||||
|
@ -452,10 +464,6 @@ public abstract class Wand extends Item {
|
|||
}
|
||||
curWand.cursedKnown = true;
|
||||
|
||||
} else {
|
||||
|
||||
GLog.w( Messages.get(Wand.class, "fizzles") );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,329 @@
|
|||
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.NPC;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.WardSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.Callback;
|
||||
import com.watabou.utils.PathFinder;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class WandOfWarding extends Wand {
|
||||
|
||||
{
|
||||
collisionProperties = Ballistica.STOP_TARGET | Ballistica.STOP_TERRAIN;
|
||||
|
||||
image = ItemSpriteSheet.WAND_WARDING;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onZap(Ballistica bolt) {
|
||||
|
||||
int currentWardLevels = 0;
|
||||
for (Char ch : Actor.chars()){
|
||||
if (ch instanceof Ward){
|
||||
currentWardLevels += ((Ward) ch).tier;
|
||||
}
|
||||
}
|
||||
boolean canPlaceMore = currentWardLevels < level()+2;
|
||||
|
||||
Char ch = Actor.findChar(bolt.collisionPos);
|
||||
if (ch != null){
|
||||
if (ch instanceof Ward){
|
||||
if (canPlaceMore) {
|
||||
((Ward) ch).upgrade(level());
|
||||
} else {
|
||||
if (((Ward) ch).tier <= 3){
|
||||
GLog.w("Your wand can't sustain any more wards.");
|
||||
} else {
|
||||
((Ward) ch).wandHeal( level() );
|
||||
}
|
||||
}
|
||||
ch.sprite.emitter().burst(MagicMissile.WardParticle.UP, ((Ward) ch).tier);
|
||||
} else {
|
||||
GLog.w("There isn't room to place a ward here");
|
||||
}
|
||||
} else if (canPlaceWard(bolt.collisionPos)){
|
||||
if (canPlaceMore) {
|
||||
Ward ward = new Ward();
|
||||
ward.pos = bolt.collisionPos;
|
||||
GameScene.add(ward, 1f);
|
||||
ward.sprite.emitter().burst(MagicMissile.WardParticle.UP, ward.tier);
|
||||
QuickSlotButton.target(ward);
|
||||
} else {
|
||||
GLog.w("Your wand can't sustain any more wards.");
|
||||
}
|
||||
} else {
|
||||
GLog.w("There isn't room to place a ward here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fx(Ballistica bolt, Callback callback) {
|
||||
MagicMissile.boltFromChar(curUser.sprite.parent,
|
||||
MagicMissile.WARD,
|
||||
curUser.sprite,
|
||||
bolt.collisionPos,
|
||||
callback);
|
||||
Sample.INSTANCE.play(Assets.SND_ZAP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHit(MagesStaff staff, Char attacker, Char defender, int damage) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void staffFx(MagesStaff.StaffParticle particle) {
|
||||
//TODO
|
||||
super.staffFx(particle);
|
||||
}
|
||||
|
||||
public static boolean canPlaceWard(int pos){
|
||||
|
||||
int adjacentBlockedCells = 0;
|
||||
int adjacentCellGroups = 0;
|
||||
boolean prevOpen = openCell(pos + PathFinder.CIRCLE8[PathFinder.CIRCLE8.length-1]);
|
||||
|
||||
for (int i : PathFinder.CIRCLE8){
|
||||
if (!openCell(pos + i)){
|
||||
adjacentBlockedCells++;
|
||||
}
|
||||
if (prevOpen != openCell(pos + i)){
|
||||
prevOpen = !prevOpen;
|
||||
adjacentCellGroups++;
|
||||
}
|
||||
}
|
||||
|
||||
switch (adjacentBlockedCells){
|
||||
case 0: case 1:
|
||||
return true;
|
||||
case 2:
|
||||
return (openCell(pos + PathFinder.CIRCLE4[0]) || openCell( pos + PathFinder.CIRCLE4[2]))
|
||||
&& (openCell(pos + PathFinder.CIRCLE4[1]) || openCell( pos + PathFinder.CIRCLE4[3]));
|
||||
case 3:
|
||||
return adjacentCellGroups <= 2;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean openCell(int pos){
|
||||
//a cell is considered blocked if it isn't passable or a ward is there
|
||||
return Dungeon.level.passable[pos] && !(Actor.findChar(pos) instanceof Ward);
|
||||
}
|
||||
|
||||
public static class Ward extends NPC {
|
||||
|
||||
private int tier = 1;
|
||||
private int wandLevel = 1;
|
||||
|
||||
private int totalZaps = 0;
|
||||
|
||||
{
|
||||
spriteClass = WardSprite.class;
|
||||
|
||||
alignment = Alignment.ALLY;
|
||||
|
||||
properties.add(Property.IMMOVABLE);
|
||||
|
||||
viewDistance = 3;
|
||||
state = WANDERING;
|
||||
}
|
||||
|
||||
public void upgrade( int wandLevel ){
|
||||
if (this.wandLevel < wandLevel){
|
||||
this.wandLevel = wandLevel;
|
||||
}
|
||||
|
||||
wandHeal(0);
|
||||
|
||||
switch (tier){
|
||||
case 1: case 2: default:
|
||||
break; //do nothing
|
||||
case 3:
|
||||
HP = HT = 30;
|
||||
break;
|
||||
case 4:
|
||||
HT = 48;
|
||||
HP = Math.round(48*(HP/30f));
|
||||
break;
|
||||
case 5:
|
||||
HT = 72;
|
||||
HP = Math.round(72*(HP/48f));
|
||||
break;
|
||||
}
|
||||
|
||||
if (tier < 6){
|
||||
tier++;
|
||||
viewDistance++;
|
||||
updateSpriteState();
|
||||
}
|
||||
}
|
||||
|
||||
private void wandHeal( int wandLevel ){
|
||||
if (this.wandLevel < wandLevel){
|
||||
this.wandLevel = wandLevel;
|
||||
}
|
||||
|
||||
switch(tier){
|
||||
default:
|
||||
break;
|
||||
case 4:
|
||||
HP = Math.min(HT, HP+6);
|
||||
break;
|
||||
case 5:
|
||||
HP = Math.min(HT, HP+8);
|
||||
break;
|
||||
case 6:
|
||||
HP = Math.min(HT, HP+12);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float attackDelay() {
|
||||
switch (tier){
|
||||
case 1: case 2: default:
|
||||
return 2f;
|
||||
case 3: case 4:
|
||||
return 1.5f;
|
||||
case 5: case 6:
|
||||
return 1f;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canAttack( Char enemy ) {
|
||||
return new Ballistica( pos, enemy.pos, Ballistica.MAGIC_BOLT).collisionPos == enemy.pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doAttack(Char enemy) {
|
||||
boolean visible = fieldOfView[pos] || fieldOfView[enemy.pos];
|
||||
if (visible) {
|
||||
sprite.zap( enemy.pos );
|
||||
} else {
|
||||
zap();
|
||||
}
|
||||
|
||||
return !visible;
|
||||
}
|
||||
|
||||
private void zap() {
|
||||
spend( 1f );
|
||||
|
||||
//always hits
|
||||
int dmg = Random.Int( 2 + wandLevel, 8 + 4*wandLevel );
|
||||
enemy.damage( dmg, WandOfWarding.class );
|
||||
|
||||
if (!enemy.isAlive() && enemy == Dungeon.hero) {
|
||||
Dungeon.fail( getClass() );
|
||||
}
|
||||
|
||||
totalZaps++;
|
||||
switch(tier){
|
||||
default:
|
||||
if (totalZaps >= tier){
|
||||
die(this);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (totalZaps >= 4){
|
||||
die(this);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
damage(6, this);
|
||||
break;
|
||||
case 5:
|
||||
damage(8, this);
|
||||
break;
|
||||
case 6:
|
||||
damage(9, this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void onZapComplete() {
|
||||
zap();
|
||||
next();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getCloser(int target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getFurther(int target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSprite sprite() {
|
||||
WardSprite sprite = (WardSprite) super.sprite();
|
||||
sprite.updateTier(tier);
|
||||
return sprite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSpriteState() {
|
||||
super.updateSpriteState();
|
||||
((WardSprite)sprite).updateTier(tier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteract(Hero h) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean interact() {
|
||||
GameScene.show(new WndOptions("test", "dismiss this ward?", "yes", "no"){
|
||||
@Override
|
||||
protected void onSelect(int index) {
|
||||
if (index == 0){
|
||||
die(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final String TIER = "tier";
|
||||
private static final String WAND_LEVEL = "wand_level";
|
||||
private static final String TOTAL_ZAPS = "total_zaps";
|
||||
|
||||
@Override
|
||||
public void storeInBundle(Bundle bundle) {
|
||||
super.storeInBundle(bundle);
|
||||
bundle.put(TIER, tier);
|
||||
bundle.put(WAND_LEVEL, wandLevel);
|
||||
bundle.put(TOTAL_ZAPS, totalZaps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle(Bundle bundle) {
|
||||
super.restoreFromBundle(bundle);
|
||||
tier = bundle.getInt(TIER);
|
||||
wandLevel = bundle.getInt(WAND_LEVEL);
|
||||
totalZaps = bundle.getInt(TOTAL_ZAPS);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,6 +57,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfStrength;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfEnchantment;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfIntuition;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfWarding;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Door;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.HighGrass;
|
||||
|
@ -976,6 +977,22 @@ public abstract class Level implements Bundlable {
|
|||
fieldOfView[p+i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (Mob ward : mobs){
|
||||
if (ward instanceof WandOfWarding.Ward){
|
||||
if (ward.fieldOfView == null || ward.fieldOfView.length != length()){
|
||||
ward.fieldOfView = new boolean[length()];
|
||||
Dungeon.level.updateFieldOfView( ward, ward.fieldOfView );
|
||||
}
|
||||
for (Mob m : mobs){
|
||||
if (ward.fieldOfView[m.pos] && !fieldOfView[m.pos] &&
|
||||
!Dungeon.hero.mindVisionEnemies.contains(m)){
|
||||
Dungeon.hero.mindVisionEnemies.add(m);
|
||||
}
|
||||
}
|
||||
BArray.or(fieldOfView, ward.fieldOfView, fieldOfView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (c == Dungeon.hero) {
|
||||
|
|
|
@ -54,6 +54,7 @@ public class SpinnerSprite extends MobSprite {
|
|||
@Override
|
||||
public void link(Char ch) {
|
||||
super.link(ch);
|
||||
if (parent != null) parent.sendToBack(this);
|
||||
renderShadow = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
package com.shatteredpixel.shatteredpixeldungeon.sprites;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Beam;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfWarding;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.tweeners.AlphaTweener;
|
||||
|
||||
public class WardSprite extends MobSprite {
|
||||
|
||||
private Animation tierIdles[] = new Animation[7];
|
||||
|
||||
public WardSprite(){
|
||||
super();
|
||||
|
||||
texture(Assets.WARDS);
|
||||
|
||||
tierIdles[1] = new Animation( 1, true );
|
||||
tierIdles[1].frames(texture.uvRect(0, 0, 9, 10));
|
||||
|
||||
tierIdles[2] = new Animation( 1, true );
|
||||
tierIdles[2].frames(texture.uvRect(10, 0, 21, 12));
|
||||
|
||||
tierIdles[3] = new Animation( 1, true );
|
||||
tierIdles[3].frames(texture.uvRect(22, 0, 37, 16));
|
||||
|
||||
tierIdles[4] = new Animation( 1, true );
|
||||
tierIdles[4].frames(texture.uvRect(38, 0, 44, 13));
|
||||
|
||||
tierIdles[5] = new Animation( 1, true );
|
||||
tierIdles[5].frames(texture.uvRect(45, 0, 51, 15));
|
||||
|
||||
tierIdles[6] = new Animation( 1, true );
|
||||
tierIdles[6].frames(texture.uvRect(52, 0, 60, 15));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zap( int pos ) {
|
||||
idle();
|
||||
flash();
|
||||
emitter().burst(MagicMissile.WardParticle.UP, 2);
|
||||
if (Actor.findChar(pos) != null){
|
||||
parent.add(new Beam.DeathRay(center(), Actor.findChar(pos).sprite.center()));
|
||||
} else {
|
||||
parent.add(new Beam.DeathRay(center(), DungeonTilemap.raisedTileCenterToWorld(pos)));
|
||||
}
|
||||
((WandOfWarding.Ward)ch).onZapComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void die() {
|
||||
super.die();
|
||||
//cancels die animation and fades out immediately
|
||||
play(idle, true);
|
||||
emitter().burst(MagicMissile.WardParticle.UP, 10);
|
||||
parent.add( new AlphaTweener( this, 0, 2f ) {
|
||||
@Override
|
||||
protected void onComplete() {
|
||||
WardSprite.this.killAndErase();
|
||||
parent.erase( this );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
public void updateTier(int tier){
|
||||
|
||||
idle = tierIdles[tier];
|
||||
run = idle.clone();
|
||||
//zap = idle.clone();
|
||||
//attack = idle.clone();
|
||||
die = idle.clone();
|
||||
|
||||
//always render first
|
||||
if (parent != null) {
|
||||
parent.sendToBack(this);
|
||||
}
|
||||
|
||||
idle();
|
||||
|
||||
if (tier <= 3){
|
||||
shadowWidth = shadowHeight = 1f;
|
||||
perspectiveRaise = (16 - height()) / 32f; //center of the cell
|
||||
} else {
|
||||
shadowWidth = 1.2f;
|
||||
shadowHeight = 0.25f;
|
||||
perspectiveRaise = 6 / 16f; //6 pixels
|
||||
}
|
||||
|
||||
if (ch != null) {
|
||||
place(ch.pos);
|
||||
}
|
||||
}
|
||||
|
||||
private float baseY;
|
||||
|
||||
@Override
|
||||
public void place(int cell) {
|
||||
super.place(cell);
|
||||
baseY = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
//if tier is greater than 3
|
||||
if (perspectiveRaise >= 6 / 16f){
|
||||
y = baseY + (float) Math.sin(Game.timeTotal);
|
||||
shadowOffset = 0.25f - 0.8f*(float) Math.sin(Game.timeTotal);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user