v0.8.1: Improved buff fading VFX & applied it to a few new ones

Also buffed alternate sources of bless:
- holy dart bless duration up to 30 turns from 20.
- Holy furor bless duration up to 120 turns from 100.
This commit is contained in:
Evan Debenham 2020-05-06 20:20:25 -04:00
parent 7fdb4f534e
commit 13ecf57edf
43 changed files with 128 additions and 94 deletions

View File

@ -41,8 +41,8 @@ public class Adrenaline extends FlavourBuff {
}
@Override
public void tintIcon(Image icon) {
greyIcon(icon, 5f, cooldown());
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override

View File

@ -67,7 +67,7 @@ public class AdrenalineSurge extends Buff {
@Override
public String desc() {
return Messages.get(this, "desc", boost, dispTurns(cooldown()+1));
return Messages.get(this, "desc", boost, dispTurns(visualcooldown()));
}
private static final String BOOST = "boost";

View File

@ -84,7 +84,7 @@ public class ArcaneArmor extends Buff {
@Override
public String desc() {
return Messages.get(this, "desc", level, dispTurns(cooldown()+1));
return Messages.get(this, "desc", level, dispTurns(visualcooldown()));
}
private static final String LEVEL = "level";

View File

@ -29,9 +29,10 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.watabou.noosa.Image;
import com.watabou.utils.Bundle;
//TODO this may be very powerful, consider balancing
public class ArtifactRecharge extends Buff {
public static final float DURATION = 30f;
{
type = buffType.POSITIVE;
}
@ -80,6 +81,11 @@ public class ArtifactRecharge extends Buff {
icon.hardlight(0, 1f, 0);
}
@Override
public float iconFadePercent() {
return Math.max(0, (DURATION - left) / DURATION);
}
@Override
public String toString() {
return Messages.get(this, "name");

View File

@ -77,7 +77,7 @@ public class Barkskin extends Buff {
@Override
public String desc() {
return Messages.get(this, "desc", level, dispTurns(cooldown()+1));
return Messages.get(this, "desc", level, dispTurns(visualcooldown()));
}
private static final String LEVEL = "level";

View File

@ -40,8 +40,8 @@ public class Bless extends FlavourBuff {
}
@Override
public void tintIcon(Image icon) {
greyIcon(icon, 5f, cooldown());
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override

View File

@ -54,8 +54,8 @@ public class BlobImmunity extends FlavourBuff {
}
@Override
public void tintIcon(Image icon) {
greyIcon(icon, 5f, cooldown());
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override

View File

@ -90,10 +90,17 @@ public class Buff extends Actor {
return BuffIndicator.NONE;
}
//some buffs may want to tint the base texture color of their icon
public void tintIcon( Image icon ){
//do nothing by default
}
//percent (0-1) to fade out out the buff icon, usually if buff is expiring
public float iconFadePercent(){
return 0;
}
//visual effect usually attached to the sprite of the character the buff is attacked to
public void fx(boolean on) {
//do nothing by default
}
@ -111,6 +118,11 @@ public class Buff extends Actor {
return new DecimalFormat("#.##").format(input);
}
//buffs act after the hero, so it is often useful to use cooldown+1 when display buff time remaining
public float visualcooldown(){
return cooldown()+1f;
}
//creates a fresh instance of the buff and attaches that, this allows duplication.
public static<T extends Buff> T append( Char target, Class<T> buffClass ) {
T buff = Reflection.newInstance(buffClass);

View File

@ -147,6 +147,7 @@ public class Burning extends Buff implements Hero.Doom {
spend( TICK );
left -= TICK;
BuffIndicator.refreshHero();
if (left <= 0 ||
(Dungeon.level.water[target.pos] && !target.flying)) {
@ -170,6 +171,11 @@ public class Burning extends Buff implements Hero.Doom {
return BuffIndicator.FIRE;
}
@Override
public float iconFadePercent() {
return Math.max(0, (DURATION - left) / DURATION);
}
@Override
public void fx(boolean on) {
if (on) target.sprite.add(CharSprite.State.BURNING);

View File

@ -62,6 +62,6 @@ public class Drowsy extends Buff {
@Override
public String desc() {
return Messages.get(this, "desc", dispTurns(cooldown()+1));
return Messages.get(this, "desc", dispTurns(visualcooldown()));
}
}

View File

@ -49,8 +49,8 @@ public class EarthImbue extends FlavourBuff {
}
@Override
public void tintIcon(Image icon) {
greyIcon(icon, 5f, cooldown());
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override

View File

@ -93,8 +93,8 @@ public class FireImbue extends Buff {
}
@Override
public void tintIcon(Image icon) {
FlavourBuff.greyIcon(icon, 5f, left);
public float iconFadePercent() {
return Math.max(0, (DURATION - left+1) / DURATION);
}
@Override

View File

@ -42,7 +42,6 @@ public class FlavourBuff extends Buff {
//flavour buffs can all just rely on cooldown()
protected String dispTurns() {
//add one turn as buffs act last, we want them to end at 1 visually, even if they end at 0 internally.
return dispTurns(cooldown()+1f);
return dispTurns(visualcooldown());
}
}

View File

@ -47,8 +47,8 @@ public class FrostImbue extends FlavourBuff {
}
@Override
public void tintIcon(Image icon) {
greyIcon(icon, 5f, cooldown());
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override

View File

@ -39,9 +39,8 @@ public class Haste extends FlavourBuff {
}
@Override
public void tintIcon(Image icon) {
icon.tint(1, 1, 0, 0.5f);
if (cooldown() < 5f) greyIcon(icon, 5f, cooldown());
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override

View File

@ -68,8 +68,8 @@ public class Invisibility extends FlavourBuff {
}
@Override
public void tintIcon(Image icon) {
greyIcon(icon, 5f, cooldown());
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override

View File

@ -60,8 +60,8 @@ public class Levitation extends FlavourBuff {
}
@Override
public void tintIcon(Image icon) {
greyIcon(icon, 5f, cooldown());
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override

View File

@ -67,8 +67,8 @@ public class Light extends FlavourBuff {
}
@Override
public void tintIcon(Image icon) {
greyIcon(icon, 20f, cooldown());
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override

View File

@ -44,8 +44,8 @@ public class MagicalSight extends FlavourBuff {
}
@Override
public void tintIcon(Image icon) {
greyIcon(icon, 5f, cooldown());
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override

View File

@ -44,8 +44,8 @@ public class MindVision extends FlavourBuff {
}
@Override
public void tintIcon(Image icon) {
greyIcon(icon, 5f, cooldown());
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override

View File

@ -27,6 +27,8 @@ import com.watabou.noosa.Image;
public class Recharging extends FlavourBuff {
public static final float DURATION = 30f;
{
type = buffType.POSITIVE;
}
@ -37,8 +39,8 @@ public class Recharging extends FlavourBuff {
}
@Override
public void tintIcon(Image icon) {
FlavourBuff.greyIcon(icon, 5f, cooldown());
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override

View File

@ -100,8 +100,8 @@ public class Shadows extends Invisibility {
}
@Override
public void tintIcon(Image icon) {
icon.resetColor();
public float iconFadePercent() {
return 0;
}
@Override

View File

@ -27,6 +27,8 @@ import com.watabou.noosa.Image;
public class Stamina extends FlavourBuff {
public static final float DURATION = 100f;
{
type = buffType.POSITIVE;
}
@ -37,9 +39,8 @@ public class Stamina extends FlavourBuff {
}
@Override
public void tintIcon(Image icon) {
icon.tint(1, 1, 0, 0.5f);
if (cooldown() < 5f) greyIcon(icon, 5f, cooldown());
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override

View File

@ -80,8 +80,8 @@ public class ToxicImbue extends Buff {
}
@Override
public void tintIcon(Image icon) {
FlavourBuff.greyIcon(icon, 5f, left);
public float iconFadePercent() {
return Math.max(0, (DURATION - left) / DURATION);
}
@Override

View File

@ -1341,7 +1341,7 @@ public class Hero extends Char {
defenseSkill++;
} else {
Buff.prolong(this, Bless.class, 30f);
Buff.prolong(this, Bless.class, Bless.DURATION);
this.exp = 0;
GLog.newLine();

View File

@ -78,7 +78,7 @@ public class RogueArmor extends ClassArmor {
mob.sprite.emitter().burst( Speck.factory( Speck.LIGHT ), 4 );
}
}
Buff.affect(curUser, Invisibility.class, 10f);
Buff.affect(curUser, Invisibility.class, Invisibility.DURATION/2f);
CellEmitter.get( curUser.pos ).burst( Speck.factory( Speck.WOOL ), 10 );
ScrollOfTeleportation.appear( curUser, target );

View File

@ -81,15 +81,13 @@ public class ElixirOfAquaticRejuvenation extends Elixir {
target.HP += healAmt;
left -= healAmt;
target.sprite.emitter().burst( Speck.factory( Speck.HEALING ), 1 );
BuffIndicator.refreshHero();
}
if (left <= 0){
detach();
} else {
spend(TICK);
if (left <= target.HT/4f){
BuffIndicator.refreshHero();
}
}
return true;
}
@ -101,7 +99,13 @@ public class ElixirOfAquaticRejuvenation extends Elixir {
@Override
public void tintIcon(Image icon) {
FlavourBuff.greyIcon(icon, target.HT/4f, left);
icon.hardlight(0, 1, 1);
}
@Override
public float iconFadePercent() {
float max = Math.round(target.HT * 1.5f);
return Math.max(0, (max - left) / max);
}
@Override

View File

@ -34,7 +34,7 @@ public class PotionOfHolyFuror extends ExoticPotion {
@Override
public void apply( Hero hero ) {
setKnown();
Buff.prolong(hero, Bless.class, 100f);
Buff.prolong(hero, Bless.class, Bless.DURATION*4f);
}
}

View File

@ -35,7 +35,7 @@ public class PotionOfStamina extends ExoticPotion {
public void apply(Hero hero) {
setKnown();
Buff.affect(hero, Stamina.class, 100f);
Buff.affect(hero, Stamina.class, Stamina.DURATION);
}
}

View File

@ -35,8 +35,6 @@ import com.watabou.noosa.audio.Sample;
public class ScrollOfRecharging extends Scroll {
public static final float BUFF_DURATION = 30f;
{
initials = 6;
}
@ -44,7 +42,7 @@ public class ScrollOfRecharging extends Scroll {
@Override
public void doRead() {
Buff.affect(curUser, Recharging.class, BUFF_DURATION);
Buff.affect(curUser, Recharging.class, Recharging.DURATION);
charge(curUser);
Sample.INSTANCE.play( Assets.SND_READ );
@ -60,7 +58,7 @@ public class ScrollOfRecharging extends Scroll {
@Override
public void empoweredRead() {
doRead();
Buff.append(curUser, Recharging.class, BUFF_DURATION/3f);
Buff.append(curUser, Recharging.class, Recharging.DURATION/3f);
}
public static void charge( Char user ) {

View File

@ -264,7 +264,7 @@ public class CursedWand {
//shock and recharge
case 3:
new ShockingTrap().set( user.pos ).activate();
Buff.prolong(user, Recharging.class, 20f);
Buff.prolong(user, Recharging.class, Recharging.DURATION);
ScrollOfRecharging.charge(user);
SpellSprite.show(user, SpellSprite.CHARGE);
afterZap.call();

View File

@ -35,7 +35,7 @@ public class HolyDart extends TippedDart {
@Override
public int proc(Char attacker, Char defender, int damage) {
Buff.affect(defender, Bless.class, 20f);
Buff.affect(defender, Bless.class, Bless.DURATION);
if (attacker.alignment == defender.alignment){
return 0;

View File

@ -46,7 +46,7 @@ public class Blindweed extends Plant {
if (ch != null) {
if (ch instanceof Hero && ((Hero) ch).subClass == HeroSubClass.WARDEN){
Buff.affect(ch, Invisibility.class, 10f);
Buff.affect(ch, Invisibility.class, Invisibility.DURATION/2f);
} else {
int len = Random.Int(5, 10);
Buff.prolong(ch, Blindness.class, len);

View File

@ -50,7 +50,7 @@ public class Dreamfoil extends Plant {
PotionOfHealing.cure(ch);
if (((Hero) ch).subClass == HeroSubClass.WARDEN){
Buff.affect(ch, BlobImmunity.class, 10f);
Buff.affect(ch, BlobImmunity.class, BlobImmunity.DURATION/2f);
}
}

View File

@ -126,8 +126,8 @@ public class Earthroot extends Plant {
}
@Override
public void tintIcon(Image icon) {
FlavourBuff.greyIcon(icon, target.HT/4f, level);
public float iconFadePercent() {
return Math.max(0, (target.HT - level) / target.HT);
}
@Override

View File

@ -44,7 +44,7 @@ public class Firebloom extends Plant {
public void activate( Char ch ) {
if (ch instanceof Hero && ((Hero) ch).subClass == HeroSubClass.WARDEN){
Buff.affect(ch, FireImbue.class).set(15f);
Buff.affect(ch, FireImbue.class).set( FireImbue.DURATION*0.3f );
}
GameScene.add( Blob.seed( pos, 2, Fire.class ) );

View File

@ -43,7 +43,7 @@ public class Icecap extends Plant {
public void activate( Char ch ) {
if (ch instanceof Hero && ((Hero) ch).subClass == HeroSubClass.WARDEN){
Buff.affect(ch, FrostImbue.class, 15f);
Buff.affect(ch, FrostImbue.class, FrostImbue.DURATION*0.3f);
}
PathFinder.buildDistanceMap( pos, BArray.not( Dungeon.level.losBlocking, null ), 1 );

View File

@ -41,7 +41,7 @@ public class Sorrowmoss extends Plant {
@Override
public void activate( Char ch ) {
if (ch instanceof Hero && ((Hero) ch).subClass == HeroSubClass.WARDEN){
Buff.affect(ch, ToxicImbue.class).set(15f);
Buff.affect(ch, ToxicImbue.class).set(ToxicImbue.DURATION*0.3f);
}
if (ch != null) {

View File

@ -43,7 +43,7 @@ public class Starflower extends Plant {
if (ch != null) {
Buff.prolong(ch, Bless.class, Bless.DURATION);
if (ch instanceof Hero && ((Hero) ch).subClass == HeroSubClass.WARDEN){
Buff.prolong(ch, Recharging.class, Bless.DURATION);
Buff.prolong(ch, Recharging.class, Recharging.DURATION);
}
}

View File

@ -40,7 +40,7 @@ public class Stormvine extends Plant {
if (ch != null) {
if (ch instanceof Hero && ((Hero) ch).subClass == HeroSubClass.WARDEN){
Buff.affect(ch, Levitation.class, 10f);
Buff.affect(ch, Levitation.class, Levitation.DURATION/2f);
} else {
Buff.affect(ch, Vertigo.class, Vertigo.DURATION);
}

View File

@ -125,8 +125,8 @@ public class Sungrass extends Plant {
}
@Override
public void tintIcon(Image icon) {
FlavourBuff.greyIcon(icon, target.HT/4f, level);
public float iconFadePercent() {
return Math.max(0, (target.HT - level) / target.HT);
}
@Override

View File

@ -80,8 +80,8 @@ public class Swiftthistle extends Plant {
}
@Override
public void tintIcon(Image icon) {
FlavourBuff.greyIcon(icon, 5f, left);
public float iconFadePercent() {
return Math.max(0, (6f - left) / 6f);
}
public void reset(){

View File

@ -197,6 +197,7 @@ public class BuffIndicator extends Component {
private Buff buff;
public Image icon;
public Image grey;
public BuffIcon( Buff buff ){
super();
@ -205,18 +206,24 @@ public class BuffIndicator extends Component {
icon = new Image( texture );
icon.frame( film.get( buff.icon() ) );
add( icon );
grey = new Image( TextureCache.createSolid(0xCC808080));
add( grey );
}
public void updateIcon(){
icon.frame( film.get( buff.icon() ) );
buff.tintIcon(icon);
//logic here rounds down to the nearest pixel
float zoom = (camera() != null) ? camera().zoom : 1;
grey.scale.set( icon.width(), (float)Math.floor(zoom*icon.height()*buff.iconFadePercent())/zoom);
}
@Override
protected void layout() {
super.layout();
icon.x = this.x+1;
icon.y = this.y+2;
grey.x = icon.x = this.x+1;
grey.y = icon.y = this.y+2;
}
@Override