diff --git a/core/src/main/assets/messages/items/items.properties b/core/src/main/assets/messages/items/items.properties index d3547d049..c4aca1090 100644 --- a/core/src/main/assets/messages/items/items.properties +++ b/core/src/main/assets/messages/items/items.properties @@ -965,8 +965,13 @@ items.scrolls.exotic.exoticscroll.odal=exotic scroll of ODAL items.scrolls.exotic.exoticscroll.tiwaz=exotic scroll of TIWAZ items.scrolls.exotic.exoticscroll.unknown_desc=A glowing indecipherable magical rune is written on this black parchment. It seems to be foreign to this land, who knows what it will do when read aloud? -items.scrolls.exotic.scrollofaffection.name=scroll of affection -items.scrolls.exotic.scrollofaffection.desc=Reading this scroll will emit an alluring laugh which charms all who hear it. +items.scrolls.exotic.scrollofsirenssong.name=scroll of siren's song +items.scrolls.exotic.scrollofsirenssong.prompt=Choose a target +items.scrolls.exotic.scrollofsirenssong.no_target=The scroll activates without a target +items.scrolls.exotic.scrollofsirenssong.cancel=You must choose a target +items.scrolls.exotic.scrollofsirenssong.desc=Reading this scroll emits an alluring melody which will enthrall a targeted enemy, permanently turning them into an ally! Other enemies who hear it will be temporarily charmed.\n\nParticularly strong enemies can resist the enthrall effect, and will be charmed instead. +items.scrolls.exotic.scrollofsirenssong$enthralled.name=Enthralled +items.scrolls.exotic.scrollofsirenssong$enthralled.desc=This creature has been bewitched by the magic of a scroll of siren's song.\n\nAn enthralled character is permanently your ally, and will fight any enemies they encounter. items.scrolls.exotic.scrollofantimagic.name=scroll of anti-magic items.scrolls.exotic.scrollofantimagic.desc=The incantation on this scroll will surround you with a magical aura that temporarily blocks all magical effects, harmful or helpful. diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java index f13825f63..59d7fa517 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java @@ -45,9 +45,13 @@ public class ShatteredPixelDungeon extends Game { public ShatteredPixelDungeon( PlatformSupport platform ) { super( sceneClass == null ? WelcomeScene.class : sceneClass, platform ); + //v1.1.0 com.watabou.utils.Bundle.addAlias( com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfDread.class, "com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfPetrification" ); + com.watabou.utils.Bundle.addAlias( + com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfSirensSong.class, + "com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfAffection" ); //v1.0.0 com.watabou.utils.Bundle.addAlias( diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ExoticScroll.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ExoticScroll.java index 7a016e7f5..d11667ff9 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ExoticScroll.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ExoticScroll.java @@ -57,8 +57,8 @@ public abstract class ExoticScroll extends Scroll { regToExo.put(ScrollOfRemoveCurse.class, ScrollOfAntiMagic.class); exoToReg.put(ScrollOfAntiMagic.class, ScrollOfRemoveCurse.class); - regToExo.put(ScrollOfLullaby.class, ScrollOfAffection.class); - exoToReg.put(ScrollOfAffection.class, ScrollOfLullaby.class); + regToExo.put(ScrollOfLullaby.class, ScrollOfSirensSong.class); + exoToReg.put(ScrollOfSirensSong.class, ScrollOfLullaby.class); regToExo.put(ScrollOfRage.class, ScrollOfConfusion.class); exoToReg.put(ScrollOfConfusion.class, ScrollOfRage.class); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ScrollOfAffection.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ScrollOfAffection.java deleted file mode 100644 index b1409ec43..000000000 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ScrollOfAffection.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Pixel Dungeon - * Copyright (C) 2012-2015 Oleg Dolya - * - * Shattered Pixel Dungeon - * Copyright (C) 2014-2021 Evan Debenham - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - */ - -package com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic; - -import com.shatteredpixel.shatteredpixeldungeon.Assets; -import com.shatteredpixel.shatteredpixeldungeon.Dungeon; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm; -import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; -import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; -import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; -import com.watabou.noosa.audio.Sample; - -public class ScrollOfAffection extends ExoticScroll { - - { - icon = ItemSpriteSheet.Icons.SCROLL_AFFECTION; - } - - @Override - public void doRead() { - - curUser.sprite.centerEmitter().start( Speck.factory( Speck.HEART ), 0.2f, 5 ); - Sample.INSTANCE.play( Assets.Sounds.CHARMS ); - - for (Mob mob : Dungeon.level.mobs.toArray( new Mob[0] )) { - if (Dungeon.level.heroFOV[mob.pos]) { - Buff.affect( mob, Charm.class, Charm.DURATION*2f ).object = curUser.id(); - mob.sprite.centerEmitter().start( Speck.factory( Speck.HEART ), 0.2f, 5 ); - } - } - - //GLog.i( Messages.get(this, "sooth") ); - - identify(); - - readAnimation(); - - } - -} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ScrollOfSirensSong.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ScrollOfSirensSong.java new file mode 100644 index 000000000..926d495bb --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/exotic/ScrollOfSirensSong.java @@ -0,0 +1,146 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2021 Evan Debenham + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +package com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic; + +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.buffs.AllyBuff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; +import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; +import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfDragonsBreath; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.watabou.noosa.audio.Sample; + +public class ScrollOfSirensSong extends ExoticScroll { + + { + icon = ItemSpriteSheet.Icons.SCROLL_SIREN; + } + + @Override + public void doRead() { + curItem.collect(); //we detach it later + GameScene.selectCell(targeter); + } + + private CellSelector.Listener targeter = new CellSelector.Listener() { + + @Override + public void onSelect(Integer cell) { + if (cell == null && isKnown() && !anonymous){ + return; + } + + Mob target = null; + if (cell != null){ + Char ch = Actor.findChar(cell); + if (ch != null && ch.alignment != Char.Alignment.ALLY && ch instanceof Mob){ + target = (Mob)ch; + } + } + + if (target == null && isKnown() && !anonymous){ + GLog.w(Messages.get(ScrollOfSirensSong.class, "cancel")); + return; + + } else { + + detach(curUser.belongings.backpack); + + curUser.sprite.centerEmitter().start( Speck.factory( Speck.HEART ), 0.2f, 5 ); + Sample.INSTANCE.play( Assets.Sounds.CHARMS ); + Sample.INSTANCE.playDelayed( Assets.Sounds.LULLABY, 0.1f ); + + for (Mob mob : Dungeon.level.mobs.toArray( new Mob[0] )) { + if (Dungeon.level.heroFOV[mob.pos] && mob != target && mob.alignment != Char.Alignment.ALLY) { + Buff.affect( mob, Charm.class, Charm.DURATION ).object = curUser.id(); + mob.sprite.centerEmitter().start( Speck.factory( Speck.HEART ), 0.2f, 5 ); + } + } + + if (target != null){ + if (!target.isImmune(Enthralled.class)){ + AllyBuff.affectAndLoot(target, curUser, Enthralled.class); + + } else { + Buff.affect( target, Charm.class, Charm.DURATION ).object = curUser.id(); + + } + target.sprite.centerEmitter().burst( Speck.factory( Speck.HEART ), 10 ); + } else { + GLog.w(Messages.get(ScrollOfSirensSong.class, "no_target")); + } + + identify(); + + readAnimation(); + + } + } + + @Override + public String prompt() { + return Messages.get(ScrollOfSirensSong.class, "prompt"); + } + + }; + + public static class Enthralled extends AllyBuff { + + { + type = buffType.NEGATIVE; + announced = true; + } + + @Override + public void fx(boolean on) { + if (on) target.sprite.add(CharSprite.State.HEARTS); + else target.sprite.remove(CharSprite.State.HEARTS); + } + + @Override + public int icon() { + return BuffIndicator.HEART; + } + + @Override + public String toString() { + return Messages.get(this, "name"); + } + + @Override + public String desc() { + return Messages.get(this, "desc"); + } + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java index 03da32af8..75bd208df 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java @@ -82,7 +82,7 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip protected float shadowOffset = 0.25f; public enum State { - BURNING, LEVITATING, INVISIBLE, PARALYSED, FROZEN, ILLUMINATED, CHILLED, DARKENED, MARKED, HEALING, SHIELDED + BURNING, LEVITATING, INVISIBLE, PARALYSED, FROZEN, ILLUMINATED, CHILLED, DARKENED, MARKED, HEALING, SHIELDED, HEARTS } private int stunStates = 0; @@ -102,6 +102,7 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip protected Emitter marked; protected Emitter levitation; protected Emitter healing; + protected Emitter hearts; protected IceBlock iceBlock; protected DarkBlock darkBlock; @@ -394,6 +395,10 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip case SHIELDED: GameScene.effect( shield = new ShieldHalo( this )); break; + case HEARTS: + hearts = emitter(); + hearts.pour(Speck.factory(Speck.HEART), 0.5f); + break; } } @@ -461,6 +466,12 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip shield.putOut(); } break; + case HEARTS: + if (hearts != null){ + hearts.on = false; + hearts = null; + } + break; } } @@ -514,6 +525,12 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip if (marked != null) { marked.visible = visible; } + if (healing != null){ + healing.visible = visible; + } + if (hearts != null){ + hearts.visible = visible; + } if (aura != null){ if (aura.parent == null){ aura.show(this, 0); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java index 2308ab993..e8969aa6a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java @@ -774,11 +774,11 @@ public class ItemSpriteSheet { public static final int SCROLL_PRISIMG = EXOTIC_SCROLLS+3; public static final int SCROLL_MYSTENRG = EXOTIC_SCROLLS+4; public static final int SCROLL_PASSAGE = EXOTIC_SCROLLS+5; - public static final int SCROLL_AFFECTION= EXOTIC_SCROLLS+6; + public static final int SCROLL_SIREN = EXOTIC_SCROLLS+6; public static final int SCROLL_FORESIGHT= EXOTIC_SCROLLS+7; public static final int SCROLL_CONFUSION= EXOTIC_SCROLLS+8; public static final int SCROLL_PSIBLAST = EXOTIC_SCROLLS+9; - public static final int SCROLL_DREAD = EXOTIC_SCROLLS+10; + public static final int SCROLL_DREAD = EXOTIC_SCROLLS+10; public static final int SCROLL_POLYMORPH= EXOTIC_SCROLLS+11; static { assignIconRect( SCROLL_ENCHANT, 7, 7 ); @@ -787,7 +787,7 @@ public class ItemSpriteSheet { assignIconRect( SCROLL_PRISIMG, 5, 7 ); assignIconRect( SCROLL_MYSTENRG, 7, 5 ); assignIconRect( SCROLL_PASSAGE, 5, 7 ); - assignIconRect( SCROLL_AFFECTION, 7, 6 ); + assignIconRect( SCROLL_SIREN, 7, 6 ); assignIconRect( SCROLL_FORESIGHT, 7, 5 ); assignIconRect( SCROLL_CONFUSION, 7, 7 ); assignIconRect( SCROLL_PSIBLAST, 5, 6 );