v1.1.0: reworked scroll of affection into scroll of siren's song

This commit is contained in:
Evan Debenham 2021-10-23 16:22:41 -04:00
parent 6a61d0851b
commit 7839cdce66
7 changed files with 180 additions and 68 deletions

View File

@ -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.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.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.scrollofsirenssong.name=scroll of siren's song
items.scrolls.exotic.scrollofaffection.desc=Reading this scroll will emit an alluring laugh which charms all who hear it. 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.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. 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.

View File

@ -45,9 +45,13 @@ public class ShatteredPixelDungeon extends Game {
public ShatteredPixelDungeon( PlatformSupport platform ) { public ShatteredPixelDungeon( PlatformSupport platform ) {
super( sceneClass == null ? WelcomeScene.class : sceneClass, platform ); super( sceneClass == null ? WelcomeScene.class : sceneClass, platform );
//v1.1.0
com.watabou.utils.Bundle.addAlias( com.watabou.utils.Bundle.addAlias(
com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfDread.class, com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfDread.class,
"com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfPetrification" ); "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 //v1.0.0
com.watabou.utils.Bundle.addAlias( com.watabou.utils.Bundle.addAlias(

View File

@ -57,8 +57,8 @@ public abstract class ExoticScroll extends Scroll {
regToExo.put(ScrollOfRemoveCurse.class, ScrollOfAntiMagic.class); regToExo.put(ScrollOfRemoveCurse.class, ScrollOfAntiMagic.class);
exoToReg.put(ScrollOfAntiMagic.class, ScrollOfRemoveCurse.class); exoToReg.put(ScrollOfAntiMagic.class, ScrollOfRemoveCurse.class);
regToExo.put(ScrollOfLullaby.class, ScrollOfAffection.class); regToExo.put(ScrollOfLullaby.class, ScrollOfSirensSong.class);
exoToReg.put(ScrollOfAffection.class, ScrollOfLullaby.class); exoToReg.put(ScrollOfSirensSong.class, ScrollOfLullaby.class);
regToExo.put(ScrollOfRage.class, ScrollOfConfusion.class); regToExo.put(ScrollOfRage.class, ScrollOfConfusion.class);
exoToReg.put(ScrollOfConfusion.class, ScrollOfRage.class); exoToReg.put(ScrollOfConfusion.class, ScrollOfRage.class);

View File

@ -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 <http://www.gnu.org/licenses/>
*/
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();
}
}

View File

@ -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 <http://www.gnu.org/licenses/>
*/
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");
}
}
}

View File

@ -82,7 +82,7 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
protected float shadowOffset = 0.25f; protected float shadowOffset = 0.25f;
public enum State { 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; private int stunStates = 0;
@ -102,6 +102,7 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
protected Emitter marked; protected Emitter marked;
protected Emitter levitation; protected Emitter levitation;
protected Emitter healing; protected Emitter healing;
protected Emitter hearts;
protected IceBlock iceBlock; protected IceBlock iceBlock;
protected DarkBlock darkBlock; protected DarkBlock darkBlock;
@ -394,6 +395,10 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
case SHIELDED: case SHIELDED:
GameScene.effect( shield = new ShieldHalo( this )); GameScene.effect( shield = new ShieldHalo( this ));
break; 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(); shield.putOut();
} }
break; 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) { if (marked != null) {
marked.visible = visible; marked.visible = visible;
} }
if (healing != null){
healing.visible = visible;
}
if (hearts != null){
hearts.visible = visible;
}
if (aura != null){ if (aura != null){
if (aura.parent == null){ if (aura.parent == null){
aura.show(this, 0); aura.show(this, 0);

View File

@ -774,11 +774,11 @@ public class ItemSpriteSheet {
public static final int SCROLL_PRISIMG = EXOTIC_SCROLLS+3; public static final int SCROLL_PRISIMG = EXOTIC_SCROLLS+3;
public static final int SCROLL_MYSTENRG = EXOTIC_SCROLLS+4; public static final int SCROLL_MYSTENRG = EXOTIC_SCROLLS+4;
public static final int SCROLL_PASSAGE = EXOTIC_SCROLLS+5; 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_FORESIGHT= EXOTIC_SCROLLS+7;
public static final int SCROLL_CONFUSION= EXOTIC_SCROLLS+8; public static final int SCROLL_CONFUSION= EXOTIC_SCROLLS+8;
public static final int SCROLL_PSIBLAST = EXOTIC_SCROLLS+9; 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; public static final int SCROLL_POLYMORPH= EXOTIC_SCROLLS+11;
static { static {
assignIconRect( SCROLL_ENCHANT, 7, 7 ); assignIconRect( SCROLL_ENCHANT, 7, 7 );
@ -787,7 +787,7 @@ public class ItemSpriteSheet {
assignIconRect( SCROLL_PRISIMG, 5, 7 ); assignIconRect( SCROLL_PRISIMG, 5, 7 );
assignIconRect( SCROLL_MYSTENRG, 7, 5 ); assignIconRect( SCROLL_MYSTENRG, 7, 5 );
assignIconRect( SCROLL_PASSAGE, 5, 7 ); assignIconRect( SCROLL_PASSAGE, 5, 7 );
assignIconRect( SCROLL_AFFECTION, 7, 6 ); assignIconRect( SCROLL_SIREN, 7, 6 );
assignIconRect( SCROLL_FORESIGHT, 7, 5 ); assignIconRect( SCROLL_FORESIGHT, 7, 5 );
assignIconRect( SCROLL_CONFUSION, 7, 7 ); assignIconRect( SCROLL_CONFUSION, 7, 7 );
assignIconRect( SCROLL_PSIBLAST, 5, 6 ); assignIconRect( SCROLL_PSIBLAST, 5, 6 );