Merging Source v1.7.2: item changes

This commit is contained in:
Evan Debenham 2014-10-21 00:38:15 -04:00
parent 4a49763309
commit 13afc9df8d
32 changed files with 523 additions and 269 deletions

View File

@ -23,7 +23,6 @@ import java.util.ArrayList;
import com.watabou.noosa.Game;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.ResultDescriptions;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.scenes.AmuletScene;
@ -66,7 +65,6 @@ public class Amulet extends Item {
if (!Statistics.amuletObtained) {
Statistics.amuletObtained = true;
Dungeon.win( ResultDescriptions.WIN );
Badges.validateVictory();
showAmuletScene( true );

View File

@ -17,6 +17,8 @@
*/
package com.shatteredpixel.shatteredpixeldungeon.items;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
@ -24,45 +26,73 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle
public abstract class EquipableItem extends Item {
public static final String AC_EQUIP = "EQUIP";
public static final String AC_UNEQUIP = "UNEQUIP";
@Override
public void execute( Hero hero, String action ) {
if (action.equals( AC_EQUIP )) {
doEquip( hero );
} else if (action.equals( AC_UNEQUIP )) {
doUnequip( hero, true );
} else {
super.execute( hero, action );
}
}
@Override
public void doDrop( Hero hero ) {
if (!isEquipped( hero ) || doUnequip( hero, false )) {
super.doDrop( hero );
}
}
@Override
public void cast( final Hero user, int dst ) {
if (isEquipped( user )) {
if (quantity == 1 && !this.doUnequip( user, false )) {
return;
}
}
super.cast( user, dst );
}
protected static void equipCursed( Hero hero ) {
hero.sprite.emitter().burst( ShadowParticle.CURSE, 6 );
Sample.INSTANCE.play( Assets.SND_CURSED );
}
public abstract boolean doEquip( Hero hero );
public abstract boolean doUnequip( Hero hero, boolean collect );
private static final String TXT_UNEQUIP_CURSED = "You can't remove cursed %s!";
public static final String AC_EQUIP = "EQUIP";
public static final String AC_UNEQUIP = "UNEQUIP";
@Override
public void execute( Hero hero, String action ) {
if (action.equals( AC_EQUIP )) {
doEquip( hero );
} else if (action.equals( AC_UNEQUIP )) {
doUnequip( hero, true );
} else {
super.execute( hero, action );
}
}
@Override
public void doDrop( Hero hero ) {
if (!isEquipped( hero ) || doUnequip( hero, false, false )) {
super.doDrop( hero );
}
}
@Override
public void cast( final Hero user, int dst ) {
if (isEquipped( user )) {
if (quantity == 1 && !this.doUnequip( user, false, false )) {
return;
}
}
super.cast( user, dst );
}
protected static void equipCursed( Hero hero ) {
hero.sprite.emitter().burst( ShadowParticle.CURSE, 6 );
Sample.INSTANCE.play( Assets.SND_CURSED );
}
protected float time2equip( Hero hero ) {
return 1;
}
public abstract boolean doEquip( Hero hero );
public boolean doUnequip( Hero hero, boolean collect, boolean single ) {
if (cursed) {
GLog.w(TXT_UNEQUIP_CURSED, name());
return false;
}
if (single) {
hero.spendAndNext( time2equip( hero ) );
} else {
hero.spend( time2equip( hero ) );
}
if (collect && !collect( hero.belongings.backpack )) {
Dungeon.level.drop( this, hero.pos );
}
return true;
}
public boolean doUnequip( Hero hero, boolean collect ) {
return doUnequip( hero, collect, true );
}
}

View File

@ -187,7 +187,7 @@ public class Item implements Bundlable {
return collect( Dungeon.hero.belongings.backpack );
}
public Item detach( Bag container ) {
public final Item detach( Bag container ) {
if (quantity <= 0) {
@ -203,28 +203,30 @@ public class Item implements Bundlable {
quantity--;
updateQuickslot();
try {
return getClass().newInstance();
try {
Item detached = getClass().newInstance();
detached.onDetach( );
return detached;
} catch (Exception e) {
return null;
}
}
}
public Item detachAll( Bag container ) {
for (Item item : container.items) {
if (item == this) {
container.items.remove( this );
QuickSlot.refresh();
return this;
} else if (item instanceof Bag) {
Bag bag = (Bag)item;
if (bag.contains( this )) {
detachAll( bag );
return this;
}
}
}
public final Item detachAll( Bag container ) {
for (Item item : container.items) {
if (item == this) {
container.items.remove( this );
item.onDetach( );
QuickSlot.refresh();
return this;
} else if (item instanceof Bag) {
Bag bag = (Bag)item;
if (bag.contains( this )) {
return detachAll( bag );
}
}
}
return this;
}
@ -232,6 +234,8 @@ public class Item implements Bundlable {
public boolean isSimilar( Item item ) {
return getClass() == item.getClass();
}
protected void onDetach(){}
public Item upgrade() {
@ -428,7 +432,7 @@ public class Item implements Bundlable {
float delay = TIME_TO_THROW;
if (this instanceof MissileWeapon) {
// Refactoring needed!
// FIXME
delay *= ((MissileWeapon)this).speedFactor( user );
if (enemy != null && enemy.buff( SnipersMark.class ) != null) {
delay *= 0.5f;

View File

@ -19,7 +19,6 @@ package com.shatteredpixel.shatteredpixeldungeon.items;
import java.util.ArrayList;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlot;
@ -29,7 +28,6 @@ import com.watabou.utils.Random;
public class KindOfWeapon extends EquipableItem {
private static final String TXT_EQUIP_CURSED = "you wince as your grip involuntarily tightens around your %s";
private static final String TXT_UNEQUIP_CURSED = "you can't remove cursed %s!";
protected static final float TIME_TO_EQUIP = 1f;
@ -75,24 +73,20 @@ public class KindOfWeapon extends EquipableItem {
return false;
}
}
@Override
public boolean doUnequip( Hero hero, boolean collect ) {
if (cursed) {
GLog.w( TXT_UNEQUIP_CURSED, name() );
return false;
}
hero.belongings.weapon = null;
hero.spendAndNext( TIME_TO_EQUIP );
if (collect && !collect( hero.belongings.backpack )) {
Dungeon.level.drop( this, hero.pos );
}
return true;
}
@Override
public boolean doUnequip( Hero hero, boolean collect, boolean single ) {
if (super.doUnequip( hero, collect, single )) {
hero.belongings.weapon = null;
return true;
} else {
return false;
}
}
public void activate( Hero hero ) {
}

View File

@ -0,0 +1,195 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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;
import java.util.ArrayList;
import com.watabou.noosa.BitmapTextMultiline;
import com.watabou.noosa.audio.Sample;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.shatteredpixel.shatteredpixeldungeon.utils.Utils;
import com.shatteredpixel.shatteredpixeldungeon.windows.IconTitle;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
public class Weightstone extends Item {
private static final String TXT_SELECT_WEAPON = "Select a weapon to balance";
private static final String TXT_FAST = "you balanced your %s to make it faster";
private static final String TXT_ACCURATE = "you balanced your %s to make it more accurate";
private static final float TIME_TO_APPLY = 2;
private static final String AC_APPLY = "APPLY";
{
name = "weightstone";
image = ItemSpriteSheet.WEIGHT;
stackable = true;
}
@Override
public ArrayList<String> actions( Hero hero ) {
ArrayList<String> actions = super.actions( hero );
actions.add( AC_APPLY );
return actions;
}
@Override
public void execute( Hero hero, String action ) {
if (action == AC_APPLY) {
curUser = hero;
GameScene.selectItem( itemSelector, WndBag.Mode.WEAPON, TXT_SELECT_WEAPON );
} else {
super.execute( hero, action );
}
}
@Override
public boolean isUpgradable() {
return false;
}
@Override
public boolean isIdentified() {
return true;
}
private void apply( Weapon weapon, boolean forSpeed ) {
detach( curUser.belongings.backpack );
if (forSpeed) {
weapon.imbue = Weapon.Imbue.SPEED;
GLog.p( TXT_FAST, weapon.name() );
} else {
weapon.imbue = Weapon.Imbue.ACCURACY;
GLog.p( TXT_ACCURATE, weapon.name() );
}
curUser.sprite.operate( curUser.pos );
Sample.INSTANCE.play( Assets.SND_MISS );
curUser.spend( TIME_TO_APPLY );
curUser.busy();
}
@Override
public int price() {
return 40 * quantity;
}
@Override
public String info() {
return
"Using a weightstone, you can balance your melee weapon to increase its speed or accuracy.";
}
private final WndBag.Listener itemSelector = new WndBag.Listener() {
@Override
public void onSelect( Item item ) {
if (item != null) {
GameScene.show( new WndBalance( (Weapon)item ) );
}
}
};
public class WndBalance extends Window {
private static final String TXT_CHOICE = "How would you like to balance your %s?";
private static final String TXT_SPEED = "For speed";
private static final String TXT_ACCURACY = "For accuracy";
private static final String TXT_CANCEL = "Never mind";
private static final int WIDTH = 120;
private static final int MARGIN = 2;
private static final int BUTTON_WIDTH = WIDTH - MARGIN * 2;
private static final int BUTTON_HEIGHT = 20;
public WndBalance( final Weapon weapon ) {
super();
IconTitle titlebar = new IconTitle( weapon );
titlebar.setRect( 0, 0, WIDTH, 0 );
add( titlebar );
BitmapTextMultiline tfMesage = PixelScene.createMultiline( Utils.format( TXT_CHOICE, weapon.name() ), 8 );
tfMesage.maxWidth = WIDTH - MARGIN * 2;
tfMesage.measure();
tfMesage.x = MARGIN;
tfMesage.y = titlebar.bottom() + MARGIN;
add( tfMesage );
float pos = tfMesage.y + tfMesage.height();
if (weapon.imbue != Weapon.Imbue.SPEED) {
RedButton btnSpeed = new RedButton( TXT_SPEED ) {
@Override
protected void onClick() {
hide();
Weightstone.this.apply( weapon, true );
}
};
btnSpeed.setRect( MARGIN, pos + MARGIN, BUTTON_WIDTH, BUTTON_HEIGHT );
add( btnSpeed );
pos = btnSpeed.bottom();
}
if (weapon.imbue != Weapon.Imbue.ACCURACY) {
RedButton btnAccuracy = new RedButton( TXT_ACCURACY ) {
@Override
protected void onClick() {
hide();
Weightstone.this.apply( weapon, false );
}
};
btnAccuracy.setRect( MARGIN, pos + MARGIN, BUTTON_WIDTH, BUTTON_HEIGHT );
add( btnAccuracy );
pos = btnAccuracy.bottom();
}
RedButton btnCancel = new RedButton( TXT_CANCEL ) {
@Override
protected void onClick() {
hide();
}
};
btnCancel.setRect( MARGIN, pos + MARGIN, BUTTON_WIDTH, BUTTON_HEIGHT );
add( btnCancel );
resize( WIDTH, (int)btnCancel.bottom() + MARGIN );
}
protected void onSelect( int index ) {};
}
}

View File

@ -37,7 +37,6 @@ import com.watabou.utils.Random;
public class Armor extends EquipableItem {
private static final String TXT_EQUIP_CURSED = "your %s constricts around you painfully";
private static final String TXT_UNEQUIP_CURSED = "You can't remove cursed %s!";
private static final String TXT_IDENTIFY = "you are now familiar enough with your %s to identify it. It is %s.";
@ -89,7 +88,7 @@ public class Armor extends EquipableItem {
detach( hero.belongings.backpack );
if (hero.belongings.armor == null || hero.belongings.armor.doUnequip( hero, true )) {
if (hero.belongings.armor == null || hero.belongings.armor.doUnequip( hero, true, false )) {
hero.belongings.armor = this;
@ -100,8 +99,8 @@ public class Armor extends EquipableItem {
}
((HeroSprite)hero.sprite).updateArmor();
hero.spendAndNext( 2 * hero.speed() );
hero.spendAndNext( 2 * time2equip( hero ) );
return true;
} else {
@ -111,29 +110,27 @@ public class Armor extends EquipableItem {
}
}
@Override
public boolean doUnequip( Hero hero, boolean collect ) {
if (cursed) {
GLog.w( TXT_UNEQUIP_CURSED, name() );
return false;
} else {
hero.belongings.armor = null;
hero.spendAndNext( hero.speed() );
((HeroSprite)hero.sprite).updateArmor();
if (collect && !collect( hero.belongings.backpack )) {
Dungeon.level.drop( this, hero.pos );
}
return true;
}
}
@Override
protected float time2equip( Hero hero ) {
return hero.speed();
}
@Override
public boolean doUnequip( Hero hero, boolean collect, boolean single ) {
if (super.doUnequip( hero, collect, single )) {
hero.belongings.armor = null;
((HeroSprite)hero.sprite).updateArmor();
return true;
} else {
return false;
}
}
@Override
public boolean isEquipped( Hero hero ) {
@ -305,11 +302,19 @@ public class Armor extends EquipableItem {
}
return price;
}
public Armor inscribe( Glyph glyph ) {
this.glyph = glyph;
return this;
}
public Armor inscribe( Glyph glyph ) {
if (glyph != null && this.glyph == null) {
DR += tier;
} else if (glyph == null && this.glyph != null) {
DR -= tier;
}
this.glyph = glyph;
return this;
}
public boolean isInscribed() {
return glyph != null;

View File

@ -85,7 +85,7 @@ abstract public class ClassArmor extends Armor {
@Override
public ArrayList<String> actions( Hero hero ) {
ArrayList<String> actions = super.actions( hero );
if (hero.HP >= 2 && isEquipped( hero )) {
if (hero.HP >= 3 && isEquipped( hero )) {
actions.add( special() );
}
return actions;
@ -95,7 +95,7 @@ abstract public class ClassArmor extends Armor {
public void execute( Hero hero, String action ) {
if (action == special()) {
if (hero.HP < 2) {
if (hero.HP < 3) {
GLog.w( TXT_LOW_HEALTH );
} else if (!isEquipped( hero )) {
GLog.w( TXT_NOT_EQUIPPED );

View File

@ -81,7 +81,7 @@ public class HuntressArmor extends ClassArmor {
return;
}
curUser.HP /= 2;
curUser.HP -= (curUser.HP / 3);
curUser.sprite.zap( curUser.pos );
curUser.busy();

View File

@ -64,8 +64,8 @@ public class MageArmor extends ClassArmor {
Buff.prolong( mob, Roots.class, 3 );
}
}
curUser.HP /= 2;
curUser.HP -= (curUser.HP / 3);
curUser.spend( Actor.TICK );
curUser.sprite.operate( curUser.pos );

View File

@ -26,7 +26,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob.State;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlink;
@ -88,13 +87,13 @@ public class RogueArmor extends ClassArmor {
GLog.w( TXT_FOV );
return;
}
curUser.HP /= 2;
curUser.HP -= (curUser.HP / 3);
for (Mob mob : Dungeon.level.mobs) {
if (Level.fieldOfView[mob.pos]) {
Buff.prolong( mob, Blindness.class, 2 );
mob.state = State.WANDERING;
mob.state = mob.WANDERING;
mob.sprite.emitter().burst( Speck.factory( Speck.LIGHT ), 4 );
}
}

View File

@ -17,8 +17,8 @@
*/
package com.shatteredpixel.shatteredpixeldungeon.items.armor;
import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite;
import com.watabou.noosa.Camera;
import com.watabou.noosa.tweeners.PosTweener;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
@ -37,8 +37,7 @@ import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.utils.PointF;
import com.watabou.utils.Callback;
public class WarriorArmor extends ClassArmor {
private static int LEAP_TIME = 1;
@ -90,34 +89,36 @@ public class WarriorArmor extends ClassArmor {
if (Actor.findChar( cell ) != null && cell != curUser.pos) {
cell = Ballistica.trace[Ballistica.distance - 2];
}
curUser.HP /= 2;
curUser.HP -= (curUser.HP / 3);
if (curUser.subClass == HeroSubClass.BERSERKER && curUser.HP <= curUser.HT * Fury.LEVEL) {
Buff.affect( curUser, Fury.class );
}
Invisibility.dispel();
curUser.move( cell );
curUser.sprite.place( cell );
Dungeon.level.press( target, curUser );
Dungeon.observe();
for (int i=0; i < Level.NEIGHBOURS8.length; i++) {
Char mob = Actor.findChar( curUser.pos + Level.NEIGHBOURS8[i] );
if (mob != null && mob != curUser) {
Buff.prolong( mob, Paralysis.class, SHOCK_TIME );
}
}
PointF pos = curUser.sprite.point();
Camera.main.target = null;
curUser.sprite.y -= 16;
curUser.sprite.parent.add( new PosTweener( curUser.sprite, pos, 0.1f ) );
CellEmitter.center( cell ).burst( Speck.factory( Speck.DUST ), 10 );
curUser.spendAndNext( LEAP_TIME );
final int dest = cell;
curUser.busy();
((HeroSprite)curUser.sprite).jump(curUser.pos, cell, new Callback() {
@Override
public void call() {
curUser.move(dest);
Dungeon.level.press(dest, curUser);
Dungeon.observe();
for (int i = 0; i < Level.NEIGHBOURS8.length; i++) {
Char mob = Actor.findChar(curUser.pos + Level.NEIGHBOURS8[i]);
if (mob != null && mob != curUser) {
Buff.prolong(mob, Paralysis.class, SHOCK_TIME);
}
}
CellEmitter.center(dest).burst(Speck.factory(Speck.DUST), 10);
Camera.main.shake(2, 0.5f);
curUser.spendAndNext(LEAP_TIME);
}
});
}
}

View File

@ -47,7 +47,7 @@ public class Bounce extends Glyph {
Actor.addDelayed( new Pushing( attacker, attacker.pos, newPos ), -1 );
attacker.pos = newPos;
// <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> :(
// FIXME
if (attacker instanceof Mob) {
Dungeon.level.mobPress( (Mob)attacker );
} else {

View File

@ -125,7 +125,7 @@ public class Viscosity extends Glyph {
target.damage( 1, this );
if (target == Dungeon.hero && !target.isAlive()) {
// Refactoring needed!
// FIXME
Glyph glyph = new Viscosity();
Dungeon.fail( Utils.format( ResultDescriptions.GLYPH, glyph.name(), Dungeon.depth ) );
GLog.n( "%s killed you...", glyph.name() );

View File

@ -97,7 +97,8 @@ public class Artifact extends KindofMisc {
}
@Override
public boolean doUnequip( Hero hero, boolean collect ) {
public boolean doUnequip( Hero hero, boolean collect, boolean single ) {
if (super.doUnequip( hero, collect, single )) {
if (hero.belongings.misc1 == this) {
hero.belongings.misc1 = null;
@ -108,13 +109,13 @@ public class Artifact extends KindofMisc {
passiveBuff.detach();
passiveBuff = null;
hero.spendAndNext( TIME_TO_EQUIP );
if (collect && !collect( hero.belongings.backpack )) {
Dungeon.level.drop( this, hero.pos );
}
return true;
} else {
return false;
}
}
@Override

View File

@ -84,12 +84,11 @@ public class Bag extends Item implements Iterable<Item> {
return false;
}
}
@Override
public Item detach( Bag container ) {
owner = null;
return super.detach( container );
}
@Override
public void onDetach( ) {
this.owner = null;
}
@Override
public boolean isUpgradable() {

View File

@ -48,16 +48,13 @@ public class WandHolster extends Bag {
return false;
}
}
@Override
public Item detach( Bag container ) {
for (Item item : items) {
((Wand)item).stopCharging();
}
return super.detach( container );
}
public void onDetach( ) {
for (Item item : items) {
((Wand)item).stopCharging();
}
}
@Override
public int price() {

View File

@ -57,7 +57,7 @@ public class MysteryMeat extends Food {
break;
case 2:
GLog.w( "You are not feeling well." );
Buff.affect( hero, Poison.class ).set( Poison.durationFactor( hero ) * hero.HT / 2 / Poison.DOT );
Buff.affect( hero, Poison.class ).set( Poison.durationFactor( hero ) * hero.HT / 5 );
break;
case 3:
GLog.w( "You are stuffed." );

View File

@ -27,7 +27,7 @@ public class IronKey extends Key {
private static final String TXT_FROM_DEPTH = "iron key from depth %d";
public static int curDepthQunatity = 0;
public static int curDepthQuantity = 0;
{
name = "iron key";
@ -51,15 +51,13 @@ public class IronKey extends Key {
}
return result;
}
@Override
public Item detach( Bag bag ) {
Item result = super.detach( bag );
if (result != null && depth == Dungeon.depth) {
Dungeon.hero.belongings.countIronKeys();
}
return result;
}
@Override
public void onDetach( ) {
if (depth == Dungeon.depth) {
Dungeon.hero.belongings.countIronKeys();
}
}
@Override
public String toString() {

View File

@ -36,13 +36,6 @@ public class Key extends Item {
return item.getClass() == getClass() && ((Key)item).depth == depth;
}
@Override
public Item detach( Bag container ) {
Key key = (Key)super.detach( container );
key.depth = depth;
return key;
}
private static final String DEPTH = "depth";
@Override
@ -66,4 +59,10 @@ public class Key extends Item {
public boolean isIdentified() {
return true;
}
@Override
public String status() {
return depth + "*";
}
}

View File

@ -145,32 +145,28 @@ public class Ring extends KindofMisc {
buff = buff();
buff.attachTo( ch );
}
@Override
public boolean doUnequip( Hero hero, boolean collect ) {
if (cursed) {
GLog.w( "You can't remove cursed " + name() + "!" );
return false;
}
if (hero.belongings.misc1 == this) {
hero.belongings.misc1 = null;
} else {
hero.belongings.misc2 = null;
}
buff.detach();
buff = null;
hero.spendAndNext( TIME_TO_EQUIP );
if (collect && !collect( hero.belongings.backpack )) {
Dungeon.level.drop( this, hero.pos );
}
return true;
}
@Override
public boolean doUnequip( Hero hero, boolean collect, boolean single ) {
if (super.doUnequip( hero, collect, single )) {
if (hero.belongings.misc1 == this) {
hero.belongings.misc1 = null;
} else {
hero.belongings.misc2 = null;
}
hero.remove( buff );
buff = null;
return true;
} else {
return false;
}
}
@Override
public boolean isEquipped( Hero hero ) {

View File

@ -147,8 +147,8 @@ public abstract class Wand extends KindOfWeapon {
@Override
public boolean doUnequip( Hero hero, boolean collect ) {
charger.detach();
return super.doUnequip(hero, collect);
onDetach();
return super.doUnequip( hero, collect );
}
@Override
@ -188,17 +188,10 @@ public abstract class Wand extends KindOfWeapon {
public void charge( Char owner ) {
(charger = new Charger()).attachTo( owner );
}
@Override
public Item detach( Bag container ) {
stopCharging();
return super.detach( container );
}
@Override
public Item detachAll( Bag container) {
public void onDetach( ) {
stopCharging();
return super.detachAll( container );
}
public void stopCharging() {

View File

@ -17,6 +17,8 @@
*/
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
import com.watabou.noosa.audio.Sample;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
@ -37,8 +39,12 @@ public class WandOfAmok extends Wand {
protected void onZap( int cell ) {
Char ch = Actor.findChar( cell );
if (ch != null) {
Buff.affect( ch, Amok.class, 3f + level() );
if (ch == Dungeon.hero) {
Buff.affect( ch, Vertigo.class, Vertigo.duration(ch) );
} else {
Buff.affect( ch, Amok.class, 3f + level() );
}
} else {

View File

@ -17,12 +17,12 @@
*/
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.NPC;
import com.watabou.noosa.audio.Sample;
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.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
@ -104,7 +104,7 @@ public class WandOfFlock extends Wand {
"A flick of this wand summons a flock of magic sheep, creating temporary impenetrable obstacle.";
}
public static class Sheep extends Mob.NPC {
public static class Sheep extends NPC {
private static final String[] QUOTES = {"Baa!", "Baa?", "Baa.", "Baa..."};

View File

@ -48,7 +48,6 @@ public class WandOfLightning extends Wand {
@Override
protected void onZap( int cell ) {
// The actual effect is processed in "fx" method
if (!curUser.isAlive()) {
Dungeon.fail( Utils.format( ResultDescriptions.ITEM, name, Dungeon.depth ) );

View File

@ -38,7 +38,7 @@ public class WandOfPoison extends Wand {
Char ch = Actor.findChar( cell );
if (ch != null) {
Buff.affect( ch, Poison.class ).set( Poison.durationFactor( ch ) * (1 + 2 * (float)Math.pow( 1.5, level() )) );
Buff.affect( ch, Poison.class ).set( Poison.durationFactor( ch ) * (5 + level()) );
} else {

View File

@ -80,7 +80,7 @@ public class WandOfTelekinesis extends Wand {
ch.pos = next;
Actor.freeCell( next );
// Refactoring needed!
// FIXME
if (ch instanceof Mob) {
Dungeon.level.mobPress( (Mob)ch );
} else {

View File

@ -17,7 +17,7 @@
*/
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.NPC;
import com.watabou.noosa.audio.Sample;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
@ -44,7 +44,7 @@ public class WandOfTeleportation extends Wand {
setKnown();
ScrollOfTeleportation.teleportHero( curUser );
} else if (ch != null && !(ch instanceof Mob.NPC)) {
} else if (ch != null && !(ch instanceof NPC)) {
int count = 10;
int pos;

View File

@ -46,7 +46,12 @@ public class Weapon extends KindOfWeapon {
public int STR = 10;
public float ACU = 1; // Accuracy modifier
public float DLY = 1f; // Speed modifier
public enum Imbue {
NONE, SPEED, ACCURACY
}
public Imbue imbue = Imbue.NONE;
private int hitsToKnow = 20;
protected Enchantment enchantment;
@ -68,17 +73,20 @@ public class Weapon extends KindOfWeapon {
}
private static final String ENCHANTMENT = "enchantment";
private static final String IMBUE = "imbue";
@Override
public void storeInBundle( Bundle bundle ) {
super.storeInBundle( bundle );
bundle.put( ENCHANTMENT, enchantment );
bundle.put( IMBUE, imbue );
}
@Override
public void restoreFromBundle( Bundle bundle ) {
super.restoreFromBundle( bundle );
enchantment = (Enchantment)bundle.get( ENCHANTMENT );
imbue = bundle.getEnum( IMBUE, Imbue.class );
}
@Override
@ -104,8 +112,10 @@ public class Weapon extends KindOfWeapon {
}
ACU *= (float)(Math.pow(1.1, bonus));
}
return encumbrance > 0 ? (float)((ACU) / Math.pow( 1.5, encumbrance )) : ACU;
return
(encumbrance > 0 ? (float)(ACU / Math.pow( 1.5, encumbrance )) : ACU) *
(imbue == Imbue.ACCURACY ? 1.5f : 1.0f);
}
@Override
@ -122,8 +132,10 @@ public class Weapon extends KindOfWeapon {
}
float DLY = (float)(0.25 + (this.DLY - 0.25)*Math.pow(0.8, bonus));
return encumrance > 0 ? (float)(DLY * Math.pow( 1.2, encumrance )) : DLY;
return
(encumrance > 0 ? (float)(DLY * Math.pow( 1.2, encumrance )) : DLY) *
(imbue == Imbue.SPEED ? 0.6f : 1.0f);
}
@Override
@ -131,7 +143,7 @@ public class Weapon extends KindOfWeapon {
int damage = super.damageRoll( hero );
if (hero.usingRanged == (hero.heroClass == HeroClass.HUNTRESS)) {
if ((hero.rangedWeapon != null) == (hero.heroClass == HeroClass.HUNTRESS)) {
int exStr = hero.STR() - STR;
if (exStr > 0) {
damage += Random.IntRange( 0, exStr );

View File

@ -17,9 +17,11 @@
*/
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite.Glowing;
@ -39,9 +41,12 @@ public class Horror extends Weapon.Enchantment {
int level = Math.max( 0, weapon.level );
if (Random.Int( level + 5 ) >= 4) {
Terror terror = Buff.affect( defender, Terror.class, Terror.DURATION );
terror.source = attacker;
if (defender == Dungeon.hero) {
Buff.affect( defender, Vertigo.class, Vertigo.duration(defender) );
} else {
Buff.affect( defender, Terror.class, Terror.DURATION ).source = attacker;
}
return true;
} else {

View File

@ -114,7 +114,16 @@ public class MeleeWeapon extends Weapon {
info.append( " weapon. ");
} else if (ACU != 1f) {
info.append( "This is a rather " + (ACU > 1f ? "accurate" : "inaccurate") + " weapon. " );
}
}
switch (imbue) {
case SPEED:
info.append( "It was balanced to make it faster. " );
break;
case ACCURACY:
info.append( "It was balanced to make it more accurate. " );
break;
case NONE:
}
if (enchantment != null) {
info.append( "It is enchanted." );

View File

@ -76,27 +76,41 @@ public class Boomerang extends MissileWeapon {
return super.enchant( ench );
}
@Override
public void proc( Char attacker, Char defender, int damage ) {
super.proc( attacker, defender, damage );
if (attacker instanceof Hero && ((Hero)attacker).usingRanged) {
circleBack( defender.pos, (Hero)attacker );
}
}
@Override
protected void miss( int cell ) {
circleBack( cell, curUser );
}
private void circleBack( int from, Hero owner ) {
if (!collect( curUser.belongings.backpack )) {
Dungeon.level.drop( this, owner.pos ).sprite.drop();
}
((MissileSprite)curUser.sprite.parent.recycle( MissileSprite.class )).
reset( from, curUser.pos, curItem, null );
}
@Override
public void proc( Char attacker, Char defender, int damage ) {
super.proc( attacker, defender, damage );
if (attacker instanceof Hero && ((Hero)attacker).rangedWeapon == this) {
circleBack( defender.pos, (Hero)attacker );
}
}
@Override
protected void miss( int cell ) {
circleBack( cell, curUser );
}
private void circleBack( int from, Hero owner ) {
((MissileSprite)curUser.sprite.parent.recycle( MissileSprite.class )).
reset( from, curUser.pos, curItem, null );
if (throwEquiped) {
owner.belongings.weapon = this;
owner.spend( -TIME_TO_EQUIP );
} else
if (!collect( curUser.belongings.backpack )) {
Dungeon.level.drop( this, owner.pos ).sprite.drop();
}
}
private boolean throwEquiped;
@Override
public void cast( Hero user, int dst ) {
throwEquiped = isEquipped( user );
super.cast( user, dst );
}
@Override
public String desc() {

View File

@ -94,9 +94,9 @@ public class MissileWeapon extends Weapon {
super.proc( attacker, defender, damage );
Hero hero = (Hero)attacker;
if (!hero.usingRanged && stackable) {
if (quantity == 1) {
doUnequip( hero, false );
if (hero.rangedWeapon == null && stackable) {
if (quantity == 1) {
doUnequip( hero, false, false );
} else {
detach( null );
}