v0.2.3: completed Dried Rose implementation

This commit is contained in:
Evan Debenham 2014-12-14 05:21:08 -05:00
parent 8ee4483004
commit 3ee8472e19

View File

@ -4,6 +4,7 @@ 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.blobs.ToxicGas;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
@ -13,10 +14,12 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShaftParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfPsionicBlast;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.GhostSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlot;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndQuest;
import com.watabou.noosa.audio.Sample;
@ -52,6 +55,11 @@ public class DriedRose extends Artifact {
public static final String AC_SUMMON = "SUMMON";
public DriedRose(){
super();
talkedTo = firstSummon = spawned = false;
}
@Override
public ArrayList<String> actions( Hero hero ) {
ArrayList<String> actions = super.actions( hero );
@ -64,7 +72,7 @@ public class DriedRose extends Artifact {
public void execute( Hero hero, String action ) {
if (action.equals(AC_SUMMON)) {
if (spawned) GLog.n("sad ghost: I'm already here");
if (spawned) GLog.n("sad ghost: \"I'm already here\"");
else if (!isEquipped( hero )) GLog.i("You need to equip your rose to do that.");
else if (charge != chargeCap) GLog.i("Your rose isn't fully charged yet.");
else if (cursed) GLog.i("You cannot use a cursed rose.");
@ -78,7 +86,7 @@ public class DriedRose extends Artifact {
}
if (spawnPoints.size() > 0) {
GhostHero ghost = new GhostHero();
GhostHero ghost = new GhostHero( level );
ghost.pos = Random.element(spawnPoints);
GameScene.add(ghost, 1f);
@ -89,7 +97,15 @@ public class DriedRose extends Artifact {
hero.busy();
hero.sprite.operate(hero.pos);
if (!firstSummon) {
ghost.yell(ghost.VOICE_HELLO + Dungeon.hero.className());
Sample.INSTANCE.play( Assets.SND_GHOST );
firstSummon = true;
} else
ghost.saySpawned();
spawned = true;
charge = 0;
} else
GLog.i("There is no free space near you.");
}
@ -101,7 +117,28 @@ public class DriedRose extends Artifact {
@Override
public String desc() {
return "";
String desc =
"Is this the rose that the ghost mentioned before disappearing? It seems to hold some spiritual power,"+
" perhaps it can be used to channel the energy of that lost warrior.";
if (isEquipped( Dungeon.hero )){
if (!cursed){
desc += "\n\nThe rose rests in your hand, it feels strangely warm.";
if (level < 5)
desc+= "\n\nThe rose has lost most of its petals. It feels extremely frail, like it " +
"could snap any moment.";
else if (level < 10)
desc+= "\n\nYou have reattached many petals and the rose has started to somehow come back to life."+
" It almost looks like it's read to bloom.";
else
desc+= "\n\nThe rose has blossomed again through some kind of magic, its connection to your spirit"+
" friend is stronger than ever.";
} else
desc += "\n\nThe cursed rose is bound to you hand, it feels eerily cold.";
}
return desc;
}
@Override
@ -147,7 +184,7 @@ public class DriedRose extends Artifact {
if (charge < chargeCap && !cursed) {
//TODO: investigate balancing on this.
partialCharge += 1/10f;
partialCharge += 10/75f;
if (partialCharge > 1){
charge++;
partialCharge--;
@ -165,18 +202,20 @@ public class DriedRose extends Artifact {
if (Actor.findChar(p) == null && (Level.passable[p] || Level.avoid[p])) {
spawnPoints.add(p);
}
if (spawnPoints.size() > 0) {
Wraith wraith = new Wraith();
wraith.pos = Random.element(spawnPoints);
wraith.adjustStats(Dungeon.depth);
GameScene.add(wraith, 1f);
Sample.INSTANCE.play(Assets.SND_CURSED);
}
}
if (spawnPoints.size() > 0) {
Wraith.spawnAt(Random.element(spawnPoints));
Sample.INSTANCE.play(Assets.SND_CURSED);
}
}
return super.act();
QuickSlot.refresh();
spend( TICK );
return true;
}
}
@ -198,7 +237,7 @@ public class DriedRose extends Artifact {
if (rose.level == rose.levelCap) {
GLog.p("The rose is completed!");
Sample.INSTANCE.play( Assets.SND_GHOST );
GLog.n("sad ghost: Thank you...");
GLog.n("sad ghost: \"Thank you...\"");
} else
GLog.i("You add the petal to the rose.");
@ -223,10 +262,6 @@ public class DriedRose extends Artifact {
//TODO: needs to:
//have combat stats
//attack only nearby enemies
//Be tethered to the player
//Enemies must be able/want to attack it
//Must be lost on level transition.
public static class GhostHero extends NPC {
{
@ -238,14 +273,48 @@ public class DriedRose extends Artifact {
state = WANDERING;
enemy = DUMMY;
ally = true;
}
GhostHero() {
public GhostHero() {
super();
if (!DriedRose.firstSummon){
yell ( VOICE_HELLO );
DriedRose.firstSummon = true;
}
//double heroes defence skill
defenseSkill = (Dungeon.hero.lvl+4)*2;
}
public GhostHero(int roseLevel){
this();
HP = HT = 10+roseLevel*3;
}
public void saySpawned(){
int i = (Dungeon.depth - 1) / 5;
if (chooseEnemy() == DUMMY)
yell( Random.element( VOICE_AMBIENT[i] ) );
else
yell( Random.element( VOICE_ENEMIES[i][ Dungeon.bossLevel() ? 1 : 0 ] ) );
Sample.INSTANCE.play( Assets.SND_GHOST );
}
public void sayAnhk(){
yell( Random.element( VOICE_BLESSEDANKH ) );
Sample.INSTANCE.play( Assets.SND_GHOST );
}
public void sayDefeated(){
yell( Random.element( VOICE_DEFEATED[ Dungeon.bossLevel() ? 1 : 0 ] ) );
Sample.INSTANCE.play( Assets.SND_GHOST );
}
public void sayHeroKilled(){
yell(Random.element(VOICE_HEROKILLED));
Sample.INSTANCE.play( Assets.SND_GHOST );
}
public void sayBossBeaten(){
yell( Random.element( VOICE_BOSSBEATEN[ Dungeon.depth==25 ? 1 : 0 ] ) );
Sample.INSTANCE.play( Assets.SND_GHOST );
}
@Override
@ -253,20 +322,34 @@ public class DriedRose extends Artifact {
return "evaded";
}
@Override
protected boolean act() {
if (Random.Int(10) == 0) damage(1 , this);
if (!isAlive())
return true;
if (!Dungeon.hero.isAlive()){
sayHeroKilled();
sprite.die();
destroy();
return true;
}
return super.act();
}
@Override
protected boolean getCloser( int target ) {
if (state == WANDERING)
if (state == WANDERING || Level.distance(target, Dungeon.hero.pos) > 6)
this.target = target = Dungeon.hero.pos;
return super.getCloser( target );
}
@Override
protected Char chooseEnemy() {
if (enemy == DUMMY || !enemy.isAlive()) {
if (enemy == DUMMY || !enemy.isAlive() || state == WANDERING) {
HashSet<Mob> enemies = new HashSet<Mob>();
for (Mob mob : Dungeon.level.mobs) {
if (mob.hostile && Level.fieldOfView[mob.pos]) {
if (mob.hostile && Level.fieldOfView[mob.pos] && mob.state != mob.PASSIVE) {
enemies.add(mob);
}
}
@ -276,11 +359,27 @@ public class DriedRose extends Artifact {
}
@Override
public void damage( int dmg, Object src ) {
public int attackSkill(Char target) {
//same accuracy as the hero.
return (defenseSkill/2)+5;
}
@Override
public int damageRoll() {
//equivalent to N/2 to 5+N, where N is rose level.
int lvl = (HT-10)/3;
return Random.NormalIntRange( lvl/2, 5+lvl);
}
@Override
public int dr() {
//defence is equal to the level of rose.
return (HT-10)/3;
}
@Override
public void add( Buff buff ) {
//in other words, can't be directly affected by buffs/debuffs.
}
@Override
@ -302,32 +401,47 @@ public class DriedRose extends Artifact {
}
}
@Override
public void die(Object cause) {
sayDefeated();
super.die(cause);
}
@Override
public void destroy() {
DriedRose.spawned = false;
super.destroy();
}
@Override
public String description() {
return
"A frail looking ethereal figure with a humanoid shape. Its power seems tied to the rose I have." +
"\n\nThis ghost may not be much, but it seems to be my only true friend down here.";
}
private static final HashSet<Class<?>> IMMUNITIES = new HashSet<Class<?>>();
static {
IMMUNITIES.add( ToxicGas.class );
IMMUNITIES.add( ScrollOfPsionicBlast.class );
}
@Override
public HashSet<Class<?>> immunities() {
return IMMUNITIES;
}
//************************************************************************************
//This is a bunch strings & string arrays, used in all of the sad ghost's voice lines.
//************************************************************************************
public static final String VOICE_HELLO = "Hello again.";
public static final String VOICE_HELLO = "Hello again ";
private static final String VOICE_INTRODUCE = "My spirit is bound to this rose, it was very precious to me, a "+
"gift from my love whom I left on the surface.\n\nI cannot return to him, but thanks to you I have a " +
"second chance to complete my journey. When I am able I will respond to your call and fight with you.\n\n" +
"hopefully you may succeed where I failed...";
//enum, for clarity.
public static enum DEPTHS{
SEWERS,
PRISON,
CAVES,
CITY,
HALLS,
AMULET
}
//1st index - depth type, 2nd index - specific line.
public static final String[][] VOICE_AMBIENT = {
{
@ -409,7 +523,7 @@ public class DriedRose extends Artifact {
}
},{
{
"Hello source viewer, I'm writing this here as this line should never trigger. Have a nice day!"
"I don't like this place... we should leave as soon as we can..."
},{
"Hello source viewer, I'm writing this here as this line should never trigger. Have a nice day!"
}