v0.9.3: restructured class armors around variable abilities

This commit is contained in:
Evan Debenham 2021-04-12 21:24:44 -04:00
parent 9a8c127709
commit 541d3105fd
20 changed files with 663 additions and 248 deletions

View File

@ -333,12 +333,32 @@ actors.buffs.wellfed.desc=You feel quite satisfied and full.\n\nWhile well fed,
###hero
##abilities
actors.hero.abilities.warrior.warrior1.name=heroic leap
actors.hero.abilities.warrior.warrior1.desc=Allows the Warrior to perform a heroic leap towards a targeted location, slamming down to stun all neighbouring enemies.
actors.hero.abilities.warrior.warrior2.name=shockwave
actors.hero.abilities.warrior.warrior2.desc=Allows the Warrior to slam the ground, disrupting all enemies in a cone AOE in front of him.
actors.hero.abilities.warrior.heroicleap.name=heroic leap
actors.hero.abilities.warrior.heroicleap.desc=The Warrior performs a heroic leap towards a targeted location, slamming down to stun all neighbouring enemies.
actors.hero.abilities.warrior.heroicleap.prompt=Choose direction to leap
actors.hero.abilities.warrior.warrior2.name=???
actors.hero.abilities.warrior.warrior2.desc=I haven't decided on this ability yet.
actors.hero.abilities.warrior.warrior3.name=???
actors.hero.abilities.warrior.warrior3.desc=I haven't decided on this ability yet
actors.hero.abilities.warrior.warrior3.desc=I haven't decided on this ability yet.
actors.hero.abilities.mage.moltenearth.name=molten earth
actors.hero.abilities.mage.moltenearth.desc=The Mage casts a spell of molten earth. All the enemies in his field of view will be rooted to the ground and blasted by flames.
actors.hero.abilities.mage.mage2.name=???
actors.hero.abilities.mage.mage2.desc=I haven't decided on this ability yet.
actors.hero.abilities.mage.mage3.name=???
actors.hero.abilities.mage.mage3.desc=I haven't decided on this ability yet.
actors.hero.abilities.rogue.smokebomb.name=smoke bomb
actors.hero.abilities.rogue.smokebomb.desc=The Rogue blinks to any nearby location which he can see, leaving a plume of smoke where he stood. This ability makes the rogue temporarily invisible, and blinds any enemies adjacent to his old location.
actors.hero.abilities.rogue.smokebomb.prompt=Choose a location to jump to
actors.hero.abilities.rogue.rogue2.name=???
actors.hero.abilities.rogue.rogue2.desc=I haven't decided on this ability yet.
actors.hero.abilities.rogue.rogue3.name=???
actors.hero.abilities.rogue.rogue3.desc=I haven't decided on this ability yet.
actors.hero.abilities.huntress.spectralblades.name=spectral blades
actors.hero.abilities.huntress.spectralblades.desc=The Huntress creates a fan of spectral blades. Each of these blades will target a single enemy in the huntress's field of view, inflicting damage depending on her currently equipped melee weapon.
actors.hero.abilities.huntress.huntress2.name=???
actors.hero.abilities.huntress.huntress2.desc=I haven't decided on this ability yet.
actors.hero.abilities.huntress.huntress3.name=???
actors.hero.abilities.huntress.huntress3.desc=I haven't decided on this ability yet.
actors.hero.hero.name=you
actors.hero.hero.leave=You can't leave yet, the rest of the dungeon awaits below!

View File

@ -27,7 +27,16 @@ import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.QuickSlot;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.Warrior1;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.Huntress2;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.Huntress3;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.SpectralBlades;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.mage.Mage2;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.mage.Mage3;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.mage.MoltenEarth;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.rogue.Rogue2;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.rogue.Rogue3;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.rogue.SmokeBomb;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.HeroicLeap;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.Warrior2;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.Warrior3;
import com.shatteredpixel.shatteredpixeldungeon.items.BrokenSeal;
@ -196,7 +205,16 @@ public enum HeroClass {
}
public ArmorAbility[] armorAbilities(){
return new ArmorAbility[]{new Warrior1(), new Warrior2(), new Warrior3()};
switch (this) {
case WARRIOR: default:
return new ArmorAbility[]{new HeroicLeap(), new Warrior2(), new Warrior3()};
case MAGE:
return new ArmorAbility[]{new MoltenEarth(), new Mage2(), new Mage3()};
case ROGUE:
return new ArmorAbility[]{new SmokeBomb(), new Rogue2(), new Rogue3()};
case HUNTRESS:
return new ArmorAbility[]{new SpectralBlades(), new Huntress2(), new Huntress3()};
}
}
public String spritesheet() {

View File

@ -21,14 +21,41 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.watabou.utils.Bundlable;
import com.watabou.utils.Bundle;
public abstract class ArmorAbility implements Bundlable {
//TODO code for actual effects
public void use( ClassArmor armor, Hero hero ){
if (targetingPrompt() == null){
activate(armor, hero, hero.pos);
} else {
GameScene.selectCell(new CellSelector.Listener() {
@Override
public void onSelect(Integer cell) {
activate(armor, hero, cell);
}
@Override
public String prompt() {
return targetingPrompt();
}
});
}
}
//leave null for no targeting
protected String targetingPrompt(){
return null;
}
protected abstract void activate( ClassArmor armor, Hero hero, Integer target );
public String name(){
return Messages.get(this, "name");

View File

@ -0,0 +1,40 @@
/*
* 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.actors.hero.abilities.huntress;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
public class Huntress2 extends ArmorAbility {
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
//TODO
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.HEARTY_MEAL, Talent.EMPOWERING_MEAL, Talent.CACHED_RATIONS, Talent.NATURES_BOUNTY};
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.actors.hero.abilities.huntress;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
public class Huntress3 extends ArmorAbility {
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
//TODO
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.HEARTY_MEAL, Talent.EMPOWERING_MEAL, Talent.CACHED_RATIONS, Talent.NATURES_BOUNTY};
}
}

View File

@ -0,0 +1,89 @@
/*
* 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.actors.hero.abilities.huntress;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Shuriken;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.MissileSprite;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.utils.Callback;
import java.util.HashMap;
public class SpectralBlades extends ArmorAbility {
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
armor.charge -= 35;
Item.updateQuickslot();
Item proto = new Shuriken();
final HashMap<Callback, Mob> targets = new HashMap<>();
for (Mob mob : Dungeon.level.mobs) {
if (Dungeon.level.distance(hero.pos, mob.pos) <= 12
&& Dungeon.level.heroFOV[mob.pos]
&& mob.alignment != Char.Alignment.ALLY) {
Callback callback = new Callback() {
@Override
public void call() {
hero.attack( targets.get( this ) );
targets.remove( this );
if (targets.isEmpty()) {
Invisibility.dispel();
hero.spendAndNext( hero.attackDelay() );
}
}
};
((MissileSprite)hero.sprite.parent.recycle( MissileSprite.class )).
reset( hero.sprite, mob.pos, proto, callback );
targets.put( callback, mob );
}
}
if (targets.size() == 0) {
GLog.w( Messages.get(this, "no_enemies") );
return;
}
hero.sprite.zap( hero.pos );
hero.busy();
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.NATURES_BOUNTY, Talent.SURVIVALISTS_INTUITION, Talent.FOLLOWUP_STRIKE, Talent.NATURES_AID};
}
}

View File

@ -19,15 +19,22 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior;
package com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.mage;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
public class Warrior1 extends ArmorAbility {
public class Mage2 extends ArmorAbility {
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
//TODO
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.HEARTY_MEAL, Talent.ARMSMASTERS_INTUITION, Talent.TEST_SUBJECT, Talent.IRON_WILL};
return new Talent[]{Talent.HEARTY_MEAL, Talent.EMPOWERING_MEAL, Talent.CACHED_RATIONS, Talent.NATURES_BOUNTY};
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.actors.hero.abilities.mage;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
public class Mage3 extends ArmorAbility {
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
//TODO
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.HEARTY_MEAL, Talent.EMPOWERING_MEAL, Talent.CACHED_RATIONS, Talent.NATURES_BOUNTY};
}
}

View File

@ -0,0 +1,73 @@
/*
* 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.actors.hero.abilities.mage;
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.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Roots;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Random;
public class MoltenEarth extends ArmorAbility {
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
armor.charge -= 35;
Item.updateQuickslot();
for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])) {
if (Dungeon.level.heroFOV[mob.pos]
&& mob.alignment != Char.Alignment.ALLY) {
Buff.affect( mob, Burning.class ).reignite( mob );
Buff.prolong( mob, Roots.class, Roots.DURATION );
mob.damage(Random.NormalIntRange(4, 16 + Dungeon.depth), new Burning());
}
}
hero.spend( Actor.TICK );
hero.sprite.operate( hero.pos );
Invisibility.dispel();
hero.busy();
hero.sprite.emitter().start( ElmoParticle.FACTORY, 0.025f, 20 );
Sample.INSTANCE.play( Assets.Sounds.BURNING );
Sample.INSTANCE.play( Assets.Sounds.BURNING );
Sample.INSTANCE.play( Assets.Sounds.BURNING );
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.EMPOWERING_MEAL, Talent.SCHOLARS_INTUITION, Talent.TESTED_HYPOTHESIS, Talent.BACKUP_BARRIER};
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.actors.hero.abilities.rogue;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
public class Rogue2 extends ArmorAbility {
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
//TODO
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.HEARTY_MEAL, Talent.EMPOWERING_MEAL, Talent.CACHED_RATIONS, Talent.NATURES_BOUNTY};
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.actors.hero.abilities.rogue;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
public class Rogue3 extends ArmorAbility {
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
//TODO
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.HEARTY_MEAL, Talent.EMPOWERING_MEAL, Talent.CACHED_RATIONS, Talent.NATURES_BOUNTY};
}
}

View File

@ -0,0 +1,96 @@
/*
* 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.actors.hero.abilities.rogue;
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.Blindness;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.RogueArmor;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.PathFinder;
public class SmokeBomb extends ArmorAbility {
@Override
protected String targetingPrompt() {
return Messages.get(this, "prompt");
}
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
if (target != null) {
PathFinder.buildDistanceMap(hero.pos, BArray.not(Dungeon.level.solid,null), 8);
if ( PathFinder.distance[target] == Integer.MAX_VALUE ||
!Dungeon.level.heroFOV[target] ||
Actor.findChar( target ) != null) {
GLog.w( Messages.get(RogueArmor.class, "fov") );
return;
}
armor.charge -= 35;
Item.updateQuickslot();
for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])) {
if (Dungeon.level.adjacent(mob.pos, hero.pos) && mob.alignment != Char.Alignment.ALLY) {
Buff.prolong( mob, Blindness.class, Blindness.DURATION/2f );
if (mob.state == mob.HUNTING) mob.state = mob.WANDERING;
mob.sprite.emitter().burst( Speck.factory( Speck.LIGHT ), 4 );
}
}
Buff.affect(hero, Invisibility.class, Invisibility.DURATION/2f);
CellEmitter.get( hero.pos ).burst( Speck.factory( Speck.WOOL ), 10 );
ScrollOfTeleportation.appear( hero, target );
Sample.INSTANCE.play( Assets.Sounds.PUFF );
Dungeon.level.occupyCell( hero );
Dungeon.observe();
GameScene.updateFog();
hero.spendAndNext( Actor.TICK );
}
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.CACHED_RATIONS, Talent.THIEFS_INTUITION, Talent.SUCKER_PUNCH, Talent.PROTECTIVE_SHADOWS};
}
}

View File

@ -0,0 +1,98 @@
/*
* 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.actors.hero.abilities.warrior;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.watabou.noosa.Camera;
import com.watabou.utils.Callback;
import com.watabou.utils.PathFinder;
public class HeroicLeap extends ArmorAbility {
private static int LEAP_TIME = 1;
private static int SHOCK_TIME = 5;
@Override
protected String targetingPrompt() {
return Messages.get(this, "prompt");
}
@Override
public void activate( ClassArmor armor, Hero hero, Integer target ) {
if (target != null && target != hero.pos) {
Ballistica route = new Ballistica(hero.pos, target, Ballistica.PROJECTILE);
int cell = route.collisionPos;
//can't occupy the same cell as another char, so move back one.
if (Actor.findChar( cell ) != null && cell != hero.pos)
cell = route.path.get(route.dist-1);
armor.charge -= 35;
armor.updateQuickslot();
final int dest = cell;
hero.busy();
hero.sprite.jump(hero.pos, cell, new Callback() {
@Override
public void call() {
hero.move(dest);
Dungeon.level.occupyCell(hero);
Dungeon.observe();
GameScene.updateFog();
for (int i = 0; i < PathFinder.NEIGHBOURS8.length; i++) {
Char mob = Actor.findChar(hero.pos + PathFinder.NEIGHBOURS8[i]);
if (mob != null && mob != hero && mob.alignment != Char.Alignment.ALLY) {
Buff.prolong(mob, Paralysis.class, SHOCK_TIME);
}
}
CellEmitter.center(dest).burst(Speck.factory(Speck.DUST), 10);
Camera.main.shake(2, 0.5f);
Invisibility.dispel();
hero.spendAndNext(LEAP_TIME);
}
});
}
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.HEARTY_MEAL, Talent.ARMSMASTERS_INTUITION, Talent.TEST_SUBJECT, Talent.IRON_WILL};
}
}

View File

@ -21,13 +21,20 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
public class Warrior2 extends ArmorAbility {
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
//TODO
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.EMPOWERING_MEAL, Talent.SCHOLARS_INTUITION, Talent.TESTED_HYPOTHESIS, Talent.BACKUP_BARRIER};
return new Talent[]{Talent.HEARTY_MEAL, Talent.EMPOWERING_MEAL, Talent.CACHED_RATIONS, Talent.NATURES_BOUNTY};
}
}

View File

@ -21,13 +21,20 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
public class Warrior3 extends ArmorAbility {
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
//TODO
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.HEARTY_MEAL, Talent.HEARTY_MEAL, Talent.HEARTY_MEAL, Talent.HEARTY_MEAL};
return new Talent[]{Talent.HEARTY_MEAL, Talent.EMPOWERING_MEAL, Talent.CACHED_RATIONS, Talent.NATURES_BOUNTY};
}
}

View File

@ -34,6 +34,7 @@ import java.util.ArrayList;
abstract public class ClassArmor extends Armor {
private static final String AC_SPECIAL = "SPECIAL";
//TODO heroes without an ability need to be able to choose one
{
levelKnown = true;
@ -45,7 +46,7 @@ abstract public class ClassArmor extends Armor {
private int armorTier;
protected float charge = 0;
public float charge = 0;
public ClassArmor() {
super( 6 );
@ -134,8 +135,7 @@ abstract public class ClassArmor extends Armor {
} else if (charge < 35) {
GLog.w( Messages.get(this, "low_charge") );
} else {
curUser = hero;
doSpecial();
hero.armorAbility.use(this, hero);
}
}
@ -149,7 +149,11 @@ abstract public class ClassArmor extends Armor {
updateQuickslot();
}
abstract public void doSpecial();
@Override
public String desc() {
//TODO custom desc, core desc + description of ability
return super.desc();
}
@Override
public int STRReq(int lvl) {

View File

@ -21,19 +21,7 @@
package com.shatteredpixel.shatteredpixeldungeon.items.armor;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Shuriken;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.sprites.MissileSprite;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.utils.Callback;
import java.util.HashMap;
public class HuntressArmor extends ClassArmor {
@ -42,47 +30,4 @@ public class HuntressArmor extends ClassArmor {
image = ItemSpriteSheet.ARMOR_HUNTRESS;
}
private HashMap<Callback, Mob> targets = new HashMap<>();
@Override
public void doSpecial() {
charge -= 35;
updateQuickslot();
Item proto = new Shuriken();
for (Mob mob : Dungeon.level.mobs) {
if (Dungeon.level.distance(curUser.pos, mob.pos) <= 12
&& Dungeon.level.heroFOV[mob.pos]
&& mob.alignment != Char.Alignment.ALLY) {
Callback callback = new Callback() {
@Override
public void call() {
curUser.attack( targets.get( this ) );
targets.remove( this );
if (targets.isEmpty()) {
Invisibility.dispel();
curUser.spendAndNext( curUser.attackDelay() );
}
}
};
((MissileSprite)curUser.sprite.parent.recycle( MissileSprite.class )).
reset( curUser.sprite, mob.pos, proto, callback );
targets.put( callback, mob );
}
}
if (targets.size() == 0) {
GLog.w( Messages.get(this, "no_enemies") );
return;
}
curUser.sprite.zap( curUser.pos );
curUser.busy();
}
}

View File

@ -21,19 +21,7 @@
package com.shatteredpixel.shatteredpixeldungeon.items.armor;
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.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Roots;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Random;
public class MageArmor extends ClassArmor {
@ -41,30 +29,4 @@ public class MageArmor extends ClassArmor {
image = ItemSpriteSheet.ARMOR_MAGE;
}
@Override
public void doSpecial() {
charge -= 35;
updateQuickslot();
for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])) {
if (Dungeon.level.heroFOV[mob.pos]
&& mob.alignment != Char.Alignment.ALLY) {
Buff.affect( mob, Burning.class ).reignite( mob );
Buff.prolong( mob, Roots.class, Roots.DURATION );
mob.damage(Random.NormalIntRange(4, 16 + Dungeon.depth), new Burning());
}
}
curUser.spend( Actor.TICK );
curUser.sprite.operate( curUser.pos );
Invisibility.dispel();
curUser.busy();
curUser.sprite.emitter().start( ElmoParticle.FACTORY, 0.025f, 20 );
Sample.INSTANCE.play( Assets.Sounds.BURNING );
Sample.INSTANCE.play( Assets.Sounds.BURNING );
Sample.INSTANCE.play( Assets.Sounds.BURNING );
}
}

View File

@ -21,25 +21,7 @@
package com.shatteredpixel.shatteredpixeldungeon.items.armor;
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.Blindness;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.PathFinder;
public class RogueArmor extends ClassArmor {
@ -47,53 +29,4 @@ public class RogueArmor extends ClassArmor {
image = ItemSpriteSheet.ARMOR_ROGUE;
}
@Override
public void doSpecial() {
GameScene.selectCell( teleporter );
}
protected CellSelector.Listener teleporter = new CellSelector.Listener() {
@Override
public void onSelect( Integer target ) {
if (target != null) {
PathFinder.buildDistanceMap(curUser.pos, BArray.not(Dungeon.level.solid,null), 8);
if ( PathFinder.distance[target] == Integer.MAX_VALUE ||
!Dungeon.level.heroFOV[target] ||
Actor.findChar( target ) != null) {
GLog.w( Messages.get(RogueArmor.class, "fov") );
return;
}
charge -= 35;
updateQuickslot();
for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])) {
if (Dungeon.level.adjacent(mob.pos, curUser.pos) && mob.alignment != Char.Alignment.ALLY) {
Buff.prolong( mob, Blindness.class, Blindness.DURATION/2f );
if (mob.state == mob.HUNTING) mob.state = mob.WANDERING;
mob.sprite.emitter().burst( Speck.factory( Speck.LIGHT ), 4 );
}
}
Buff.affect(curUser, Invisibility.class, Invisibility.DURATION/2f);
CellEmitter.get( curUser.pos ).burst( Speck.factory( Speck.WOOL ), 10 );
ScrollOfTeleportation.appear( curUser, target );
Sample.INSTANCE.play( Assets.Sounds.PUFF );
Dungeon.level.occupyCell(curUser );
Dungeon.observe();
GameScene.updateFog();
curUser.spendAndNext( Actor.TICK );
}
}
@Override
public String prompt() {
return Messages.get(RogueArmor.class, "prompt");
}
};
}

View File

@ -21,83 +21,12 @@
package com.shatteredpixel.shatteredpixeldungeon.items.armor;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.Camera;
import com.watabou.utils.Callback;
import com.watabou.utils.PathFinder;
public class WarriorArmor extends ClassArmor {
private static int LEAP_TIME = 1;
private static int SHOCK_TIME = 5;
{
image = ItemSpriteSheet.ARMOR_WARRIOR;
}
@Override
public void doSpecial() {
GameScene.selectCell( leaper );
}
protected CellSelector.Listener leaper = new CellSelector.Listener() {
@Override
public void onSelect( Integer target ) {
if (target != null && target != curUser.pos) {
Ballistica route = new Ballistica(curUser.pos, target, Ballistica.PROJECTILE);
int cell = route.collisionPos;
//can't occupy the same cell as another char, so move back one.
if (Actor.findChar( cell ) != null && cell != curUser.pos)
cell = route.path.get(route.dist-1);
charge -= 35;
updateQuickslot();
final int dest = cell;
curUser.busy();
curUser.sprite.jump(curUser.pos, cell, new Callback() {
@Override
public void call() {
curUser.move(dest);
Dungeon.level.occupyCell(curUser);
Dungeon.observe();
GameScene.updateFog();
for (int i = 0; i < PathFinder.NEIGHBOURS8.length; i++) {
Char mob = Actor.findChar(curUser.pos + PathFinder.NEIGHBOURS8[i]);
if (mob != null && mob != curUser && mob.alignment != Char.Alignment.ALLY) {
Buff.prolong(mob, Paralysis.class, SHOCK_TIME);
}
}
CellEmitter.center(dest).burst(Speck.factory(Speck.DUST), 10);
Camera.main.shake(2, 0.5f);
Invisibility.dispel();
curUser.spendAndNext(LEAP_TIME);
}
});
}
}
@Override
public String prompt() {
return Messages.get(WarriorArmor.class, "prompt");
}
};
}