v0.7.3: added 2 additional thrown weapons

This commit is contained in:
Evan Debenham 2019-05-14 18:47:09 -04:00
parent 1434e36725
commit ea3f4bb99e
6 changed files with 251 additions and 30 deletions

View File

@ -295,9 +295,6 @@ public class Hero extends Char {
public int tier() {
return belongings.armor == null ? 0 : belongings.armor.tier;
}
//this variable is only needed because of the boomerang, remove if/when it is no longer equippable
boolean rangedAttack = false;
public boolean shoot( Char enemy, MissileWeapon wep ) {

View File

@ -138,8 +138,10 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Sword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.WarHammer;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Whip;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.WornShortsword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.HeavyBoomerang;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Bolas;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.FishingSpear;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.ForceCube;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Javelin;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Kunai;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
@ -398,15 +400,17 @@ public class Generator {
MIS_T4.classes = new Class<?>[]{
Javelin.class,
Tomahawk.class
Tomahawk.class,
HeavyBoomerang.class
};
MIS_T4.probs = new float[]{ 4, 3 };
MIS_T4.probs = new float[]{ 6, 5, 4 };
MIS_T5.classes = new Class<?>[]{
Trident.class,
ThrowingHammer.class
ThrowingHammer.class,
ForceCube.class
};
MIS_T5.probs = new float[]{ 4, 3 };
MIS_T5.probs = new float[]{ 6, 5, 4 };
FOOD.classes = new Class<?>[]{
Food.class,

View File

@ -0,0 +1,67 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2019 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles;
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.items.wands.WandOfBlastWave;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.PathFinder;
import java.util.ArrayList;
public class ForceCube extends MissileWeapon {
{
image = ItemSpriteSheet.FORCE_CUBE;
tier = 5;
baseUses = 5;
sticky = false;
}
@Override
protected void onThrow(int cell) {
Dungeon.level.press(cell, null, true);
ArrayList<Char> targets = new ArrayList<>();
if (Actor.findChar(cell) != null) targets.add(Actor.findChar(cell));
for (int i : PathFinder.NEIGHBOURS8){
Dungeon.level.press(cell + i, null, true);
if (Actor.findChar(cell + i) != null) targets.add(Actor.findChar(cell + i));
}
for (Char target : targets){
curUser.shoot(target, this);
}
rangedHit( null, cell );
WandOfBlastWave.BlastWave.blast(cell);
Sample.INSTANCE.play( Assets.SND_BLAST );
}
}

View File

@ -0,0 +1,143 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2019 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.sprites.MissileSprite;
import com.watabou.utils.Bundle;
import com.watabou.utils.Callback;
public class HeavyBoomerang extends MissileWeapon {
{
image = ItemSpriteSheet.BOOMERANG;
tier = 4;
sticky = false;
}
@Override
public int max(int lvl) {
return 4 * tier + //16 base, down from 20
(tier) * lvl; //scaling unchanged
}
@Override
protected void rangedHit(Char enemy, int cell) {
decrementDurability();
if (durability > 0){
//TODO vfx
Buff.append(Dungeon.hero, CircleBack.class).setup(this, cell, Dungeon.hero.pos, Dungeon.depth);
}
}
@Override
protected void rangedMiss(int cell) {
//TODO vfx
parent = null;
Buff.append(Dungeon.hero, CircleBack.class).setup(this, cell, Dungeon.hero.pos, Dungeon.depth);
}
public static class CircleBack extends Buff {
private MissileWeapon boomerang;
private int thrownPos;
private int returnPos;
private int returnDepth;
private int left;
public void setup( MissileWeapon boomerang, int thrownPos, int returnPos, int returnDepth){
this.boomerang = boomerang;
this.thrownPos = thrownPos;
this.returnPos = returnPos;
this.returnDepth = returnDepth;
left = 3;
}
@Override
public boolean act() {
if (returnDepth == Dungeon.depth){
left--;
if (left <= 0){
final Char returnTarget = Actor.findChar(returnPos);
((MissileSprite) Dungeon.hero.sprite.parent.recycle(MissileSprite.class)).
reset( thrownPos,
returnPos,
boomerang,
new Callback() {
@Override
public void call() {
if (returnTarget == Dungeon.hero){
boomerang.doPickUp(Dungeon.hero);
//grabbing the boomerang takes no time
Dungeon.hero.spend( -TIME_TO_PICK_UP );
} else if (returnTarget != null){
if (curUser.shoot( returnTarget, boomerang )) {
boomerang.decrementDurability();
}
if (boomerang.durability > 0) {
Dungeon.level.drop(boomerang, returnPos).sprite.drop();
}
} else {
Dungeon.level.drop(boomerang, returnPos).sprite.drop();
}
}
});
detach();
}
}
spend( TICK );
return true;
}
private static final String BOOMERANG = "boomerang";
private static final String THROWN_POS = "thrown_pos";
private static final String RETURN_POS = "return_pos";
private static final String RETURN_DEPTH = "return_depth";
@Override
public void storeInBundle(Bundle bundle) {
super.storeInBundle(bundle);
bundle.put(BOOMERANG, boomerang);
bundle.put(THROWN_POS, thrownPos);
bundle.put(RETURN_POS, returnPos);
bundle.put(RETURN_DEPTH, returnDepth);
}
@Override
public void restoreFromBundle(Bundle bundle) {
super.restoreFromBundle(bundle);
boomerang = (MissileWeapon) bundle.get(BOOMERANG);
thrownPos = bundle.getInt(THROWN_POS);
returnPos = bundle.getInt(RETURN_POS);
returnDepth = bundle.getInt(RETURN_DEPTH);
}
}
}

View File

@ -198,37 +198,17 @@ abstract public class MissileWeapon extends Weapon {
}
protected void rangedHit( Char enemy, int cell ){
//if this weapon was thrown from a source stack, degrade that stack.
//unless a weapon is about to break, then break the one being thrown
if (parent != null){
if (parent.durability <= parent.durabilityPerUse()){
durability = 0;
parent.durability = MAX_DURABILITY;
} else {
parent.durability -= parent.durabilityPerUse();
if (parent.durability > 0 && parent.durability <= parent.durabilityPerUse()){
if (level() <= 0)GLog.w(Messages.get(this, "about_to_break"));
else GLog.n(Messages.get(this, "about_to_break"));
}
}
parent = null;
} else {
durability -= durabilityPerUse();
if (durability > 0 && durability <= durabilityPerUse()){
if (level() <= 0)GLog.w(Messages.get(this, "about_to_break"));
else GLog.n(Messages.get(this, "about_to_break"));
}
}
decrementDurability();
if (durability > 0){
//attempt to stick the missile weapon to the enemy, just drop it if we can't.
if (enemy.isAlive() && sticky) {
if (enemy != null && enemy.isAlive() && sticky) {
PinCushion p = Buff.affect(enemy, PinCushion.class);
if (p.target == enemy){
p.stick(this);
return;
}
}
Dungeon.level.drop( this, enemy.pos ).sprite.drop();
Dungeon.level.drop( this, cell ).sprite.drop();
}
}
@ -252,6 +232,30 @@ abstract public class MissileWeapon extends Weapon {
return (MAX_DURABILITY/usages) + 0.001f;
}
protected void decrementDurability(){
//if this weapon was thrown from a source stack, degrade that stack.
//unless a weapon is about to break, then break the one being thrown
if (parent != null){
if (parent.durability <= parent.durabilityPerUse()){
durability = 0;
parent.durability = MAX_DURABILITY;
} else {
parent.durability -= parent.durabilityPerUse();
if (parent.durability > 0 && parent.durability <= parent.durabilityPerUse()){
if (level() <= 0)GLog.w(Messages.get(this, "about_to_break"));
else GLog.n(Messages.get(this, "about_to_break"));
}
}
parent = null;
} else {
durability -= durabilityPerUse();
if (durability > 0 && durability <= durabilityPerUse()){
if (level() <= 0)GLog.w(Messages.get(this, "about_to_break"));
else GLog.n(Messages.get(this, "about_to_break"));
}
}
}
@Override
public int damageRoll(Char owner) {
int damage = augment.damageFactor(super.damageRoll( owner ));

View File

@ -1406,6 +1406,12 @@ items.weapon.missiles.boomerang.durability=Due to its solid construction, this b
items.weapon.missiles.fishingspear.name=fishing spear
items.weapon.missiles.fishingspear.desc=Tiny throwing spears designed for fishing. They work well as an improvised weapon too.
items.weapon.missiles.forcecube.name=force cube
items.weapon.missiles.forcecube.desc=This oddly-shaped weapon is small enough to hold in your hand, but is incredibly heavy. When thrown, it will spread the force of its impact over a small area, damaging everything in the blast.
items.weapon.missiles.heavyboomerang.name=heavy boomerang
items.weapon.missiles.heavyboomerang.desc=This large boomerang is difficult to wield effectively, but will deal considerable damage. After a few turns, it will fly back to the location it was thrown from.
items.weapon.missiles.javelin.name=javelin
items.weapon.missiles.javelin.desc=These larger throwing spears are weighted to keep the spike at their tip foremost as they sail through the air.