v0.9.3: implemented the ratmogrify ability

This commit is contained in:
Evan Debenham 2021-05-17 20:53:28 -04:00
parent 92570e6f78
commit 0272216f9a
12 changed files with 221 additions and 22 deletions

View File

@ -378,8 +378,12 @@ actors.hero.abilities.huntress.spirithawk.short_desc=The Huntress summons a _Spi
actors.hero.abilities.huntress.spirithawk.desc=TODO
actors.hero.abilities.ratmogrify.name=ratmogrify
actors.hero.abilities.ratmogrify.short_desc=The hero _ratmogrifies_ an enemy! This temporarily turns them into a rat with weakened attack power and no abilities.
actors.hero.abilities.ratmogrify.cant_transform=You can't ratmogrify that!
actors.hero.abilities.ratmogrify.too_strong=That enemy is too strong to ratmogrify!
actors.hero.abilities.ratmogrify.short_desc=The hero _Ratmogrifies_ an enemy! This turns them into a rat with no abilities, but also no loot.
actors.hero.abilities.ratmogrify.desc=TODO
actors.hero.abilities.ratmogrify$transmograt.name=ratmogrified %s
actors.hero.abilities.ratmogrify$transmograt.desc=TODO
actors.hero.hero.name=you
actors.hero.hero.leave=You can't leave yet, the rest of the dungeon awaits below!
@ -689,12 +693,12 @@ actors.hero.talent.huntress_3_3.desc=TODO DESC
actors.hero.talent.heroic_energy.title=heroic energy
actors.hero.talent.heroic_energy.desc=_+1:_ The hero's armor ability has a _13% reduced_ charge cost.\n\n_+2:_ The hero's armor ability has a _24% reduced_ charge cost.\n\n_+3:_ The hero's armor ability has a _34% reduced_ charge cost.\n\n_+4:_ The hero's armor ability has a _43% reduced_ charge cost
actors.hero.talent.rk_1.title=TODO NAME
actors.hero.talent.rk_1.desc=TODO DESC
actors.hero.talent.rk_2.title=TODO NAME
actors.hero.talent.rk_2.desc=TODO DESC
actors.hero.talent.rk_3.title=TODO NAME
actors.hero.talent.rk_3.desc=TODO DESC
actors.hero.talent.ratsistance.title=ratsistance
actors.hero.talent.ratsistance.desc=_+1:_ Hostile ratmogrified enemies deal _-10% damage_.\n\n_+2:_ Hostile ratmogrified enemies deal _-20% damage_.\n\n_+3:_ Hostile ratmogrified enemies deal _-30% damage_.\n\n_+4:_ Hostile ratmogrified enemies deal _-40% damage_.
actors.hero.talent.ratlomacy.title=ratlomacy
actors.hero.talent.ratlomacy.desc=_+1:_ Using ratmogrify on a ratmogrified enemy makes them permanently friendly.\n\n_+2:_ Using ratmogrify on a ratmogrified enemy makes them permanently friendly and gives them _2 turns_ of adrenaline.\n\n_+3:_ Using ratmogrify on a ratmogrified enemy makes them permanently friendly and gives them _4 turns_ of adrenaline.\n\n_+4:_ Using ratmogrify on a ratmogrified enemy makes them permanently friendly and gives them _6 turns_ of adrenaline.
actors.hero.talent.ratforcements.title=ratforcements
actors.hero.talent.ratforcements.desc=_+1:_ Using ratmogrify on yourself _spawns 1_ ally marsupial rat next to you.\n\n_+2:_ Using ratmogrify on yourself _spawns 2_ ally marsupial rats next to you.\n\n_+3:_ Using ratmogrify on yourself _spawns 3_ ally marsupial rats next to you.\n\n_+4:_ Using ratmogrify on yourself _spawns 4_ ally marsupial rats next to you.
@ -753,7 +757,8 @@ actors.mobs.npcs.ratking.confused=Wha... Where am I? My kingdom needs me!
actors.mobs.npcs.ratking.crown_clothes=Put some clothes on! You're in no state to talk to royalty!
actors.mobs.npcs.ratking.crown_desc=Oooh, is that crown for me!? It looks much shinier than mine, so I graciously accept!\n\nIn fact, I think I can offer you something as a reward for this crown. A tremendous power befitting a hero such as yourself! Would you like that?
actors.mobs.npcs.ratking.crown_yes=Of course!
actors.mobs.npcs.ratking.crown_no=I'm not so sure...
actors.mobs.npcs.ratking.crown_info=Tell me more first.
actors.mobs.npcs.ratking.crown_no=I'd rather not...
actors.mobs.npcs.ratking.crown_thankyou=Hehehe, thank you! Now go and make your king proud!
actors.mobs.npcs.ratking.crown_fine=Fine! It's not like I wanted it anyway...
actors.mobs.npcs.ratking.crown_after=Enjoying your new armor? No take-backsies!

View File

@ -138,8 +138,8 @@ public enum Talent {
//universal T4
HEROIC_ENERGY(123, 4),
//??? T4
RK_1(125, 4), RK_2(126, 4), RK_3(127, 4);
//Ratmogrify T4
RATSISTANCE(125, 4), RATLOMACY(126, 4), RATFORCEMENTS(127, 4);
public static class ImprovisedProjectileCooldown extends FlavourBuff{};
public static class LethalMomentumTracker extends FlavourBuff{};

View File

@ -1,18 +1,207 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities;
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.Adrenaline;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Rat;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.MirrorImage;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.RatSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.TargetHealthIndicator;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundle;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Random;
import java.util.ArrayList;
public class Ratmogrify extends ArmorAbility {
@Override
protected String targetingPrompt() {
return Messages.get(this, "prompt");
}
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
//TODO
if (target == null){
return;
}
Char ch = Actor.findChar(target);
if (ch == null) {
GLog.w(Messages.get(this, "no_target"));
return;
} else if (ch == hero){
if (!hero.hasTalent(Talent.RATFORCEMENTS)){
GLog.w(Messages.get(this, "self_target"));
} else {
ArrayList<Integer> spawnPoints = new ArrayList<>();
for (int i = 0; i < PathFinder.NEIGHBOURS8.length; i++) {
int p = hero.pos + PathFinder.NEIGHBOURS8[i];
if (Actor.findChar( p ) == null && Dungeon.level.passable[p]) {
spawnPoints.add( p );
}
}
int ratsToSpawn = hero.pointsInTalent(Talent.RATFORCEMENTS);
while (ratsToSpawn > 0 && spawnPoints.size() > 0) {
int index = Random.index( spawnPoints );
Rat rat = new Rat();
rat.alignment = Char.Alignment.ALLY;
rat.state = rat.HUNTING;
GameScene.add( rat );
ScrollOfTeleportation.appear( rat, spawnPoints.get( index ) );
spawnPoints.remove( index );
ratsToSpawn--;
}
}
} else if (ch.alignment != Char.Alignment.ENEMY || !(ch instanceof Mob) || ch instanceof Rat){
GLog.w(Messages.get(this, "cant_transform"));
return;
} else if (ch instanceof TransmogRat){
if (((TransmogRat) ch).allied || !hero.hasTalent(Talent.RATLOMACY)){
GLog.w(Messages.get(this, "cant_transform"));
return;
} else {
((TransmogRat) ch).makeAlly();
ch.sprite.emitter().start(Speck.factory(Speck.HEART), 0.2f, 5);
Sample.INSTANCE.play(Assets.Sounds.TELEPORT);
if (hero.pointsInTalent(Talent.RATLOMACY) > 1){
Buff.affect(ch, Adrenaline.class, 2*(hero.pointsInTalent(Talent.RATLOMACY)-1));
}
}
} else if (Char.hasProp(ch, Char.Property.MINIBOSS) || Char.hasProp(ch, Char.Property.BOSS)){
GLog.w(Messages.get(this, "too_strong"));
} else {
TransmogRat rat = new TransmogRat();
rat.setup((Mob)ch);
rat.pos = ch.pos;
Actor.remove( ch );
ch.sprite.killAndErase();
Dungeon.level.mobs.remove(ch);
GameScene.add(rat);
TargetHealthIndicator.instance.target(null);
CellEmitter.get(rat.pos).burst(Speck.factory(Speck.WOOL), 4);
Sample.INSTANCE.play(Assets.Sounds.PUFF);
}
armor.charge -= chargeUse(hero);
armor.updateQuickslot();
hero.spendAndNext(Actor.TICK);
}
@Override
public Talent[] talents() {
return new Talent[]{ Talent.RK_1, Talent.RK_2, Talent.RK_3, Talent.HEROIC_ENERGY};
return new Talent[]{ Talent.RATSISTANCE, Talent.RATLOMACY, Talent.RATFORCEMENTS, Talent.HEROIC_ENERGY};
}
public static class TransmogRat extends Mob {
{
spriteClass = RatSprite.class;
maxLvl = -2;
}
private Mob original;
private boolean allied;
public void setup(Mob original) {
this.original = original;
HP = original.HP;
HT = original.HT;
defenseSkill = original.defenseSkill;
EXP = original.EXP;
if (original.state == original.SLEEPING) {
state = SLEEPING;
} else if (original.state == original.HUNTING) {
state = HUNTING;
} else {
state = WANDERING;
}
}
public void makeAlly() {
allied = true;
alignment = Alignment.ALLY;
}
public int attackSkill(Char target) {
return original.attackSkill(target);
}
public int drRoll() {
return original.drRoll();
}
@Override
public int damageRoll() {
int damage = original.damageRoll();
if (!allied && Dungeon.hero.hasTalent(Talent.RATSISTANCE)){
damage = Math.round(damage * (1f - .1f*Dungeon.hero.pointsInTalent(Talent.RATSISTANCE)));
}
return damage;
}
@Override
public float attackDelay() {
return original.attackDelay();
}
@Override
public String name() {
return Messages.get(this, "name", original.name());
}
private static final String ORIGINAL = "original";
private static final String ALLIED = "allied";
@Override
public void storeInBundle(Bundle bundle) {
super.storeInBundle(bundle);
bundle.put(ORIGINAL, original);
bundle.put(ALLIED, allied);
}
@Override
public void restoreFromBundle(Bundle bundle) {
super.restoreFromBundle(bundle);
original = (Mob) bundle.get(ORIGINAL);
defenseSkill = original.defenseSkill;
EXP = original.EXP;
allied = bundle.getBoolean(ALLIED);
if (allied) alignment = Alignment.ALLY;
}
}
}

View File

@ -100,7 +100,7 @@ public abstract class Mob extends Char {
protected int target = -1;
protected int defenseSkill = 0;
public int defenseSkill = 0;
public int EXP = 1;
public int maxLvl = Hero.MAX_LEVEL;
@ -518,7 +518,7 @@ public abstract class Mob extends Char {
sprite.add( CharSprite.State.PARALYSED );
}
protected float attackDelay() {
public float attackDelay() {
float delay = 1f;
if ( buff(Adrenaline.class) != null) delay /= 1.5f;
return delay;

View File

@ -62,7 +62,7 @@ public class Monk extends Mob {
}
@Override
protected float attackDelay() {
public float attackDelay() {
return super.attackDelay()*0.5f;
}

View File

@ -40,8 +40,9 @@ public class Rat extends Mob {
@Override
protected boolean act() {
if (Dungeon.hero.armorAbility instanceof Ratmogrify){
alignment = Alignment.NEUTRAL;
if (Dungeon.level.heroFOV[pos] && Dungeon.hero.armorAbility instanceof Ratmogrify){
alignment = Alignment.ALLY;
if (state == SLEEPING) state = WANDERING;
}
return super.act();
}

View File

@ -77,7 +77,7 @@ public class RipperDemon extends Mob {
}
@Override
protected float attackDelay() {
public float attackDelay() {
return super.attackDelay()*0.5f;
}

View File

@ -94,7 +94,7 @@ public class Statue extends Mob {
}
@Override
protected float attackDelay() {
public float attackDelay() {
return super.attackDelay()*weapon.speedFactor( this );
}

View File

@ -87,7 +87,7 @@ public class Thief extends Mob {
}
@Override
protected float attackDelay() {
public float attackDelay() {
return super.attackDelay()*0.5f;
}

View File

@ -129,7 +129,7 @@ public class MirrorImage extends NPC {
}
@Override
protected float attackDelay() {
public float attackDelay() {
return hero.attackDelay(); //handles ring of furor
}

View File

@ -29,6 +29,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.KingsCrown;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.RatKingSprite;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndInfoArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
import com.watabou.noosa.Game;
import com.watabou.utils.Callback;
@ -126,6 +127,7 @@ public class RatKing extends NPC {
Messages.titleCase(name()),
Messages.get(RatKing.class, "crown_desc"),
Messages.get(RatKing.class, "crown_yes"),
Messages.get(RatKing.class, "crown_info"),
Messages.get(RatKing.class, "crown_no")
){
@Override
@ -134,6 +136,8 @@ public class RatKing extends NPC {
crown.upgradeArmor(Dungeon.hero, Dungeon.hero.belongings.armor, new Ratmogrify());
((RatKingSprite)sprite).resetAnims();
yell(Messages.get(RatKing.class, "crown_thankyou"));
} else if (index == 1) {
GameScene.show(new WndInfoArmorAbility(Dungeon.hero.heroClass, new Ratmogrify()));
} else {
yell(Messages.get(RatKing.class, "crown_fine"));
}

View File

@ -604,7 +604,7 @@ public class DriedRose extends Artifact {
}
@Override
protected float attackDelay() {
public float attackDelay() {
float delay = super.attackDelay();
if (rose != null && rose.weapon != null){
delay *= rose.weapon.speedFactor(this);