v0.6.3: reworked core logic for ranged weapons
Still work to do: - need to rework ring of sharpshooting - need to convert huntress class powers - need to adjust how ranged weapons are dropped - need to change ranged weapon implementations
This commit is contained in:
parent
57b1f1e759
commit
ec724bea02
|
@ -42,6 +42,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfElements;
|
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfElements;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Door;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Door;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
|
@ -143,9 +144,15 @@ public abstract class Char extends Actor {
|
||||||
|
|
||||||
if (hit( this, enemy, false )) {
|
if (hit( this, enemy, false )) {
|
||||||
|
|
||||||
// FIXME
|
int dr = enemy.drRoll();
|
||||||
int dr = this instanceof Hero && ((Hero)this).rangedWeapon != null && ((Hero)this).subClass ==
|
|
||||||
HeroSubClass.SNIPER ? 0 : enemy.drRoll();
|
if (this instanceof Hero){
|
||||||
|
Hero h = (Hero)this;
|
||||||
|
if (h.belongings.weapon instanceof MissileWeapon
|
||||||
|
&& h.subClass == HeroSubClass.SNIPER){
|
||||||
|
dr = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int dmg;
|
int dmg;
|
||||||
Preparation prep = buff(Preparation.class);
|
Preparation prep = buff(Preparation.class);
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class PinCushion extends Buff {
|
||||||
public void stick(MissileWeapon projectile){
|
public void stick(MissileWeapon projectile){
|
||||||
for (Item item : items){
|
for (Item item : items){
|
||||||
if (item.isSimilar(projectile)){
|
if (item.isSimilar(projectile)){
|
||||||
item.quantity(item.quantity() + projectile.quantity());
|
item.merge(projectile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,8 +157,7 @@ public class Hero extends Char {
|
||||||
private Char enemy;
|
private Char enemy;
|
||||||
|
|
||||||
public boolean resting = false;
|
public boolean resting = false;
|
||||||
|
|
||||||
public MissileWeapon rangedWeapon = null;
|
|
||||||
public Belongings belongings;
|
public Belongings belongings;
|
||||||
|
|
||||||
public int STR;
|
public int STR;
|
||||||
|
@ -282,22 +281,26 @@ public class Hero extends Char {
|
||||||
|
|
||||||
public boolean shoot( Char enemy, MissileWeapon wep ) {
|
public boolean shoot( Char enemy, MissileWeapon wep ) {
|
||||||
|
|
||||||
rangedWeapon = wep;
|
//temporarily set the hero's weapon to the missile weapon being used
|
||||||
|
KindOfWeapon equipped = belongings.weapon;
|
||||||
|
belongings.weapon = wep;
|
||||||
boolean result = attack( enemy );
|
boolean result = attack( enemy );
|
||||||
Invisibility.dispel();
|
Invisibility.dispel();
|
||||||
rangedWeapon = null;
|
belongings.weapon = equipped;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int attackSkill( Char target ) {
|
public int attackSkill( Char target ) {
|
||||||
|
KindOfWeapon wep = belongings.weapon;
|
||||||
|
|
||||||
float accuracy = 1;
|
float accuracy = 1;
|
||||||
if (rangedWeapon != null && Dungeon.level.distance( pos, target.pos ) == 1) {
|
if (wep instanceof MissileWeapon
|
||||||
|
&& Dungeon.level.distance( pos, target.pos ) == 1) {
|
||||||
accuracy *= 0.5f;
|
accuracy *= 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
KindOfWeapon wep = rangedWeapon != null ? rangedWeapon : belongings.weapon;
|
|
||||||
if (wep != null) {
|
if (wep != null) {
|
||||||
return (int)(attackSkill * accuracy * wep.accuracyFactor( this ));
|
return (int)(attackSkill * accuracy * wep.accuracyFactor( this ));
|
||||||
} else {
|
} else {
|
||||||
|
@ -352,7 +355,7 @@ public class Hero extends Char {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int damageRoll() {
|
public int damageRoll() {
|
||||||
KindOfWeapon wep = rangedWeapon != null ? rangedWeapon : belongings.weapon;
|
KindOfWeapon wep = belongings.weapon;
|
||||||
int dmg;
|
int dmg;
|
||||||
|
|
||||||
if (wep != null) {
|
if (wep != null) {
|
||||||
|
@ -400,14 +403,9 @@ public class Hero extends Char {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canSurpriseAttack(){
|
public boolean canSurpriseAttack(){
|
||||||
if (belongings.weapon == null || !(belongings.weapon instanceof Weapon))
|
if (belongings.weapon == null || !(belongings.weapon instanceof Weapon)) return true;
|
||||||
return true;
|
if (STR() < ((Weapon)belongings.weapon).STRReq()) return false;
|
||||||
|
if (belongings.weapon instanceof Flail) return false;
|
||||||
if (STR() < ((Weapon)belongings.weapon).STRReq())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (belongings.weapon instanceof Flail && rangedWeapon == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -438,10 +436,9 @@ public class Hero extends Char {
|
||||||
}
|
}
|
||||||
|
|
||||||
public float attackDelay() {
|
public float attackDelay() {
|
||||||
KindOfWeapon wep = rangedWeapon != null ? rangedWeapon : belongings.weapon;
|
if (belongings.weapon != null) {
|
||||||
if (wep != null) {
|
|
||||||
|
|
||||||
return wep.speedFactor( this );
|
return belongings.weapon.speedFactor( this );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//Normally putting furor speed on unarmed attacks would be unnecessary
|
//Normally putting furor speed on unarmed attacks would be unnecessary
|
||||||
|
@ -915,14 +912,14 @@ public class Hero extends Char {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int attackProc( Char enemy, int damage ) {
|
public int attackProc( Char enemy, int damage ) {
|
||||||
KindOfWeapon wep = rangedWeapon != null ? rangedWeapon : belongings.weapon;
|
KindOfWeapon wep = belongings.weapon;
|
||||||
|
|
||||||
if (wep != null) damage = wep.proc( this, enemy, damage );
|
if (wep != null) damage = wep.proc( this, enemy, damage );
|
||||||
|
|
||||||
switch (subClass) {
|
switch (subClass) {
|
||||||
case SNIPER:
|
case SNIPER:
|
||||||
if (rangedWeapon != null) {
|
if (wep instanceof MissileWeapon) {
|
||||||
Buff.prolong( this, SnipersMark.class, attackDelay() * 1.1f ).object = enemy.id();
|
Buff.prolong( this, SnipersMark.class, attackDelay() ).object = enemy.id();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -181,8 +181,7 @@ public class Heap implements Bundlable {
|
||||||
|
|
||||||
for (Item i : items) {
|
for (Item i : items) {
|
||||||
if (i.isSimilar( item )) {
|
if (i.isSimilar( item )) {
|
||||||
i.quantity += item.quantity;
|
item = i.merge( item );
|
||||||
item = i;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,10 @@ import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||||
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.buffs.Combo;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Combo;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SnipersMark;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
|
import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Boomerang;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Boomerang;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog;
|
import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
|
@ -159,6 +157,15 @@ public class Item implements Bundlable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//takes two items and merges them (if possible)
|
||||||
|
public Item merge( Item other ){
|
||||||
|
if (isSimilar( other )){
|
||||||
|
quantity += other.quantity;
|
||||||
|
other.quantity = 0;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean collect( Bag container ) {
|
public boolean collect( Bag container ) {
|
||||||
|
|
||||||
ArrayList<Item> items = container.items;
|
ArrayList<Item> items = container.items;
|
||||||
|
@ -176,7 +183,7 @@ public class Item implements Bundlable {
|
||||||
if (stackable) {
|
if (stackable) {
|
||||||
for (Item item:items) {
|
for (Item item:items) {
|
||||||
if (isSimilar( item )) {
|
if (isSimilar( item )) {
|
||||||
item.quantity += quantity;
|
item.merge( this );
|
||||||
item.updateQuickslot();
|
item.updateQuickslot();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -207,6 +214,29 @@ public class Item implements Bundlable {
|
||||||
return collect( Dungeon.hero.belongings.backpack );
|
return collect( Dungeon.hero.belongings.backpack );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//returns a new item if the split was sucessful and there are now 2 items, otherwise null
|
||||||
|
public Item split( int amount ){
|
||||||
|
if (amount <= 0 || amount >= quantity()) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
|
||||||
|
//pssh, who needs copy constructors?
|
||||||
|
Item split = getClass().newInstance();
|
||||||
|
Bundle copy = new Bundle();
|
||||||
|
this.storeInBundle(copy);
|
||||||
|
split.restoreFromBundle(copy);
|
||||||
|
split.quantity(amount);
|
||||||
|
quantity -= amount;
|
||||||
|
|
||||||
|
return split;
|
||||||
|
} catch (Exception e){
|
||||||
|
ShatteredPixelDungeon.reportException(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public final Item detach( Bag container ) {
|
public final Item detach( Bag container ) {
|
||||||
|
|
||||||
if (quantity <= 0) {
|
if (quantity <= 0) {
|
||||||
|
@ -224,24 +254,12 @@ public class Item implements Bundlable {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
quantity--;
|
|
||||||
updateQuickslot();
|
|
||||||
|
|
||||||
try {
|
Item detached = split(1);
|
||||||
|
updateQuickslot();
|
||||||
//pssh, who needs copy constructors?
|
if (detached != null) detached.onDetach( );
|
||||||
Item detached = getClass().newInstance();
|
return detached;
|
||||||
Bundle copy = new Bundle();
|
|
||||||
this.storeInBundle(copy);
|
|
||||||
detached.restoreFromBundle(copy);
|
|
||||||
detached.quantity(1);
|
|
||||||
|
|
||||||
detached.onDetach( );
|
|
||||||
return detached;
|
|
||||||
} catch (Exception e) {
|
|
||||||
ShatteredPixelDungeon.reportException(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,7 +492,7 @@ public class Item implements Bundlable {
|
||||||
return new Ballistica( user.pos, dst, Ballistica.PROJECTILE ).collisionPos;
|
return new Ballistica( user.pos, dst, Ballistica.PROJECTILE ).collisionPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cast( final Hero user, int dst ) {
|
public void cast( final Hero user, final int dst ) {
|
||||||
|
|
||||||
final int cell = throwPos( user, dst );
|
final int cell = throwPos( user, dst );
|
||||||
user.sprite.zap( cell );
|
user.sprite.zap( cell );
|
||||||
|
@ -484,22 +502,8 @@ public class Item implements Bundlable {
|
||||||
|
|
||||||
Char enemy = Actor.findChar( cell );
|
Char enemy = Actor.findChar( cell );
|
||||||
QuickSlotButton.target(enemy);
|
QuickSlotButton.target(enemy);
|
||||||
|
|
||||||
// FIXME!!!
|
final float delay = castDelay(user, dst);
|
||||||
float delay = TIME_TO_THROW;
|
|
||||||
if (this instanceof MissileWeapon) {
|
|
||||||
delay *= ((MissileWeapon)this).speedFactor( user );
|
|
||||||
if (enemy != null) {
|
|
||||||
SnipersMark mark = user.buff( SnipersMark.class );
|
|
||||||
if (mark != null) {
|
|
||||||
if (mark.object == enemy.id()) {
|
|
||||||
delay *= 0.5f;
|
|
||||||
}
|
|
||||||
user.remove( mark );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final float finalDelay = delay;
|
|
||||||
|
|
||||||
if (enemy != null) {
|
if (enemy != null) {
|
||||||
((MissileSprite) user.sprite.parent.recycle(MissileSprite.class)).
|
((MissileSprite) user.sprite.parent.recycle(MissileSprite.class)).
|
||||||
|
@ -510,7 +514,7 @@ public class Item implements Bundlable {
|
||||||
@Override
|
@Override
|
||||||
public void call() {
|
public void call() {
|
||||||
Item.this.detach(user.belongings.backpack).onThrow(cell);
|
Item.this.detach(user.belongings.backpack).onThrow(cell);
|
||||||
user.spendAndNext(finalDelay);
|
user.spendAndNext(delay);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -522,12 +526,16 @@ public class Item implements Bundlable {
|
||||||
@Override
|
@Override
|
||||||
public void call() {
|
public void call() {
|
||||||
Item.this.detach(user.belongings.backpack).onThrow(cell);
|
Item.this.detach(user.belongings.backpack).onThrow(cell);
|
||||||
user.spendAndNext(finalDelay);
|
user.spendAndNext(delay);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float castDelay( Char user, int dst ){
|
||||||
|
return TIME_TO_THROW;
|
||||||
|
}
|
||||||
|
|
||||||
protected static Hero curUser = null;
|
protected static Hero curUser = null;
|
||||||
protected static Item curItem = null;
|
protected static Item curItem = null;
|
||||||
protected static CellSelector.Listener thrower = new CellSelector.Listener() {
|
protected static CellSelector.Listener thrower = new CellSelector.Listener() {
|
||||||
|
|
|
@ -41,6 +41,9 @@ public class Boomerang extends MissileWeapon {
|
||||||
|
|
||||||
unique = true;
|
unique = true;
|
||||||
bones = false;
|
bones = false;
|
||||||
|
|
||||||
|
//does not use durability
|
||||||
|
durability = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -87,22 +90,14 @@ public class Boomerang extends MissileWeapon {
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item degrade() {
|
public void rangedHit( Char enemy ) {
|
||||||
return super.degrade();
|
circleBack(enemy.pos, curUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int proc( Char attacker, Char defender, int damage ) {
|
protected void rangedMiss( int cell ) {
|
||||||
if (attacker instanceof Hero && ((Hero)attacker).rangedWeapon == this) {
|
|
||||||
circleBack( defender.pos, (Hero)attacker );
|
|
||||||
}
|
|
||||||
return super.proc( attacker, defender, damage );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void miss( int cell ) {
|
|
||||||
circleBack( cell, curUser );
|
circleBack( cell, curUser );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
public class CurareDart extends MissileWeapon {
|
public class CurareDart extends Dart {
|
||||||
|
|
||||||
public static final float DURATION = 3f;
|
public static final float DURATION = 3f;
|
||||||
|
|
||||||
|
@ -36,16 +36,6 @@ public class CurareDart extends MissileWeapon {
|
||||||
image = ItemSpriteSheet.CURARE_DART;
|
image = ItemSpriteSheet.CURARE_DART;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int min(int lvl) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int max(int lvl) {
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int STRReq(int lvl) {
|
public int STRReq(int lvl) {
|
||||||
return 14;
|
return 14;
|
||||||
|
|
|
@ -21,6 +21,10 @@
|
||||||
|
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles;
|
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.PinCushion;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
@ -31,6 +35,9 @@ public class Dart extends MissileWeapon {
|
||||||
image = ItemSpriteSheet.DART;
|
image = ItemSpriteSheet.DART;
|
||||||
|
|
||||||
bones = false; //Finding them in bones would be semi-frequent and disappointing.
|
bones = false; //Finding them in bones would be semi-frequent and disappointing.
|
||||||
|
|
||||||
|
//does not use durability
|
||||||
|
durability = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,7 +54,15 @@ public class Dart extends MissileWeapon {
|
||||||
public int STRReq(int lvl) {
|
public int STRReq(int lvl) {
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void rangedHit(Char enemy) {
|
||||||
|
if (enemy.isAlive())
|
||||||
|
Buff.affect(enemy, PinCushion.class).stick(new Dart());
|
||||||
|
else
|
||||||
|
Dungeon.level.drop( new Dart(), enemy.pos).sprite.drop();
|
||||||
|
}
|
||||||
|
|
||||||
public Dart() {
|
public Dart() {
|
||||||
this( 1 );
|
this( 1 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,22 +33,12 @@ import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
public class IncendiaryDart extends MissileWeapon {
|
public class IncendiaryDart extends Dart {
|
||||||
|
|
||||||
{
|
{
|
||||||
image = ItemSpriteSheet.INCENDIARY_DART;
|
image = ItemSpriteSheet.INCENDIARY_DART;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int min(int lvl) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int max(int lvl) {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int STRReq(int lvl) {
|
public int STRReq(int lvl) {
|
||||||
return 12;
|
return 12;
|
||||||
|
@ -66,10 +56,12 @@ public class IncendiaryDart extends MissileWeapon {
|
||||||
@Override
|
@Override
|
||||||
protected void onThrow( int cell ) {
|
protected void onThrow( int cell ) {
|
||||||
Char enemy = Actor.findChar( cell );
|
Char enemy = Actor.findChar( cell );
|
||||||
if ((enemy == null || enemy == curUser) && Dungeon.level.flamable[cell])
|
if ((enemy == null || enemy == curUser) && Dungeon.level.flamable[cell]) {
|
||||||
GameScene.add( Blob.seed( cell, 4, Fire.class ) );
|
GameScene.add(Blob.seed(cell, 4, Fire.class));
|
||||||
else
|
Dungeon.level.drop(new Dart(), cell).sprite.drop();
|
||||||
super.onThrow( cell );
|
} else{
|
||||||
|
super.onThrow(cell);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -64,6 +64,11 @@ public class Javelin extends MissileWeapon {
|
||||||
return super.proc( attacker, defender, damage );
|
return super.proc( attacker, defender, damage );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void reduceDurability() {
|
||||||
|
durability -= 10;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item random() {
|
public Item random() {
|
||||||
quantity = Random.Int( 5, 15 );
|
quantity = Random.Int( 5, 15 );
|
||||||
|
|
|
@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||||
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.PinCushion;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.PinCushion;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SnipersMark;
|
||||||
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.items.Item;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
|
@ -33,6 +34,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfSharpshooting;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Projecting;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Projecting;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
|
import com.watabou.utils.Bundle;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -47,6 +49,9 @@ abstract public class MissileWeapon extends Weapon {
|
||||||
usesTargeting = true;
|
usesTargeting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//weapons which don't use durability should set it to -1
|
||||||
|
protected float durability = 100;
|
||||||
|
|
||||||
@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 );
|
||||||
|
@ -68,32 +73,56 @@ abstract public class MissileWeapon extends Weapon {
|
||||||
protected void onThrow( int cell ) {
|
protected void onThrow( int cell ) {
|
||||||
Char enemy = Actor.findChar( cell );
|
Char enemy = Actor.findChar( cell );
|
||||||
if (enemy == null || enemy == curUser) {
|
if (enemy == null || enemy == curUser) {
|
||||||
if (this instanceof Boomerang)
|
|
||||||
super.onThrow( cell );
|
super.onThrow( cell );
|
||||||
else
|
|
||||||
miss( cell );
|
|
||||||
} else {
|
} else {
|
||||||
if (!curUser.shoot( enemy, this )) {
|
if (!curUser.shoot( enemy, this )) {
|
||||||
miss( cell );
|
rangedMiss( cell );
|
||||||
} else if (!(this instanceof Boomerang)){
|
} else {
|
||||||
|
|
||||||
int bonus = RingOfSharpshooting.getBonus(curUser, RingOfSharpshooting.Aim.class);
|
//int bonus = RingOfSharpshooting.getBonus(curUser, RingOfSharpshooting.Aim.class);
|
||||||
|
|
||||||
if (curUser.heroClass == HeroClass.HUNTRESS && enemy.buff(PinCushion.class) == null)
|
//if (curUser.heroClass == HeroClass.HUNTRESS && enemy.buff(PinCushion.class) == null)
|
||||||
bonus += 3;
|
// bonus += 3;
|
||||||
|
|
||||||
if (Random.Float() > Math.pow(0.7, bonus)){
|
rangedHit( enemy );
|
||||||
if (enemy.isAlive())
|
|
||||||
Buff.affect(enemy, PinCushion.class).stick(this);
|
|
||||||
else
|
|
||||||
Dungeon.level.drop( this, enemy.pos).sprite.drop();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void miss( int cell ) {
|
@Override
|
||||||
|
public float castDelay(Char user, int dst) {
|
||||||
|
float delay = speedFactor( user );
|
||||||
|
|
||||||
|
Char enemy = Actor.findChar(dst);
|
||||||
|
|
||||||
|
if (enemy != null) {
|
||||||
|
SnipersMark mark = user.buff( SnipersMark.class );
|
||||||
|
if (mark != null) {
|
||||||
|
if (mark.object == enemy.id()) {
|
||||||
|
delay *= 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void rangedHit(Char enemy ){
|
||||||
|
reduceDurability();
|
||||||
|
if (durability > 0){
|
||||||
|
if (enemy.isAlive())
|
||||||
|
Buff.affect(enemy, PinCushion.class).stick(this);
|
||||||
|
else
|
||||||
|
Dungeon.level.drop( this, enemy.pos).sprite.drop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void reduceDurability(){
|
||||||
|
//do nothing by default
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void rangedMiss(int cell ) {
|
||||||
int bonus = RingOfSharpshooting.getBonus(curUser, RingOfSharpshooting.Aim.class);
|
int bonus = RingOfSharpshooting.getBonus(curUser, RingOfSharpshooting.Aim.class);
|
||||||
|
|
||||||
//degraded ring of sharpshooting will even make missed shots break.
|
//degraded ring of sharpshooting will even make missed shots break.
|
||||||
|
@ -102,26 +131,43 @@ abstract public class MissileWeapon extends Weapon {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int proc( Char attacker, Char defender, int damage ) {
|
public Item random() {
|
||||||
|
if (durability != -1) durability = Random.NormalIntRange(70, 100);
|
||||||
Hero hero = (Hero)attacker;
|
return this;
|
||||||
if (hero.rangedWeapon == null && stackable) {
|
|
||||||
if (quantity == 1) {
|
|
||||||
doUnequip( hero, false, false );
|
|
||||||
} else {
|
|
||||||
detach( null );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.proc( attacker, defender, damage );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item random() {
|
public void reset() {
|
||||||
|
super.reset();
|
||||||
|
durability = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Item merge(Item other) {
|
||||||
|
super.merge(other);
|
||||||
|
if (isSimilar(other) && durability != -1) {
|
||||||
|
durability += ((MissileWeapon)other).durability;
|
||||||
|
durability -= 100;
|
||||||
|
while (durability <= 0){
|
||||||
|
quantity -= 1;
|
||||||
|
durability += 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Item split(int amount) {
|
||||||
|
Item split = super.split(amount);
|
||||||
|
|
||||||
|
//the split item will retain lost durability
|
||||||
|
if (split != null && durability != -1){
|
||||||
|
durability = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
return split;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isUpgradable() {
|
public boolean isUpgradable() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -158,6 +204,34 @@ abstract public class MissileWeapon extends Weapon {
|
||||||
|
|
||||||
info += "\n\n" + Messages.get(MissileWeapon.class, "distance");
|
info += "\n\n" + Messages.get(MissileWeapon.class, "distance");
|
||||||
|
|
||||||
|
info += "\n\n" + Messages.get(this, "durability");
|
||||||
|
|
||||||
|
//weapons which don't use durability should set it to -1, and have their own text
|
||||||
|
if (durability >= 100) info += "\n\n" + Messages.get(this, "dur_100");
|
||||||
|
else if (durability >= 80) info += "\n\n" + Messages.get(this, "dur_80");
|
||||||
|
else if (durability >= 60) info += "\n\n" + Messages.get(this, "dur_60");
|
||||||
|
else if (durability >= 40) info += "\n\n" + Messages.get(this, "dur_40");
|
||||||
|
else if (durability >= 20) info += "\n\n" + Messages.get(this, "dur_20");
|
||||||
|
else if (durability >= 0) info += "\n\n" + Messages.get(this, "dur_0");
|
||||||
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String DURABILITY = "durability";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeInBundle(Bundle bundle) {
|
||||||
|
super.storeInBundle(bundle);
|
||||||
|
bundle.put(DURABILITY, durability);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreFromBundle(Bundle bundle) {
|
||||||
|
super.restoreFromBundle(bundle);
|
||||||
|
//compatibility with pre-0.6.3 saves
|
||||||
|
if (bundle.contains(DURABILITY)) {
|
||||||
|
durability = bundle.getInt(DURABILITY);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,11 @@ public class Shuriken extends MissileWeapon {
|
||||||
quantity = number;
|
quantity = number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void reduceDurability() {
|
||||||
|
durability -= 10;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item random() {
|
public Item random() {
|
||||||
quantity = Random.Int( 5, 15 );
|
quantity = Random.Int( 5, 15 );
|
||||||
|
|
|
@ -65,6 +65,11 @@ public class Tamahawk extends MissileWeapon {
|
||||||
return super.proc( attacker, defender, damage );
|
return super.proc( attacker, defender, damage );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void reduceDurability() {
|
||||||
|
durability -= 10;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item random() {
|
public Item random() {
|
||||||
quantity = Random.Int( 5, 12 );
|
quantity = Random.Int( 5, 12 );
|
||||||
|
|
|
@ -928,12 +928,14 @@ items.weapon.melee.wornshortsword.desc=A quite short sword, worn down through he
|
||||||
###missile weapons
|
###missile weapons
|
||||||
items.weapon.missiles.boomerang.name=boomerang
|
items.weapon.missiles.boomerang.name=boomerang
|
||||||
items.weapon.missiles.boomerang.desc=Thrown to the enemy this flat curved wooden missile will return to the hands of its thrower.
|
items.weapon.missiles.boomerang.desc=Thrown to the enemy this flat curved wooden missile will return to the hands of its thrower.
|
||||||
|
items.weapon.missiles.boomerang.durability=Due it its solid construction, this boomerang will not break from use.
|
||||||
|
|
||||||
items.weapon.missiles.curaredart.name=curare dart
|
items.weapon.missiles.curaredart.name=curare dart
|
||||||
items.weapon.missiles.curaredart.desc=These little evil darts don't do much damage but they can paralyze the target leaving it helpless and motionless for some time.
|
items.weapon.missiles.curaredart.desc=These little evil darts don't do much damage but they can paralyze the target leaving it helpless and motionless for some time.
|
||||||
|
|
||||||
items.weapon.missiles.dart.name=dart
|
items.weapon.missiles.dart.name=dart
|
||||||
items.weapon.missiles.dart.desc=These simple metal spikes are weighted to fly true and sting their prey with a flick of the wrist.
|
items.weapon.missiles.dart.desc=These simple metal spikes are weighted to fly true and sting their prey with a flick of the wrist.
|
||||||
|
items.weapon.missiles.dart.durability=Due to their size and simple construction, darts will never break from use. However specially tipped darts will lose their effect after one use.
|
||||||
|
|
||||||
items.weapon.missiles.incendiarydart.name=incendiary dart
|
items.weapon.missiles.incendiarydart.name=incendiary dart
|
||||||
items.weapon.missiles.incendiarydart.desc=The spike on each of these darts is designed to pin it to its target while the unstable compounds strapped to its length burst into brilliant flames.
|
items.weapon.missiles.incendiarydart.desc=The spike on each of these darts is designed to pin it to its target while the unstable compounds strapped to its length burst into brilliant flames.
|
||||||
|
@ -943,6 +945,13 @@ items.weapon.missiles.javelin.desc=This length of metal is weighted to keep the
|
||||||
|
|
||||||
items.weapon.missiles.missileweapon.stats=This missile weapon deals _%1$d-%2$d damage_ and requires _%3$d strength_ to use properly.
|
items.weapon.missiles.missileweapon.stats=This missile weapon deals _%1$d-%2$d damage_ and requires _%3$d strength_ to use properly.
|
||||||
items.weapon.missiles.missileweapon.distance=This weapon is designed to be used at a distance, it is much less accurate at melee range.
|
items.weapon.missiles.missileweapon.distance=This weapon is designed to be used at a distance, it is much less accurate at melee range.
|
||||||
|
items.weapon.missiles.missileweapon.durability=Missile weapons will wear out and break as they are used. You will automatically combine parts so that only the first weapon in a stack is worn.
|
||||||
|
items.weapon.missiles.missileweapon.dur_100=The first weapon is in _perfect condition._
|
||||||
|
items.weapon.missiles.missileweapon.dur_80=The first weapon is in _excellent condition._
|
||||||
|
items.weapon.missiles.missileweapon.dur_60=The first weapon is in _good condition._
|
||||||
|
items.weapon.missiles.missileweapon.dur_40=The first weapon is in _fair condition._
|
||||||
|
items.weapon.missiles.missileweapon.dur_20=The first weapon is in _poor condition._
|
||||||
|
items.weapon.missiles.missileweapon.dur_0=The first weapon is in _terrible condition._
|
||||||
|
|
||||||
items.weapon.missiles.shuriken.name=shuriken
|
items.weapon.missiles.shuriken.name=shuriken
|
||||||
items.weapon.missiles.shuriken.desc=Star-shaped pieces of metal with razor-sharp blades do significant damage when they hit a target. They can be thrown at very high rate.
|
items.weapon.missiles.shuriken.desc=Star-shaped pieces of metal with razor-sharp blades do significant damage when they hit a target. They can be thrown at very high rate.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user