v2.0.0: lots of initial duelist weapon ability structure
This commit is contained in:
@@ -504,7 +504,7 @@ actors.hero.heroclass.huntress_unlock=To unlock the Huntress _hit enemies with t
|
|||||||
|
|
||||||
actors.hero.heroclass.duelist=Duelist
|
actors.hero.heroclass.duelist=Duelist
|
||||||
actors.hero.heroclass.duelist_desc_short=The Duelist is a weapons master who can use her weapon to trigger a _special weapon ability._ This special ability is _different for every weapon._
|
actors.hero.heroclass.duelist_desc_short=The Duelist is a weapons master who can use her weapon to trigger a _special weapon ability._ This special ability is _different for every weapon._
|
||||||
actors.hero.heroclass.duelist_desc=The Duelist starts with a _unique Rapier_ with a special ability.\n\nThe Duelist gets a _different special ability_ for every weapon in the game.\n\nThe duelist also starts with _three throwing knives_, cloth armor, a waterskin, and a velvet pouch.\n\nThe Duelist automatically identifies:\n_-_ Scrolls of Identify\n_-_ Potions of Strength\n_-_ Scrolls of Mirror Image
|
actors.hero.heroclass.duelist_desc=The Duelist starts with a _unique rapier_ with a special ability that recharges over time.\n\nEvery weapon in the game has a _different special ability_ that the Duelist can use.\n\nThe duelist also starts with _three throwing knives_, cloth armor, a waterskin, and a velvet pouch.\n\nThe Duelist automatically identifies:\n_-_ Scrolls of Identify\n_-_ Potions of Strength\n_-_ Scrolls of Mirror Image
|
||||||
actors.hero.heroclass.duelist_unlock=To unlock the Duelist _equip a tier 2 or higher weapon with no strength penalty._
|
actors.hero.heroclass.duelist_unlock=To unlock the Duelist _equip a tier 2 or higher weapon with no strength penalty._
|
||||||
|
|
||||||
actors.hero.herosubclass.berserker=berserker
|
actors.hero.herosubclass.berserker=berserker
|
||||||
|
|||||||
@@ -1566,6 +1566,10 @@ items.weapon.melee.meleeweapon.stats_known=This _tier-%1$d_ melee weapon deals _
|
|||||||
items.weapon.melee.meleeweapon.stats_unknown=Typically this _tier-%1$d_ melee weapon deals _%2$d-%3$d damage_ and requires _%4$d strength_ to use properly.
|
items.weapon.melee.meleeweapon.stats_unknown=Typically this _tier-%1$d_ melee weapon deals _%2$d-%3$d damage_ and requires _%4$d strength_ to use properly.
|
||||||
items.weapon.melee.meleeweapon.probably_too_heavy=Probably this weapon is too heavy for you.
|
items.weapon.melee.meleeweapon.probably_too_heavy=Probably this weapon is too heavy for you.
|
||||||
items.weapon.melee.meleeweapon.stats_desc=
|
items.weapon.melee.meleeweapon.stats_desc=
|
||||||
|
items.weapon.melee.meleeweapon.charge_use=This will consume _%s_ charge.
|
||||||
|
items.weapon.melee.meleeweapon.ability_equip=You must equip that weapon to use its ability.
|
||||||
|
items.weapon.melee.meleeweapon.ability_charge=You don't have enough energy to use that ability.
|
||||||
|
items.weapon.melee.meleeweapon.prompt=Select a Target
|
||||||
|
|
||||||
items.weapon.melee.shortsword.name=shortsword
|
items.weapon.melee.shortsword.name=shortsword
|
||||||
items.weapon.melee.shortsword.desc=A quite short sword, only a few inches longer than a dagger.
|
items.weapon.melee.shortsword.desc=A quite short sword, only a few inches longer than a dagger.
|
||||||
@@ -1576,7 +1580,9 @@ items.weapon.melee.quarterstaff.desc=A staff of hardwood, its ends are shod with
|
|||||||
|
|
||||||
items.weapon.melee.rapier.name=rapier
|
items.weapon.melee.rapier.name=rapier
|
||||||
items.weapon.melee.rapier.stats_desc=This weapon blocks 0-1 damage.
|
items.weapon.melee.rapier.stats_desc=This weapon blocks 0-1 damage.
|
||||||
items.weapon.melee.rapier.desc=TODO
|
items.weapon.melee.rapier.ability_name=lunge
|
||||||
|
items.weapon.melee.rapier.ability_desc=The duelist can _lunge_ with a rapier at an enemy 1 tile away. This moves into the enemy, deals +33% damage, and is guaranteed to hit.
|
||||||
|
items.weapon.melee.rapier.desc=A slim straight sword that offers some protection in exchange for less slashing power.
|
||||||
|
|
||||||
items.weapon.melee.roundshield.name=round shield
|
items.weapon.melee.roundshield.name=round shield
|
||||||
items.weapon.melee.roundshield.typical_stats_desc=Typically this weapon blocks 0-%d damage. This blocking scales with upgrades.
|
items.weapon.melee.roundshield.typical_stats_desc=Typically this weapon blocks 0-%d damage. This blocking scales with upgrades.
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Challenges;
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.QuickSlot;
|
import com.shatteredpixel.shatteredpixeldungeon.QuickSlot;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
|
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.NaturesPower;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.NaturesPower;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.SpiritHawk;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.SpiritHawk;
|
||||||
@@ -63,6 +64,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.SpiritBow;
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Dagger;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Dagger;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Gloves;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Gloves;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Rapier;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Rapier;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.WornShortsword;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.WornShortsword;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.ThrowingKnife;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.ThrowingKnife;
|
||||||
@@ -212,6 +214,9 @@ public enum HeroClass {
|
|||||||
private static void initDuelist( Hero hero ) {
|
private static void initDuelist( Hero hero ) {
|
||||||
|
|
||||||
(hero.belongings.weapon = new Rapier()).identify();
|
(hero.belongings.weapon = new Rapier()).identify();
|
||||||
|
hero.belongings.weapon.activate(hero);
|
||||||
|
|
||||||
|
Buff.affect(hero, MeleeWeapon.Charger.class).charge = 100f;
|
||||||
|
|
||||||
ThrowingKnife knives = new ThrowingKnife();
|
ThrowingKnife knives = new ThrowingKnife();
|
||||||
knives.quantity(3).collect();
|
knives.quantity(3).collect();
|
||||||
|
|||||||
+1
-1
@@ -164,7 +164,7 @@ abstract public class ClassArmor extends Armor {
|
|||||||
@Override
|
@Override
|
||||||
public String actionName(String action, Hero hero) {
|
public String actionName(String action, Hero hero) {
|
||||||
if (hero.armorAbility != null && action.equals(AC_ABILITY)){
|
if (hero.armorAbility != null && action.equals(AC_ABILITY)){
|
||||||
return hero.armorAbility.name().toUpperCase();
|
return Messages.upperCase(hero.armorAbility.name());
|
||||||
} else {
|
} else {
|
||||||
return super.actionName(action, hero);
|
return super.actionName(action, hero);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -115,6 +115,7 @@ public class MagesStaff extends MeleeWeapon {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void activate( Char ch ) {
|
public void activate( Char ch ) {
|
||||||
|
super.activate(ch);
|
||||||
applyWandChargeBuff(ch);
|
applyWandChargeBuff(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+119
-5
@@ -23,25 +23,39 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee;
|
|||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
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.LockedFloor;
|
||||||
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.weapon.Weapon;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||||
|
import com.watabou.utils.Bundle;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class MeleeWeapon extends Weapon {
|
public class MeleeWeapon extends Weapon {
|
||||||
|
|
||||||
public static String AC_ABILITY = "ABILITY";
|
public static String AC_ABILITY = "ABILITY";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void activate(Char ch) {
|
||||||
|
super.activate(ch);
|
||||||
|
if (ch instanceof Hero && ((Hero) ch).heroClass == HeroClass.DUELIST){
|
||||||
|
Buff.affect(ch, Charger.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String defaultAction() {
|
public String defaultAction() {
|
||||||
if (Dungeon.hero != null && Dungeon.hero.heroClass == HeroClass.DUELIST){
|
if (Dungeon.hero != null && Dungeon.hero.heroClass == HeroClass.DUELIST){
|
||||||
return AC_ABILITY;
|
return AC_ABILITY;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return super.defaultAction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,19 +68,68 @@ public class MeleeWeapon extends Weapon {
|
|||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String actionName(String action, Hero hero) {
|
||||||
|
if (action.equals(AC_ABILITY)){
|
||||||
|
return Messages.upperCase(Messages.get(this, "ability_name"));
|
||||||
|
} else {
|
||||||
|
return super.actionName(action, hero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Hero hero, String action) {
|
public void execute(Hero hero, String action) {
|
||||||
super.execute(hero, action);
|
super.execute(hero, action);
|
||||||
|
|
||||||
if (action.equals(AC_ABILITY)){
|
if (action.equals(AC_ABILITY)){
|
||||||
if (!isEquipped(hero)){
|
if (!isEquipped(hero)) {
|
||||||
GLog.w("Need to Equip!");
|
GLog.w(Messages.get(this, "ability_equip"));
|
||||||
|
} else if (Buff.affect(hero, Charger.class).charge < abilityChargeUse()) {
|
||||||
|
GLog.w(Messages.get(this, "ability_charge"));
|
||||||
} else {
|
} else {
|
||||||
GLog.i("Weapon Ability TODO");
|
|
||||||
|
if (targetingPrompt() == null){
|
||||||
|
Buff.affect(hero, Charger.class).charge -= abilityChargeUse();
|
||||||
|
duelistAbility(hero, hero.pos);
|
||||||
|
updateQuickslot();
|
||||||
|
} else {
|
||||||
|
usesTargeting = useTargeting();
|
||||||
|
GameScene.selectCell(new CellSelector.Listener() {
|
||||||
|
@Override
|
||||||
|
public void onSelect(Integer cell) {
|
||||||
|
if (cell != null) {
|
||||||
|
Buff.affect(hero, Charger.class).charge -= abilityChargeUse();
|
||||||
|
duelistAbility(hero, cell);
|
||||||
|
updateQuickslot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String prompt() {
|
||||||
|
return targetingPrompt();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//leave null for no targeting
|
||||||
|
public String targetingPrompt(){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean useTargeting(){
|
||||||
|
return targetingPrompt() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO make abstract
|
||||||
|
protected void duelistAbility( Hero hero, Integer target ){}
|
||||||
|
|
||||||
|
public float abilityChargeUse(){
|
||||||
|
return 33f; //TODO
|
||||||
|
}
|
||||||
|
|
||||||
public int tier;
|
public int tier;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -147,6 +210,11 @@ public class MeleeWeapon extends Weapon {
|
|||||||
info += "\n\n" + Messages.get(Weapon.class, "not_cursed");
|
info += "\n\n" + Messages.get(Weapon.class, "not_cursed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Dungeon.hero.heroClass == HeroClass.DUELIST){
|
||||||
|
info += "\n\n" + Messages.get(this, "ability_desc");
|
||||||
|
info += " " + Messages.get(MeleeWeapon.class, "charge_use", new DecimalFormat("#.##").format(abilityChargeUse()));
|
||||||
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@@ -154,7 +222,17 @@ public class MeleeWeapon extends Weapon {
|
|||||||
public String statsInfo(){
|
public String statsInfo(){
|
||||||
return Messages.get(this, "stats_desc");
|
return Messages.get(this, "stats_desc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String status() {
|
||||||
|
if (isEquipped(Dungeon.hero)
|
||||||
|
&& Dungeon.hero.buff(Charger.class) != null) {
|
||||||
|
return Messages.format( "%.0f%%", Math.floor(Dungeon.hero.buff(Charger.class).charge) );
|
||||||
|
} else {
|
||||||
|
return super.status();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int value() {
|
public int value() {
|
||||||
int price = 20 * tier;
|
int price = 20 * tier;
|
||||||
@@ -173,4 +251,40 @@ public class MeleeWeapon extends Weapon {
|
|||||||
return price;
|
return price;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Charger extends Buff {
|
||||||
|
|
||||||
|
public float charge;
|
||||||
|
//offhand charge as well?
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean act() {
|
||||||
|
LockedFloor lock = target.buff(LockedFloor.class);
|
||||||
|
if (lock == null || lock.regenOn()) {
|
||||||
|
charge += 100 / 300f; //300 turns to full charge
|
||||||
|
updateQuickslot();
|
||||||
|
if (charge > 100) {
|
||||||
|
charge = 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spend(TICK);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static final String CHARGE = "charge";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeInBundle(Bundle bundle) {
|
||||||
|
super.storeInBundle(bundle);
|
||||||
|
bundle.put(CHARGE, charge);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreFromBundle(Bundle bundle) {
|
||||||
|
super.restoreFromBundle(bundle);
|
||||||
|
charge = bundle.getFloat(CHARGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee;
|
|||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||||
|
|
||||||
public class Rapier extends MeleeWeapon {
|
public class Rapier extends MeleeWeapon {
|
||||||
@@ -50,4 +51,8 @@ public class Rapier extends MeleeWeapon {
|
|||||||
return 1; //1 extra defence
|
return 1; //1 extra defence
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String targetingPrompt() {
|
||||||
|
return Messages.get(this, "prompt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,4 +191,12 @@ public class Messages {
|
|||||||
//Otherwise, use sentence case
|
//Otherwise, use sentence case
|
||||||
return capitalize(str);
|
return capitalize(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String upperCase( String str ){
|
||||||
|
return str.toUpperCase(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String lowerCase( String str ){
|
||||||
|
return str.toLowerCase(locale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user