v0.8.1: loads of changes and improvements to wand of warding:

Buffs:
- Ward/sentry energy cost reduced by 1, wand of warding energy capacity also reduced by 1
- Wards/sentries are now inorganic
- Vision range up to 4/5/6/7/8/9 from 3/4/5/6/7/8
- Zaps per ward tier increased to 1/3/5 from 1/3/4
- Upgrading a sentry now always grants it the largest possible health boost (18/22)
- Regular Sentry healing up to 8/10/15 from 6/8/12
QoL:
- Ward sprites now visually darken as they use up charges
- Sentries now show how much they are being healed by wand of warding
Massively reduced cases of "can't place ward here":
- wards can now be adjacent to eachother
- wards can now be summoned out of FOV if nothing is in the way
- wards now spawn adjacent to an enemy/wall if shot at one
And two that are more adjustments/nerfs:
- Lesser sentries now start with 4 less HP for each zap they used as a ward
- Attack speed changed to .5x/.5x/.5x/1x/1x/1x from .5x/.5x/.67x/.67x/1x/1x
This commit is contained in:
Evan Debenham 2020-06-11 23:31:59 -04:00
parent 3ce7d49991
commit 02270aa3d8
5 changed files with 93 additions and 68 deletions

View File

@ -1224,19 +1224,19 @@ items.wands.wandofwarding.staff_name=staff of warding
items.wands.wandofwarding.no_more_wards=Your wand can't sustain any more wards. items.wands.wandofwarding.no_more_wards=Your wand can't sustain any more wards.
items.wands.wandofwarding.bad_location=You can't place a ward there. items.wands.wandofwarding.bad_location=You can't place a ward there.
items.wands.wandofwarding.desc=This short metal wand has a bright purple gem floating above its tip. items.wands.wandofwarding.desc=This short metal wand has a bright purple gem floating above its tip.
items.wands.wandofwarding.stats_desc=Rather than directly damaging an enemy, this wand will summon stationary wards and sentries. Wards can be summoned anywhere you have vision, even through walls, but cannot be placed next to each other. This wand can sustain _%d energy_ worth of wards at a time. items.wands.wandofwarding.stats_desc=Rather than directly damaging an enemy, this wand will summon stationary wards and sentries. Wards can be summoned anywhere, even through walls if you have vision. This wand can sustain _%d energy_ worth of wards at a time.
items.wands.wandofwarding$ward.name_1=lesser ward items.wands.wandofwarding$ward.name_1=lesser ward
items.wands.wandofwarding$ward.desc_1=This basic ward will automatically zap any enemy which comes into its range of vision, dealing _%1$d-%2$d damage._\n\nZapping this ward with your wand of warding will upgrade it.\n\nThis ward will only zap a single time before dissipating.\n\nYour wand of warding is using _2 energy_ to sustain this ward. items.wands.wandofwarding$ward.desc_1=This basic ward will automatically zap any enemy which comes into its range of vision, dealing _%1$d-%2$d damage._\n\nZapping this ward with your wand of warding will upgrade it.\n\nThis ward will only zap a single time before dissipating.\n\nYour wand of warding is using _%3$d energy_ to sustain this ward.
items.wands.wandofwarding$ward.name_2=ward items.wands.wandofwarding$ward.name_2=ward
items.wands.wandofwarding$ward.desc_2=This upgraded ward has a more intricate pattern, and can attack multiple times. Each zap from this ward will deal _%1$d-%2$d damage._\n\nZapping this ward with your wand of warding will upgrade it.\n\nThis ward will zap three times before dissipating.\n\nYour wand of warding is using _3 energy_ to sustain this ward. items.wands.wandofwarding$ward.desc_2=This upgraded ward has a more intricate pattern, and can attack multiple times. Each zap from this ward will deal _%1$d-%2$d damage._\n\nZapping this ward with your wand of warding will upgrade it.\n\nThis ward will zap three times before dissipating.\n\nYour wand of warding is using _%3$d energy_ to sustain this ward.
items.wands.wandofwarding$ward.name_3=greater ward items.wands.wandofwarding$ward.name_3=greater ward
items.wands.wandofwarding$ward.desc_3=This fully upgraded ward is able to attack more times, and more quickly, than its predecessors. Each zap from this ward will deal _%1$d-%2$d damage._\n\nZapping this ward with your wand of warding will upgrade it.\n\nThis ward will zap four times before dissipating.\n\nYour wand of warding is using _4 energy_ to sustain this ward. items.wands.wandofwarding$ward.desc_3=This fully upgraded ward is able to attack more times than its predecessors. Each zap from this ward will deal _%1$d-%2$d damage._\n\nZapping this ward with your wand of warding will upgrade it.\n\nThis ward will zap five times before dissipating.\n\nYour wand of warding is using _%3$d energy_ to sustain this ward.
items.wands.wandofwarding$ward.name_4=lesser sentry items.wands.wandofwarding$ward.name_4=lesser sentry
items.wands.wandofwarding$ward.desc_4=This smaller sentry has the same attack power as a greater ward, but isn't nearly as fragile. It resembles the gem at the tip of your wand of warding. Each zap from this sentry will deal _%1$d-%2$d damage._\n\nZapping this sentry with your wand of warding will upgrade and heal it.\n\nThis sentry will spend some health each time it zaps an enemy, but can be healed by using your wand of warding on it.\n\nYour wand of warding is using _5 energy_ to sustain this sentry. items.wands.wandofwarding$ward.desc_4=This smaller sentry has the same firepower as a greater ward, but can fire more quickly. It resembles the gem at the tip of your wand of warding. Each zap from this sentry will deal _%1$d-%2$d damage._\n\nZapping this sentry with your wand of warding will upgrade and heal it.\n\nThis sentry will spend some health each time it zaps an enemy, but can be healed by using your wand of warding on it.\n\nYour wand of warding is using _%3$d energy_ to sustain this sentry.
items.wands.wandofwarding$ward.name_5=sentry items.wands.wandofwarding$ward.name_5=sentry
items.wands.wandofwarding$ward.desc_5=This upgraded sentry is larger and able to attack more quickly than a lesser sentry. Each zap from this sentry will deal _%1$d-%2$d damage._\n\nZapping this sentry with your wand of warding will upgrade and heal it.\n\nThis sentry will spend some health each time it zaps an enemy, but can be healed by using your wand of warding on it.\n\nYour wand of warding is using _6 energy_ to sustain this sentry. items.wands.wandofwarding$ward.desc_5=This upgraded sentry is larger and more durable than a lesser sentry. Each zap from this sentry will deal _%1$d-%2$d damage._\n\nZapping this sentry with your wand of warding will upgrade and heal it.\n\nThis sentry will spend some health each time it zaps an enemy, but can be healed by using your wand of warding on it.\n\nYour wand of warding is using _%3$d energy_ to sustain this sentry.
items.wands.wandofwarding$ward.name_6=greater sentry items.wands.wandofwarding$ward.name_6=greater sentry
items.wands.wandofwarding$ward.desc_6=This fully upgraded sentry is significantly more durable than its predecessors. Each zap from this sentry will deal _%1$d-%2$d damage._\n\nZapping this sentry with your wand of warding will heal it.\n\nThis sentry will spend some health each time it zaps an enemy, but can be healed by using your wand of warding on it.\n\nYour wand of warding is using _7 energy_ to sustain this sentry. items.wands.wandofwarding$ward.desc_6=This fully upgraded sentry is significantly more durable than its predecessors. Each zap from this sentry will deal _%1$d-%2$d damage._\n\nZapping this sentry with your wand of warding will heal it.\n\nThis sentry will spend some health each time it zaps an enemy, but can be healed by using your wand of warding on it.\n\nYour wand of warding is using _%3$d energy_ to sustain this sentry.
items.wands.wandofwarding$ward.dismiss_title=Dismiss this ward? items.wands.wandofwarding$ward.dismiss_title=Dismiss this ward?
items.wands.wandofwarding$ward.dismiss_body=You can dispel this ward if you no longer want your wand to maintain it. Doing so immediately destroys the ward.\n\nDismiss this ward? items.wands.wandofwarding$ward.dismiss_body=You can dispel this ward if you no longer want your wand to maintain it. Doing so immediately destroys the ward.\n\nDismiss this ward?
items.wands.wandofwarding$ward.dismiss_confirm=yes items.wands.wandofwarding$ward.dismiss_confirm=yes

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 B

After

Width:  |  Height:  |  Size: 283 B

View File

@ -426,6 +426,10 @@ public abstract class Wand extends Item {
availableUsesToID = USES_TO_ID/2f; availableUsesToID = USES_TO_ID/2f;
} }
protected int collisionProperties( int target ){
return collisionProperties;
}
protected static CellSelector.Listener zapper = new CellSelector.Listener() { protected static CellSelector.Listener zapper = new CellSelector.Listener() {
@Override @Override
@ -442,7 +446,7 @@ public abstract class Wand extends Item {
return; return;
} }
final Ballistica shot = new Ballistica( curUser.pos, target, curWand.collisionProperties); final Ballistica shot = new Ballistica( curUser.pos, target, curWand.collisionProperties(target));
int cell = shot.collisionPos; int cell = shot.collisionPos;
if (target == curUser.pos || cell == curUser.pos) { if (target == curUser.pos || cell == curUser.pos) {

View File

@ -29,11 +29,15 @@ import com.watabou.utils.Random;
public class WandOfWarding extends Wand { public class WandOfWarding extends Wand {
{ {
collisionProperties = Ballistica.STOP_TARGET;
image = ItemSpriteSheet.WAND_WARDING; image = ItemSpriteSheet.WAND_WARDING;
} }
@Override
protected int collisionProperties(int target) {
if (Dungeon.level.heroFOV[target]) return Ballistica.STOP_TARGET;
else return Ballistica.PROJECTILE;
}
private boolean wardAvailable = true; private boolean wardAvailable = true;
@Override @Override
@ -42,7 +46,7 @@ public class WandOfWarding extends Wand {
int currentWardEnergy = 0; int currentWardEnergy = 0;
for (Char ch : Actor.chars()){ for (Char ch : Actor.chars()){
if (ch instanceof Ward){ if (ch instanceof Ward){
currentWardEnergy += ((Ward) ch).tier + 1; currentWardEnergy += ((Ward) ch).tier;
} }
} }
@ -50,7 +54,7 @@ public class WandOfWarding extends Wand {
for (Buff buff : curUser.buffs()){ for (Buff buff : curUser.buffs()){
if (buff instanceof Wand.Charger){ if (buff instanceof Wand.Charger){
if (((Charger) buff).wand() instanceof WandOfWarding){ if (((Charger) buff).wand() instanceof WandOfWarding){
maxWardEnergy += 3 + ((Charger) buff).wand().level(); maxWardEnergy += 2 + ((Charger) buff).wand().level();
} }
} }
} }
@ -76,10 +80,22 @@ public class WandOfWarding extends Wand {
@Override @Override
protected void onZap(Ballistica bolt) { protected void onZap(Ballistica bolt) {
Char ch = Actor.findChar(bolt.collisionPos); int target = bolt.collisionPos;
if (!curUser.fieldOfView[bolt.collisionPos] || !Dungeon.level.passable[bolt.collisionPos]){ Char ch = Actor.findChar(target);
if (ch != null && !(ch instanceof Ward)){
if (bolt.dist > 1) target = bolt.path.get(bolt.dist-1);
ch = Actor.findChar(target);
if (ch != null && !(ch instanceof Ward)){
GLog.w( Messages.get(this, "bad_location"));
Dungeon.level.pressCell(bolt.collisionPos);
return;
}
}
if (!Dungeon.level.passable[target]){
GLog.w( Messages.get(this, "bad_location")); GLog.w( Messages.get(this, "bad_location"));
Dungeon.level.pressCell(bolt.collisionPos); Dungeon.level.pressCell(target);
} else if (ch != null){ } else if (ch != null){
if (ch instanceof Ward){ if (ch instanceof Ward){
@ -91,21 +107,18 @@ public class WandOfWarding extends Wand {
ch.sprite.emitter().burst(MagicMissile.WardParticle.UP, ((Ward) ch).tier); ch.sprite.emitter().burst(MagicMissile.WardParticle.UP, ((Ward) ch).tier);
} else { } else {
GLog.w( Messages.get(this, "bad_location")); GLog.w( Messages.get(this, "bad_location"));
Dungeon.level.pressCell(bolt.collisionPos); Dungeon.level.pressCell(target);
} }
} else if (canPlaceWard(bolt.collisionPos)){ } else {
Ward ward = new Ward(); Ward ward = new Ward();
ward.pos = bolt.collisionPos; ward.pos = target;
ward.wandLevel = buffedLvl(); ward.wandLevel = buffedLvl();
GameScene.add(ward, 1f); GameScene.add(ward, 1f);
Dungeon.level.occupyCell(ward); Dungeon.level.occupyCell(ward);
ward.sprite.emitter().burst(MagicMissile.WardParticle.UP, ward.tier); ward.sprite.emitter().burst(MagicMissile.WardParticle.UP, ward.tier);
Dungeon.level.pressCell(bolt.collisionPos); Dungeon.level.pressCell(target);
} else {
GLog.w( Messages.get(this, "bad_location"));
Dungeon.level.pressCell(bolt.collisionPos);
} }
} }
@ -151,24 +164,12 @@ public class WandOfWarding extends Wand {
particle.radiateXY(2.5f); particle.radiateXY(2.5f);
} }
public static boolean canPlaceWard(int pos){
for (int i : PathFinder.CIRCLE8){
if (Actor.findChar(pos+i) instanceof Ward){
return false;
}
}
return true;
}
@Override @Override
public String statsDesc() { public String statsDesc() {
if (levelKnown) if (levelKnown)
return Messages.get(this, "stats_desc", level()+3); return Messages.get(this, "stats_desc", level()+2);
else else
return Messages.get(this, "stats_desc", 3); return Messages.get(this, "stats_desc", 2);
} }
public static class Ward extends NPC { public static class Ward extends NPC {
@ -176,7 +177,7 @@ public class WandOfWarding extends Wand {
public int tier = 1; public int tier = 1;
private int wandLevel = 1; private int wandLevel = 1;
private int totalZaps = 0; public int totalZaps = 0;
{ {
spriteClass = WardSprite.class; spriteClass = WardSprite.class;
@ -184,8 +185,9 @@ public class WandOfWarding extends Wand {
alignment = Alignment.ALLY; alignment = Alignment.ALLY;
properties.add(Property.IMMOVABLE); properties.add(Property.IMMOVABLE);
properties.add(Property.INORGANIC);
viewDistance = 3; viewDistance = 4;
state = WANDERING; state = WANDERING;
} }
@ -205,30 +207,36 @@ public class WandOfWarding extends Wand {
this.wandLevel = wandLevel; this.wandLevel = wandLevel;
} }
wandHeal(0);
switch (tier){ switch (tier){
case 1: case 2: default: case 1: case 2: default:
break; //do nothing break; //do nothing
case 3: case 3:
HP = HT = 30; HT = 30;
HP = 10 + (5-totalZaps)*4;
break; break;
case 4: case 4:
HT = 48; HT = 48;
HP = Math.round(48*(HP/30f)); HP += 18;
break; break;
case 5: case 5:
HT = 70; HT = 70;
HP = Math.round(70*(HP/48f)); HP += 22;
break;
case 6:
wandHeal(wandLevel);
break; break;
} }
if (tier < 6){ if (tier < 6){
tier++; tier++;
viewDistance++; viewDistance++;
updateSpriteState(); if (sprite != null){
((WardSprite)sprite).updateTier(tier);
sprite.place(pos);
}
GameScene.updateFog(pos, viewDistance+1); GameScene.updateFog(pos, viewDistance+1);
} }
} }
private void wandHeal( int wandLevel ){ private void wandHeal( int wandLevel ){
@ -236,19 +244,27 @@ public class WandOfWarding extends Wand {
this.wandLevel = wandLevel; this.wandLevel = wandLevel;
} }
int heal;
switch(tier){ switch(tier){
default: default:
break; return;
case 4: case 4:
HP = Math.min(HT, HP+6); heal = 8;
HP = Math.min(HT, HP+9);
break; break;
case 5: case 5:
HP = Math.min(HT, HP+8); heal = 10;
HP = Math.min(HT, HP+10);
break; break;
case 6: case 6:
HP = Math.min(HT, HP+12); heal = 15;
HP = Math.min(HT, HP+15);
break; break;
} }
HP = Math.min(HT, HP+heal);
if (sprite != null) sprite.showStatus(CharSprite.POSITIVE, Integer.toString(heal));
} }
@Override @Override
@ -270,13 +286,10 @@ public class WandOfWarding extends Wand {
@Override @Override
protected float attackDelay() { protected float attackDelay() {
switch (tier){ if (tier > 3){
case 1: case 2: default: return 1f;
return 2f; } else {
case 3: case 4: return 2f;
return 1.5f;
case 5: case 6:
return 1f;
} }
} }
@ -313,13 +326,8 @@ public class WandOfWarding extends Wand {
totalZaps++; totalZaps++;
switch(tier){ switch(tier){
case 1: default: case 1: case 2: case 3: default:
if (totalZaps >= tier){ if (totalZaps >= (2*tier-1)){
die(this);
}
break;
case 2: case 3:
if (totalZaps > tier){
die(this); die(this);
} }
break; break;
@ -402,7 +410,7 @@ public class WandOfWarding extends Wand {
@Override @Override
public String description() { public String description() {
return Messages.get(this, "desc_" + tier, 2+wandLevel, 8 + 4*wandLevel ); return Messages.get(this, "desc_" + tier, 2+wandLevel, 8 + 4*wandLevel, tier );
} }
{ {
@ -425,7 +433,7 @@ public class WandOfWarding extends Wand {
public void restoreFromBundle(Bundle bundle) { public void restoreFromBundle(Bundle bundle) {
super.restoreFromBundle(bundle); super.restoreFromBundle(bundle);
tier = bundle.getInt(TIER); tier = bundle.getInt(TIER);
viewDistance = 2 + tier; viewDistance = 3 + tier;
wandLevel = bundle.getInt(WAND_LEVEL); wandLevel = bundle.getInt(WAND_LEVEL);
totalZaps = bundle.getInt(TOTAL_ZAPS); totalZaps = bundle.getInt(TOTAL_ZAPS);
} }

View File

@ -72,7 +72,18 @@ public class WardSprite extends MobSprite {
} ); } );
} }
public void linkVisuals( Char ch ){ @Override
public void resetColor() {
super.resetColor();
if (ch instanceof WandOfWarding.Ward){
WandOfWarding.Ward ward = (WandOfWarding.Ward) ch;
if (ward.tier <= 3){
brightness(Math.max(0.2f, 1f - (ward.totalZaps / (float)(2*ward.tier-1))));
}
}
}
public void linkVisuals(Char ch ){
if (ch == null) return; if (ch == null) return;
@ -92,6 +103,8 @@ public class WardSprite extends MobSprite {
parent.sendToBack(this); parent.sendToBack(this);
} }
resetColor();
if (ch != null) place(ch.pos);
idle(); idle();
if (tier <= 3){ if (tier <= 3){