v0.7.0: added 3 early spells, still very wip

This commit is contained in:
Evan Debenham 2018-09-07 00:33:58 -04:00
parent fd4b0cf4ea
commit d06603b95b
10 changed files with 437 additions and 23 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -142,6 +142,9 @@ public class ShatteredPixelDungeon extends Game {
com.watabou.utils.Bundle.addAlias(
com.shatteredpixel.shatteredpixeldungeon.items.potions.elixirs.ElixirOfMight.class,
"com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfMight" );
com.watabou.utils.Bundle.addAlias(
com.shatteredpixel.shatteredpixeldungeon.items.spells.MagicalInfusion.class,
"com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfMagicalInfusion" );
}
@Override

View File

@ -0,0 +1,71 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 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.spells;
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.Paralysis;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.effects.Splash;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Random;
public class AquaBlast extends TargetedSpell {
{
image = ItemSpriteSheet.AQUA_BLAST;
}
@Override
protected void affectTarget(Ballistica bolt, Hero hero) {
int cell = bolt.collisionPos;
//TODO perhaps different color based on depth?
Splash.at(cell, 0x00AAFF, 10);
for (int i : PathFinder.NEIGHBOURS9){
if (i == 0 || Random.Int(2) == 0){
int terr = Dungeon.level.map[cell + i];
if (terr == Terrain.EMPTY || terr == Terrain.GRASS ||
terr == Terrain.EMBERS || terr == Terrain.EMPTY_SP ||
terr == Terrain.HIGH_GRASS || terr == Terrain.EMPTY_DECO) {
Level.set(cell + i, Terrain.WATER);
GameScene.updateMap(cell + i);
}
}
}
Char target = Actor.findChar(cell);
if (target != null && target != hero){
//just enough to skip their current turn
Buff.affect(target, Paralysis.class, 0f);
}
}
}

View File

@ -0,0 +1,71 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 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.spells;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
import com.watabou.noosa.audio.Sample;
public abstract class InventorySpell extends Spell {
protected String inventoryTitle = Messages.get(this, "inv_title");
protected WndBag.Mode mode = WndBag.Mode.ALL;
@Override
protected void onCast(Hero hero) {
curItem = detach( hero.belongings.backpack );
GameScene.selectItem( itemSelector, mode, inventoryTitle );
}
protected abstract void onItemSelected( Item item );
protected static WndBag.Listener itemSelector = new WndBag.Listener() {
@Override
public void onSelect( Item item ) {
//FIXME this safety check shouldn't be necessary
//it would be better to eliminate the curItem static variable.
if (!(curItem instanceof InventorySpell)){
return;
}
if (item != null) {
((InventorySpell)curItem).onItemSelected( item );
curUser.spend( 1f );
curUser.busy();
(curUser.sprite).operate( curUser.pos );
Sample.INSTANCE.play( Assets.SND_READ );
Invisibility.dispel();
} else {
curItem.collect( curUser.belongings.backpack );
}
}
};
}

View File

@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.scrolls;
package com.shatteredpixel.shatteredpixeldungeon.items.spells;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.effects.Enchanting;
@ -32,13 +32,11 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
public class ScrollOfMagicalInfusion extends InventoryScroll {
//TODO transition to a spell
public class MagicalInfusion extends InventorySpell {
{
mode = WndBag.Mode.ENCHANTABLE;
image = ItemSpriteSheet.SCROLL_ISAZ;
image = ItemSpriteSheet.MAGIC_INFUSE;
}
@Override
@ -57,18 +55,8 @@ public class ScrollOfMagicalInfusion extends InventoryScroll {
Enchanting.show(curUser, item);
}
@Override
public void empoweredRead() {
//does nothing for now, this should never happen.
}
@Override
public boolean isKnown() {
return true;
}
@Override
public int price() {
return isKnown() ? 100 * quantity : super.price();
return 100 * quantity;
}
}

View File

@ -0,0 +1,80 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 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.spells;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
public class PhaseShift extends TargetedSpell {
{
image = ItemSpriteSheet.PHASE_SHIFT;
}
@Override
protected void affectTarget(Ballistica bolt, Hero hero) {
final Char ch = Actor.findChar(bolt.collisionPos);
if (ch == hero){
ScrollOfTeleportation.teleportHero(curUser);
} else if (ch != null) {
int count = 10;
int pos;
do {
pos = Dungeon.level.randomRespawnCell();
if (count-- <= 0) {
break;
}
} while (pos == -1);
if (pos == -1 || Dungeon.bossLevel()) {
GLog.w( Messages.get(ScrollOfTeleportation.class, "no_tele") );
} else if (ch.properties().contains(Char.Property.IMMOVABLE)) {
//TODO move text
GLog.w( Messages.get(LloydsBeacon.class, "tele_fail") );
} else {
ch.pos = pos;
if (ch instanceof Mob && ((Mob) ch).state == ((Mob) ch).HUNTING){
((Mob) ch).state = ((Mob) ch).WANDERING;
}
ch.sprite.place(ch.pos);
ch.sprite.visible = Dungeon.level.heroFOV[pos];
}
}
}
}

View File

@ -0,0 +1,73 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 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.spells;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicImmune;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import java.util.ArrayList;
public abstract class Spell extends Item {
public static final String AC_CAST = "CAST";
{
stackable = true;
defaultAction = AC_CAST;
}
@Override
public ArrayList<String> actions(Hero hero ) {
ArrayList<String> actions = super.actions( hero );
actions.add( AC_CAST );
return actions;
}
@Override
public void execute( final Hero hero, String action ) {
super.execute( hero, action );
if (action.equals( AC_CAST )) {
if (curUser.buff(MagicImmune.class) != null){
GLog.w( Messages.get(this, "no_magic") );
return;
}
onCast( hero );
}
}
@Override
public boolean isIdentified() {
return true;
}
protected abstract void onCast(Hero hero );
}

View File

@ -0,0 +1,106 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 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.spells;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
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.ui.QuickSlotButton;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Callback;
public abstract class TargetedSpell extends Spell {
protected int collisionProperties = Ballistica.PROJECTILE;
@Override
protected void onCast(Hero hero) {
GameScene.selectCell(targeter);
}
protected abstract void affectTarget( Ballistica bolt, Hero hero );
protected void fx( Ballistica bolt, Callback callback ) {
MagicMissile.boltFromChar( curUser.sprite.parent,
MagicMissile.MAGIC_MISSILE,
curUser.sprite,
bolt.collisionPos,
callback);
Sample.INSTANCE.play( Assets.SND_ZAP );
}
private static CellSelector.Listener targeter = new CellSelector.Listener(){
@Override
public void onSelect( Integer target ) {
if (target != null) {
//FIXME this safety check shouldn't be necessary
//it would be better to eliminate the curItem static variable.
final TargetedSpell curSpell;
if (curItem instanceof TargetedSpell) {
curSpell = (TargetedSpell)curItem;
} else {
return;
}
final Ballistica shot = new Ballistica( curUser.pos, target, curSpell.collisionProperties);
int cell = shot.collisionPos;
curUser.sprite.zap(cell);
//attempts to target the cell aimed at if something is there, otherwise targets the collision pos.
if (Actor.findChar(target) != null)
QuickSlotButton.target(Actor.findChar(target));
else
QuickSlotButton.target(Actor.findChar(cell));
curUser.busy();
Invisibility.dispel();
curSpell.fx(shot, new Callback() {
public void call() {
curSpell.affectTarget(shot, curUser);
curSpell.detach( curUser.belongings.backpack );
curSpell.updateQuickslot();
curUser.spendAndNext( 1f );
}
});
}
}
@Override
public String prompt() {
return Messages.get(TargetedSpell.class, "prompt");
}
};
}

View File

@ -553,12 +553,21 @@ public class ItemSpriteSheet {
assignItemRect(BREW_FRIGID, 10, 14);
assignItemRect(BREW_FROSTFIRE, 10, 14);
assignItemRect(BREW_CAUSTIC, 10, 14);
assignItemRect(BREW_CAUSTIC, 10, 14);
assignItemRect(BREW_INFERNAL, 10, 14);
assignItemRect(BREW_BLIZZARD, 10, 14);
assignItemRect(BREW_SHOCKING, 10, 14);
}
//16 free slots
private static final int SPELLS = xy(1, 27); //16 slots
public static final int PHASE_SHIFT = SPELLS+0;
public static final int AQUA_BLAST = SPELLS+1;
public static final int MAGIC_INFUSE = SPELLS+2;
static{
assignItemRect(PHASE_SHIFT, 12, 11);
assignItemRect(AQUA_BLAST, 11, 11);
assignItemRect(MAGIC_INFUSE, 10, 15);
}
private static final int FOOD = xy(1, 28); //16 slots
public static final int MEAT = FOOD+0;

View File

@ -792,11 +792,6 @@ items.scrolls.scrolloflullaby.name=scroll of lullaby
items.scrolls.scrolloflullaby.sooth=The scroll utters a soothing melody. You feel very sleepy.
items.scrolls.scrolloflullaby.desc=Reading this scroll emits a soothing melody will lull all who hear it into a deep magical sleep.
items.scrolls.scrollofmagicalinfusion.name=scroll of magical infusion
items.scrolls.scrollofmagicalinfusion.inv_title=Infuse an item
items.scrolls.scrollofmagicalinfusion.infuse=Your %s is infused with arcane energy!
items.scrolls.scrollofmagicalinfusion.desc=This scroll will infuse a weapon or armor with powerful magical energy.\n\nIn addition to being upgraded, A weapon will gain a magical enchantment, or armor will be imbued with a magical glyph.\n\nIf the item already has an enchantment or glyph, it will never be erased by this scroll.
items.scrolls.scrollofmagicmapping.name=scroll of magic mapping
items.scrolls.scrollofmagicmapping.layout=You are now aware of the level layout.
items.scrolls.scrollofmagicmapping.desc=When this scroll is read, an image of crystal clarity will be etched into your memory, alerting you to the precise layout of the level and revealing all hidden secrets. The locations of items and creatures will remain unknown.
@ -909,6 +904,24 @@ items.scrolls.exotic.scrollofpsionicblast.desc=This scroll contains incredible d
###spells
items.spells.aquablast.name=aqua blast
items.spells.aquablast.desc=WIP
items.spells.spell.ac_cast=CAST
items.spells.magicalinfusion.name=magical infusion
items.spells.magicalinfusion.inv_title=Infuse an item
items.spells.magicalinfusion.infuse=Your %s is infused with arcane energy!
items.spells.magicalinfusion.desc=This spell will infuse a weapon or armor with powerful magical energy.\n\nIn addition to being upgraded, A weapon will gain a magical enchantment, or armor will be imbued with a magical glyph.\n\nIf the item already has an enchantment or glyph, it will not be erased by the upgrade.
items.spells.phaseshift.name=phase shift
items.spells.phaseshift.desc=WIP
items.spells.targetedspell.prompt=Choose a target
items.spells.targetedspell.inv_title=Infuse an item
###runestones
items.stones.inventorystone.ac_use=USE