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

View File

@ -17,6 +17,8 @@
*/ */
package com.shatteredpixel.shatteredpixeldungeon.items; package com.shatteredpixel.shatteredpixeldungeon.items;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample; import com.watabou.noosa.audio.Sample;
import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
@ -24,6 +26,8 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle
public abstract class EquipableItem extends Item { public abstract class EquipableItem extends Item {
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_EQUIP = "EQUIP";
public static final String AC_UNEQUIP = "UNEQUIP"; public static final String AC_UNEQUIP = "UNEQUIP";
@ -40,7 +44,7 @@ public abstract class EquipableItem extends Item {
@Override @Override
public void doDrop( Hero hero ) { public void doDrop( Hero hero ) {
if (!isEquipped( hero ) || doUnequip( hero, false )) { if (!isEquipped( hero ) || doUnequip( hero, false, false )) {
super.doDrop( hero ); super.doDrop( hero );
} }
} }
@ -49,8 +53,7 @@ public abstract class EquipableItem extends Item {
public void cast( final Hero user, int dst ) { public void cast( final Hero user, int dst ) {
if (isEquipped( user )) { if (isEquipped( user )) {
if (quantity == 1 && !this.doUnequip( user, false, false )) {
if (quantity == 1 && !this.doUnequip( user, false )) {
return; return;
} }
} }
@ -63,6 +66,33 @@ public abstract class EquipableItem extends Item {
Sample.INSTANCE.play( Assets.SND_CURSED ); Sample.INSTANCE.play( Assets.SND_CURSED );
} }
protected float time2equip( Hero hero ) {
return 1;
}
public abstract boolean doEquip( Hero hero ); public abstract boolean doEquip( Hero hero );
public abstract boolean doUnequip( Hero hero, boolean collect );
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 ); return collect( Dungeon.hero.belongings.backpack );
} }
public Item detach( Bag container ) { public final Item detach( Bag container ) {
if (quantity <= 0) { if (quantity <= 0) {
@ -204,24 +204,26 @@ public class Item implements Bundlable {
updateQuickslot(); updateQuickslot();
try { try {
return getClass().newInstance(); Item detached = getClass().newInstance();
detached.onDetach( );
return detached;
} catch (Exception e) { } catch (Exception e) {
return null; return null;
} }
} }
} }
public Item detachAll( Bag container ) { public final Item detachAll( Bag container ) {
for (Item item : container.items) { for (Item item : container.items) {
if (item == this) { if (item == this) {
container.items.remove( this ); container.items.remove( this );
item.onDetach( );
QuickSlot.refresh(); QuickSlot.refresh();
return this; return this;
} else if (item instanceof Bag) { } else if (item instanceof Bag) {
Bag bag = (Bag)item; Bag bag = (Bag)item;
if (bag.contains( this )) { if (bag.contains( this )) {
detachAll( bag ); return detachAll( bag );
return this;
} }
} }
} }
@ -233,6 +235,8 @@ public class Item implements Bundlable {
return getClass() == item.getClass(); return getClass() == item.getClass();
} }
protected void onDetach(){}
public Item upgrade() { public Item upgrade() {
cursed = false; cursed = false;
@ -428,7 +432,7 @@ public class Item implements Bundlable {
float delay = TIME_TO_THROW; float delay = TIME_TO_THROW;
if (this instanceof MissileWeapon) { if (this instanceof MissileWeapon) {
// Refactoring needed! // FIXME
delay *= ((MissileWeapon)this).speedFactor( user ); delay *= ((MissileWeapon)this).speedFactor( user );
if (enemy != null && enemy.buff( SnipersMark.class ) != null) { if (enemy != null && enemy.buff( SnipersMark.class ) != null) {
delay *= 0.5f; delay *= 0.5f;

View File

@ -19,7 +19,6 @@ package com.shatteredpixel.shatteredpixeldungeon.items;
import java.util.ArrayList; import java.util.ArrayList;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlot; import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlot;
@ -29,7 +28,6 @@ import com.watabou.utils.Random;
public class KindOfWeapon extends EquipableItem { 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_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; protected static final float TIME_TO_EQUIP = 1f;
@ -77,21 +75,17 @@ public class KindOfWeapon extends EquipableItem {
} }
@Override @Override
public boolean doUnequip( Hero hero, boolean collect ) { public boolean doUnequip( Hero hero, boolean collect, boolean single ) {
if (super.doUnequip( hero, collect, single )) {
if (cursed) {
GLog.w( TXT_UNEQUIP_CURSED, name() );
return false;
}
hero.belongings.weapon = null; hero.belongings.weapon = null;
hero.spendAndNext( TIME_TO_EQUIP );
if (collect && !collect( hero.belongings.backpack )) {
Dungeon.level.drop( this, hero.pos );
}
return true; return true;
} else {
return false;
}
} }
public void activate( Hero hero ) { 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 { public class Armor extends EquipableItem {
private static final String TXT_EQUIP_CURSED = "your %s constricts around you painfully"; 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."; 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 ); 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; hero.belongings.armor = this;
@ -101,7 +100,7 @@ public class Armor extends EquipableItem {
((HeroSprite)hero.sprite).updateArmor(); ((HeroSprite)hero.sprite).updateArmor();
hero.spendAndNext( 2 * hero.speed() ); hero.spendAndNext( 2 * time2equip( hero ) );
return true; return true;
} else { } else {
@ -113,24 +112,22 @@ public class Armor extends EquipableItem {
} }
@Override @Override
public boolean doUnequip( Hero hero, boolean collect ) { protected float time2equip( Hero hero ) {
if (cursed) { return hero.speed();
}
GLog.w( TXT_UNEQUIP_CURSED, name() ); @Override
return false; 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 { } else {
hero.belongings.armor = null; return false;
hero.spendAndNext( hero.speed() );
((HeroSprite)hero.sprite).updateArmor();
if (collect && !collect( hero.belongings.backpack )) {
Dungeon.level.drop( this, hero.pos );
}
return true;
} }
} }
@ -307,7 +304,15 @@ public class Armor extends EquipableItem {
} }
public Armor inscribe( Glyph glyph ) { 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; this.glyph = glyph;
return this; return this;
} }

View File

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

View File

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

View File

@ -65,7 +65,7 @@ public class MageArmor extends ClassArmor {
} }
} }
curUser.HP /= 2; curUser.HP -= (curUser.HP / 3);
curUser.spend( Actor.TICK ); curUser.spend( Actor.TICK );
curUser.sprite.operate( curUser.pos ); 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.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; 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.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlink; import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlink;
@ -89,12 +88,12 @@ public class RogueArmor extends ClassArmor {
return; return;
} }
curUser.HP /= 2; curUser.HP -= (curUser.HP / 3);
for (Mob mob : Dungeon.level.mobs) { for (Mob mob : Dungeon.level.mobs) {
if (Level.fieldOfView[mob.pos]) { if (Level.fieldOfView[mob.pos]) {
Buff.prolong( mob, Blindness.class, 2 ); Buff.prolong( mob, Blindness.class, 2 );
mob.state = State.WANDERING; mob.state = mob.WANDERING;
mob.sprite.emitter().burst( Speck.factory( Speck.LIGHT ), 4 ); mob.sprite.emitter().burst( Speck.factory( Speck.LIGHT ), 4 );
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -86,9 +86,8 @@ public class Bag extends Item implements Iterable<Item> {
} }
@Override @Override
public Item detach( Bag container ) { public void onDetach( ) {
owner = null; this.owner = null;
return super.detach( container );
} }
@Override @Override

View File

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

View File

@ -57,7 +57,7 @@ public class MysteryMeat extends Food {
break; break;
case 2: case 2:
GLog.w( "You are not feeling well." ); 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; break;
case 3: case 3:
GLog.w( "You are stuffed." ); 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"; 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"; name = "iron key";
@ -53,12 +53,10 @@ public class IronKey extends Key {
} }
@Override @Override
public Item detach( Bag bag ) { public void onDetach( ) {
Item result = super.detach( bag ); if (depth == Dungeon.depth) {
if (result != null && depth == Dungeon.depth) {
Dungeon.hero.belongings.countIronKeys(); Dungeon.hero.belongings.countIronKeys();
} }
return result;
} }
@Override @Override

View File

@ -36,13 +36,6 @@ public class Key extends Item {
return item.getClass() == getClass() && ((Key)item).depth == depth; 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"; private static final String DEPTH = "depth";
@Override @Override
@ -66,4 +59,10 @@ public class Key extends Item {
public boolean isIdentified() { public boolean isIdentified() {
return true; return true;
} }
@Override
public String status() {
return depth + "*";
}
} }

View File

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

View File

@ -147,8 +147,8 @@ public abstract class Wand extends KindOfWeapon {
@Override @Override
public boolean doUnequip( Hero hero, boolean collect ) { public boolean doUnequip( Hero hero, boolean collect ) {
charger.detach(); onDetach();
return super.doUnequip(hero, collect); return super.doUnequip( hero, collect );
} }
@Override @Override
@ -190,15 +190,8 @@ public abstract class Wand extends KindOfWeapon {
} }
@Override @Override
public Item detach( Bag container ) { public void onDetach( ) {
stopCharging(); stopCharging();
return super.detach( container );
}
@Override
public Item detachAll( Bag container) {
stopCharging();
return super.detachAll( container );
} }
public void stopCharging() { public void stopCharging() {

View File

@ -17,6 +17,8 @@
*/ */
package com.shatteredpixel.shatteredpixeldungeon.items.wands; 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.watabou.noosa.audio.Sample;
import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
@ -38,7 +40,11 @@ public class WandOfAmok extends Wand {
Char ch = Actor.findChar( cell ); Char ch = Actor.findChar( cell );
if (ch != null) { if (ch != null) {
if (ch == Dungeon.hero) {
Buff.affect( ch, Vertigo.class, Vertigo.duration(ch) );
} else {
Buff.affect( ch, Amok.class, 3f + level() ); Buff.affect( ch, Amok.class, 3f + level() );
}
} else { } else {

View File

@ -17,12 +17,12 @@
*/ */
package com.shatteredpixel.shatteredpixeldungeon.items.wands; package com.shatteredpixel.shatteredpixeldungeon.items.wands;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.NPC;
import com.watabou.noosa.audio.Sample; import com.watabou.noosa.audio.Sample;
import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile; import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; 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."; "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..."}; private static final String[] QUOTES = {"Baa!", "Baa?", "Baa.", "Baa..."};

View File

@ -48,7 +48,6 @@ public class WandOfLightning extends Wand {
@Override @Override
protected void onZap( int cell ) { protected void onZap( int cell ) {
// The actual effect is processed in "fx" method
if (!curUser.isAlive()) { if (!curUser.isAlive()) {
Dungeon.fail( Utils.format( ResultDescriptions.ITEM, name, Dungeon.depth ) ); 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 ); Char ch = Actor.findChar( cell );
if (ch != null) { 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 { } else {

View File

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

View File

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

View File

@ -47,6 +47,11 @@ public class Weapon extends KindOfWeapon {
public float ACU = 1; // Accuracy modifier public float ACU = 1; // Accuracy modifier
public float DLY = 1f; // Speed modifier public float DLY = 1f; // Speed modifier
public enum Imbue {
NONE, SPEED, ACCURACY
}
public Imbue imbue = Imbue.NONE;
private int hitsToKnow = 20; private int hitsToKnow = 20;
protected Enchantment enchantment; protected Enchantment enchantment;
@ -68,17 +73,20 @@ public class Weapon extends KindOfWeapon {
} }
private static final String ENCHANTMENT = "enchantment"; private static final String ENCHANTMENT = "enchantment";
private static final String IMBUE = "imbue";
@Override @Override
public void storeInBundle( Bundle bundle ) { public void storeInBundle( Bundle bundle ) {
super.storeInBundle( bundle ); super.storeInBundle( bundle );
bundle.put( ENCHANTMENT, enchantment ); bundle.put( ENCHANTMENT, enchantment );
bundle.put( IMBUE, imbue );
} }
@Override @Override
public void restoreFromBundle( Bundle bundle ) { public void restoreFromBundle( Bundle bundle ) {
super.restoreFromBundle( bundle ); super.restoreFromBundle( bundle );
enchantment = (Enchantment)bundle.get( ENCHANTMENT ); enchantment = (Enchantment)bundle.get( ENCHANTMENT );
imbue = bundle.getEnum( IMBUE, Imbue.class );
} }
@Override @Override
@ -105,7 +113,9 @@ public class Weapon extends KindOfWeapon {
ACU *= (float)(Math.pow(1.1, bonus)); 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 @Override
@ -123,7 +133,9 @@ public class Weapon extends KindOfWeapon {
float DLY = (float)(0.25 + (this.DLY - 0.25)*Math.pow(0.8, bonus)); 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 @Override
@ -131,7 +143,7 @@ public class Weapon extends KindOfWeapon {
int damage = super.damageRoll( hero ); 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; int exStr = hero.STR() - STR;
if (exStr > 0) { if (exStr > 0) {
damage += Random.IntRange( 0, exStr ); damage += Random.IntRange( 0, exStr );

View File

@ -17,9 +17,11 @@
*/ */
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments; package com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror; 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.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite.Glowing; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite.Glowing;
@ -40,8 +42,11 @@ public class Horror extends Weapon.Enchantment {
if (Random.Int( level + 5 ) >= 4) { if (Random.Int( level + 5 ) >= 4) {
Terror terror = Buff.affect( defender, Terror.class, Terror.DURATION ); if (defender == Dungeon.hero) {
terror.source = attacker; Buff.affect( defender, Vertigo.class, Vertigo.duration(defender) );
} else {
Buff.affect( defender, Terror.class, Terror.DURATION ).source = attacker;
}
return true; return true;
} else { } else {

View File

@ -115,6 +115,15 @@ public class MeleeWeapon extends Weapon {
} else if (ACU != 1f) { } else if (ACU != 1f) {
info.append( "This is a rather " + (ACU > 1f ? "accurate" : "inaccurate") + " weapon. " ); 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) { if (enchantment != null) {
info.append( "It is enchanted." ); info.append( "It is enchanted." );

View File

@ -80,7 +80,7 @@ public class Boomerang extends MissileWeapon {
@Override @Override
public void proc( Char attacker, Char defender, int damage ) { public void proc( Char attacker, Char defender, int damage ) {
super.proc( attacker, defender, damage ); super.proc( attacker, defender, damage );
if (attacker instanceof Hero && ((Hero)attacker).usingRanged) { if (attacker instanceof Hero && ((Hero)attacker).rangedWeapon == this) {
circleBack( defender.pos, (Hero)attacker ); circleBack( defender.pos, (Hero)attacker );
} }
} }
@ -91,11 +91,25 @@ public class Boomerang extends MissileWeapon {
} }
private void circleBack( int from, Hero owner ) { 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 )) { if (!collect( curUser.belongings.backpack )) {
Dungeon.level.drop( this, owner.pos ).sprite.drop(); Dungeon.level.drop( this, owner.pos ).sprite.drop();
} }
((MissileSprite)curUser.sprite.parent.recycle( MissileSprite.class )). }
reset( from, curUser.pos, curItem, null );
private boolean throwEquiped;
@Override
public void cast( Hero user, int dst ) {
throwEquiped = isEquipped( user );
super.cast( user, dst );
} }
@Override @Override

View File

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