v0.7.1: implemented simpler benefits for warden and sniper
This commit is contained in:
parent
42895419a9
commit
782c5a0dd4
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user