v0.7.1: implemented simpler benefits for warden and sniper

This commit is contained in:
Evan Debenham 2018-11-28 06:23:52 -05:00
parent 42895419a9
commit 782c5a0dd4
10 changed files with 76 additions and 111 deletions

View File

@ -186,7 +186,8 @@ public abstract class Char extends Actor {
if (this instanceof Hero){
Hero h = (Hero)this;
if (h.belongings.weapon instanceof MissileWeapon
&& h.subClass == HeroSubClass.SNIPER){
&& h.subClass == HeroSubClass.SNIPER
&& !Dungeon.level.adjacent(h.pos, enemy.pos)){
dr = 0;
}
}

View File

@ -61,7 +61,7 @@ public class Barkskin extends Buff {
if (Math.sqrt(interval)*level < Math.sqrt(time)*value) {
level = value;
interval = time;
spend(time - cooldown());
spend(time - cooldown() - 1);
}
}

View File

@ -295,11 +295,9 @@ public class Hero extends Char {
//temporarily set the hero's weapon to the missile weapon being used
KindOfWeapon equipped = belongings.weapon;
belongings.weapon = wep;
rangedAttack = true;
boolean result = attack( enemy );
Invisibility.dispel();
belongings.weapon = equipped;
rangedAttack = false;
return result;
}
@ -311,9 +309,13 @@ public class Hero extends Char {
float accuracy = 1;
accuracy *= RingOfAccuracy.accuracyMultiplier( this );
if (wep instanceof MissileWeapon && rangedAttack
&& Dungeon.level.distance( pos, target.pos ) == 1) {
accuracy *= 0.5f;
if (wep instanceof MissileWeapon){
if (Dungeon.level.adjacent( pos, target.pos )) {
accuracy *= 0.5f;
} else if (subClass == HeroSubClass.SNIPER){
//+10% accuracy per tile of distance
accuracy *= .9f + (.1f * Dungeon.level.distance( pos, target.pos));
}
}
if (wep != null) {
@ -474,7 +476,6 @@ public class Hero extends Char {
//calls to dungeon.observe will also update hero's local FOV.
fieldOfView = Dungeon.level.heroFOV;
if (!ready) {
//do a full observe (including fog update) if not resting.
if (!resting || buff(MindVision.class) != null || buff(Awareness.class) != null) {
@ -498,15 +499,17 @@ public class Hero extends Char {
return false;
}
boolean actResult;
if (curAction == null) {
if (resting) {
spend( TIME_TO_REST ); next();
return false;
spend( TIME_TO_REST );
next();
} else {
ready();
}
ready();
return false;
actResult = false;
} else {
@ -515,58 +518,45 @@ public class Hero extends Char {
ready = false;
if (curAction instanceof HeroAction.Move) {
actResult = actMove( (HeroAction.Move)curAction );
return actMove( (HeroAction.Move)curAction );
} else if (curAction instanceof HeroAction.Interact) {
actResult = actInteract( (HeroAction.Interact)curAction );
} else
if (curAction instanceof HeroAction.Interact) {
} else if (curAction instanceof HeroAction.Buy) {
actResult = actBuy( (HeroAction.Buy)curAction );
return actInteract( (HeroAction.Interact)curAction );
}else if (curAction instanceof HeroAction.PickUp) {
actResult = actPickUp( (HeroAction.PickUp)curAction );
} else
if (curAction instanceof HeroAction.Buy) {
} else if (curAction instanceof HeroAction.OpenChest) {
actResult = actOpenChest( (HeroAction.OpenChest)curAction );
return actBuy( (HeroAction.Buy)curAction );
} else if (curAction instanceof HeroAction.Unlock) {
actResult = actUnlock((HeroAction.Unlock) curAction);
}else
if (curAction instanceof HeroAction.PickUp) {
} else if (curAction instanceof HeroAction.Descend) {
actResult = actDescend( (HeroAction.Descend)curAction );
return actPickUp( (HeroAction.PickUp)curAction );
} else if (curAction instanceof HeroAction.Ascend) {
actResult = actAscend( (HeroAction.Ascend)curAction );
} else
if (curAction instanceof HeroAction.OpenChest) {
} else if (curAction instanceof HeroAction.Attack) {
actResult = actAttack( (HeroAction.Attack)curAction );
return actOpenChest( (HeroAction.OpenChest)curAction );
} else
if (curAction instanceof HeroAction.Unlock) {
return actUnlock((HeroAction.Unlock) curAction);
} else
if (curAction instanceof HeroAction.Descend) {
return actDescend( (HeroAction.Descend)curAction );
} else
if (curAction instanceof HeroAction.Ascend) {
return actAscend( (HeroAction.Ascend)curAction );
} else
if (curAction instanceof HeroAction.Attack) {
return actAttack( (HeroAction.Attack)curAction );
} else
if (curAction instanceof HeroAction.Alchemy) {
return actAlchemy( (HeroAction.Alchemy)curAction );
} else if (curAction instanceof HeroAction.Alchemy) {
actResult = actAlchemy( (HeroAction.Alchemy)curAction );
} else {
actResult = false;
}
}
return false;
if( subClass == HeroSubClass.WARDEN && Dungeon.level.map[pos] == Terrain.FURROWED_GRASS){
Buff.affect(this, Barkskin.class).set( lvl, 1 );
}
return actResult;
}
public void busy() {
@ -937,7 +927,7 @@ public class Hero extends Char {
switch (subClass) {
case SNIPER:
if (wep instanceof MissileWeapon && rangedAttack) {
if (wep instanceof MissileWeapon) {
Buff.prolong( this, SnipersMark.class, attackDelay() ).object = enemy.id();
}
break;

View File

@ -59,7 +59,7 @@ public enum HeroClass {
WARRIOR( "warrior", HeroSubClass.BERSERKER, HeroSubClass.GLADIATOR ),
MAGE( "mage", HeroSubClass.BATTLEMAGE, HeroSubClass.WARLOCK ),
ROGUE( "rogue", HeroSubClass.ASSASSIN, HeroSubClass.FREERUNNER ),
HUNTRESS( "huntress", HeroSubClass.WARDEN, HeroSubClass.SNIPER );
HUNTRESS( "huntress", HeroSubClass.SNIPER, HeroSubClass.WARDEN );
private String title;
private HeroSubClass[] subClasses;

View File

@ -23,7 +23,6 @@ package com.shatteredpixel.shatteredpixeldungeon.items;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
@ -87,15 +86,14 @@ public class DewVial extends Item {
if (volume > 0) {
//20 drops for a full heal normally, 15 for the warden
float dropHealPercent = hero.subClass == HeroSubClass.WARDEN ? 0.0667f : 0.05f;
float missingHealthPercent = 1f - (hero.HP / (float)hero.HT);
//trimming off 0.01 drops helps with floating point errors
int dropsNeeded = (int)Math.ceil((missingHealthPercent / dropHealPercent) - 0.01f);
int dropsNeeded = (int)Math.ceil((missingHealthPercent / 0.05f) - 0.01f);
dropsNeeded = (int)GameMath.gate(1, dropsNeeded, volume);
int heal = Math.round( hero.HT * dropHealPercent * dropsNeeded );
//20 drops for a full heal normally
int heal = Math.round( hero.HT * 0.05f * dropsNeeded );
int effect = Math.min( hero.HT - hero.HP, heal );
if (effect > 0) {

View File

@ -23,7 +23,6 @@ package com.shatteredpixel.shatteredpixeldungeon.items;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
@ -50,9 +49,8 @@ public class Dewdrop extends Item {
} else {
//20 drops for a full heal normally, 15 for the warden
float healthPercent = hero.subClass == HeroSubClass.WARDEN ? 0.0667f : 0.05f;
int heal = Math.round( hero.HT * healthPercent * quantity );
//20 drops for a full heal
int heal = Math.round( hero.HT * 0.05f * quantity );
int effect = Math.min( hero.HT - hero.HP, heal );
if (effect > 0) {

View File

@ -23,11 +23,9 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.features;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barkskin;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.LeafParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.Dewdrop;
@ -91,32 +89,23 @@ public class HighGrass {
}
}
if (ch instanceof Hero) {
Hero hero = (Hero) ch;
//Camouflage
//FIXME doesn't work with sad ghost
if (hero.belongings.armor != null && hero.belongings.armor.hasGlyph(Camouflage.class, hero)) {
Buff.affect(hero, Camouflage.Camo.class).set(3 + hero.belongings.armor.level());
}
}
}
freezeTrample = false;
GameScene.updateMap( pos );
int leaves = 4;
if (ch instanceof Hero) {
Hero hero = (Hero)ch;
// Barkskin
if (hero.subClass == HeroSubClass.WARDEN) {
Buff.affect(ch, Barkskin.class).set(ch.HT / 3, 1);
leaves += 4;
}
//Camouflage
//FIXME doesn't work with sad ghost
if (hero.belongings.armor != null && hero.belongings.armor.hasGlyph(Camouflage.class, hero)){
Buff.affect(hero, Camouflage.Camo.class).set(3 + hero.belongings.armor.level());
leaves += 4;
}
}
CellEmitter.get( pos ).burst( LeafParticle.LEVEL_SPECIFIC, leaves );
CellEmitter.get( pos ).burst( LeafParticle.LEVEL_SPECIFIC, 4 );
if (Dungeon.level.heroFOV[pos]) Dungeon.observe();
}
}

View File

@ -27,24 +27,20 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barkskin;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.LeafParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.Dewdrop;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.SandalsOfNature;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundlable;
import com.watabou.utils.Bundle;
import com.watabou.utils.Random;
import com.watabou.utils.PathFinder;
import java.util.ArrayList;
@ -61,9 +57,6 @@ public abstract class Plant implements Bundlable {
if (ch instanceof Hero){
((Hero) ch).interrupt();
if (((Hero)ch).subClass == HeroSubClass.WARDEN) {
Buff.affect(ch, Barkskin.class).set(ch.HT / 3, 1);
}
}
wither();
@ -79,21 +72,6 @@ public abstract class Plant implements Bundlable {
CellEmitter.get( pos ).burst( LeafParticle.GENERAL, 6 );
}
if (Dungeon.hero.subClass == HeroSubClass.WARDEN) {
int naturalismLevel = 0;
SandalsOfNature.Naturalism naturalism = Dungeon.hero.buff( SandalsOfNature.Naturalism.class );
if (naturalism != null) {
naturalismLevel = naturalism.itemLevel()+1;
}
if (Random.Int( 5 - (naturalismLevel/2) ) == 0) {
Dungeon.level.drop(Generator.random(Generator.Category.SEED), pos).sprite.drop();
}
if (Random.Int( 5 - naturalismLevel ) == 0) {
Dungeon.level.drop( new Dewdrop(), pos ).sprite.drop();
}
}
}
private static final String POS = "pos";
@ -141,6 +119,17 @@ public abstract class Plant implements Bundlable {
super.onThrow( cell );
} else {
Dungeon.level.plant( this, cell );
if (Dungeon.hero.subClass == HeroSubClass.WARDEN) {
for (int i : PathFinder.NEIGHBOURS8) {
int c = Dungeon.level.map[cell + i];
if ( c == Terrain.EMPTY || c == Terrain.EMPTY_DECO
|| c == Terrain.EMBERS || c == Terrain.GRASS){
Level.set(cell + i, Terrain.FURROWED_GRASS);
GameScene.updateMap(cell + i);
CellEmitter.get( cell + i ).burst( LeafParticle.LEVEL_SPECIFIC, 4 );
}
}
}
}
}

View File

@ -333,9 +333,9 @@ actors.hero.herosubclass.assassin_desc=While invisible the _Assassin_ prepares a
actors.hero.herosubclass.freerunner=freerunner
actors.hero.herosubclass.freerunner_desc=The _Freerunner_ builds momentum as he runs. Momentum increases his movement speed and evasion, but it quickly fades when he isn't moving.
actors.hero.herosubclass.sniper=sniper
actors.hero.herosubclass.sniper_desc=The _Sniper_ is able to detect weak points in an enemy's armor, effectively ignoring it when using a thrown weapon.
actors.hero.herosubclass.sniper_desc=The _Sniper_ is a master of ranged combat, with increased vision and bonus accuracy and armor piercing based on attack distance. After striking with a thrown weapon, she can follow up with a special attack from her bow.
actors.hero.herosubclass.warden=warden
actors.hero.herosubclass.warden_desc=Having a strong connection with forces of nature allows the _Warden_ to gain additional health from dew, armor from trampling grass, and seeds and dew from plants.
actors.hero.herosubclass.warden_desc=The _Warden_ has a strong connection to nature which allows her to see through tall grass and command furrowed grass to sprout around plants she grows. Plants she tramples will also give bonus effects, tipped darts will last longer, and grass will give her an armor boost when she stands in it.