v0.8.1: reworked wand of regrowth!
This commit is contained in:
parent
c4ffb9b82a
commit
f5cba1a9ba
|
@ -1206,11 +1206,13 @@ items.wands.wandofprismaticlight.stats_desc=This wand shoots rays of light which
|
|||
items.wands.wandofregrowth.name=wand of regrowth
|
||||
items.wands.wandofregrowth.staff_name=staff of regrowth
|
||||
items.wands.wandofregrowth.desc=This wand is made from a thin shaft of expertly carved wood. Somehow it is still alive and vibrant, bright green like a young tree's core.
|
||||
items.wands.wandofregrowth.stats_desc=When used, this wand will consume all its charges to blast magical regrowth energy outward in a cone. This magic will cause grass, roots, and rare plants to spring to life. "When life ceases new life always begins to grow... The eternal cycle always remains!"
|
||||
items.wands.wandofregrowth.stats_desc=When used, this wand will blast magical regrowth energy outward in a cone, causing grass, roots, and rare plants to spring to life. As this wand is upgraded it will consume more charges, the effect becomes significantly more powerful the more charges are consumed. Its next zap will consume _%1$d charges_. "When life ceases new life always begins to grow... The eternal cycle always remains!"
|
||||
items.wands.wandofregrowth$dewcatcher.name=Dewcatcher
|
||||
items.wands.wandofregrowth$dewcatcher.desc=Dewcatchers camouflage as grass to avoid attention, but their bulges of collected dew give them away.
|
||||
items.wands.wandofregrowth$dewcatcher.desc=Dewcatchers are wonderous plants that fill themselves with magical dew. They attempt to camouflage as grass to avoid attention, but their bulges of collected dew give them away.
|
||||
items.wands.wandofregrowth$seedpod.name=Seed Pod
|
||||
items.wands.wandofregrowth$seedpod.desc=Seed Pods look pretty, but the seeds they carry are actually stolen from other plants they kill with their roots.
|
||||
items.wands.wandofregrowth$seedpod.desc=Seed Pods are magical plants that produce seeds from other plan types, rather than any seeds of their own. They somehow manage to spread despite having no seed of their own.
|
||||
items.wands.wandofregrowth$lotus.name=Golden Lotus
|
||||
items.wands.wandofregrowth$lotus.desc=The golden lotus is a mystical plant that can only be conjured by a powerful wand of regrowth. Its aura enhances all plants and plant effects, but it burns through its energy and dies after a short time.\n\nThis lotus was produced by a _+%1$d_ wand of regrowth. All plants in its effect will _instantly trigger_ if they are planted on a character. Plants will also have a _%2$d%% chance_ to drop their seed, and tipped darts gain _%3$d%% extra durability_.
|
||||
|
||||
items.wands.wandoftransfusion.name=wand of transfusion
|
||||
items.wands.wandoftransfusion.staff_name=staff of transfusion
|
||||
|
|
BIN
core/src/main/assets/sprites/lotus.png
Normal file
BIN
core/src/main/assets/sprites/lotus.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.0 KiB |
|
@ -267,5 +267,6 @@ public class Assets {
|
|||
public static final String DM100 = "sprites/dm100.png";
|
||||
public static final String PYLON = "sprites/pylon.png";
|
||||
public static final String DM200 = "sprites/dm200.png";
|
||||
public static final String LOTUS = "sprites/lotus.png";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,10 @@ 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.actors.blobs.Blob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Regrowth;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Roots;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.NPC;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Dewdrop;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
||||
|
@ -35,10 +37,12 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.ConeAOE;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.plants.Starflower;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.LotusSprite;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.Callback;
|
||||
|
@ -47,7 +51,6 @@ import com.watabou.utils.PathFinder;
|
|||
import com.watabou.utils.Random;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class WandOfRegrowth extends Wand {
|
||||
|
@ -58,138 +61,136 @@ public class WandOfRegrowth extends Wand {
|
|||
collisionProperties = Ballistica.STOP_TERRAIN;
|
||||
}
|
||||
|
||||
//the actual affected cells
|
||||
private HashSet<Integer> affectedCells;
|
||||
//the cells to trace growth particles to, for visual effects.
|
||||
private HashSet<Integer> visualCells;
|
||||
private int direction = 0;
|
||||
|
||||
private int totChrgUsed = 0;
|
||||
|
||||
ConeAOE cone;
|
||||
int target;
|
||||
|
||||
@Override
|
||||
public boolean tryToZap(Hero owner, int target) {
|
||||
if (super.tryToZap(owner, target)){
|
||||
this.target = target;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onZap( Ballistica bolt ) {
|
||||
|
||||
//ignore tiles which can't have anything grow in them.
|
||||
for (Iterator<Integer> i = affectedCells.iterator(); i.hasNext();) {
|
||||
int c = Dungeon.level.map[i.next()];
|
||||
if (!(c == Terrain.EMPTY ||
|
||||
c == Terrain.EMBERS ||
|
||||
c == Terrain.EMPTY_DECO ||
|
||||
c == Terrain.GRASS ||
|
||||
c == Terrain.HIGH_GRASS ||
|
||||
c == Terrain.FURROWED_GRASS)) {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
|
||||
float numPlants, numDews, numPods, numStars;
|
||||
ArrayList<Integer> cells = new ArrayList<>(cone.cells);
|
||||
|
||||
int overLimit = totChrgUsed - chargeLimit(Dungeon.hero.lvl);
|
||||
float furrowedChance = overLimit > 0 ? (overLimit / (10f + Dungeon.hero.lvl)) : 0;
|
||||
|
||||
int chrgUsed = chargesPerCast();
|
||||
//numbers greater than n*100% means n guaranteed plants, e.g. 210% = 2 plants w/10% chance for 3 plants.
|
||||
numPlants = 0.2f + chrgUsed*chrgUsed*0.020f; //scales from 22% to 220%
|
||||
numDews = 0.05f + chrgUsed*chrgUsed*0.016f; //scales from 6.6% to 165%
|
||||
numPods = 0.02f + chrgUsed*chrgUsed*0.013f; //scales from 3.3% to 135%
|
||||
numStars = (chrgUsed*chrgUsed*chrgUsed/5f)*0.005f; //scales from 0.1% to 100%
|
||||
int grassToPlace = Math.round((3.5f+buffedLvl()/2f)*chrgUsed);
|
||||
|
||||
if (overLimit > 0){
|
||||
numPlants -= overLimit*0.02f;
|
||||
numDews -= overLimit*0.02f;
|
||||
numPods -= overLimit*0.02f;
|
||||
numStars -= overLimit*0.02f;
|
||||
}
|
||||
|
||||
placePlants(numPlants, numDews, numPods, numStars);
|
||||
|
||||
for (int i : affectedCells){
|
||||
int c = Dungeon.level.map[i];
|
||||
if (c == Terrain.EMPTY ||
|
||||
c == Terrain.EMBERS ||
|
||||
c == Terrain.EMPTY_DECO) {
|
||||
Level.set( i, Terrain.GRASS );
|
||||
}
|
||||
|
||||
Char ch = Actor.findChar(i);
|
||||
if (ch != null){
|
||||
processSoulMark(ch, chargesPerCast());
|
||||
}
|
||||
|
||||
if (Random.Int(50) < overLimit) {
|
||||
if (Dungeon.level.map[i] == Terrain.GRASS) {
|
||||
Level.set( i, Terrain.FURROWED_GRASS );
|
||||
GameScene.updateMap( i );
|
||||
}
|
||||
GameScene.add(Blob.seed(i, 9, Regrowth.class));
|
||||
//ignore cells which can't have anything grow in them.
|
||||
for (Iterator<Integer> i = cells.iterator(); i.hasNext();) {
|
||||
int cell = i.next();
|
||||
int terr = Dungeon.level.map[cell];
|
||||
if (!(terr == Terrain.EMPTY ||
|
||||
terr == Terrain.EMBERS ||
|
||||
terr == Terrain.EMPTY_DECO ||
|
||||
terr == Terrain.GRASS ||
|
||||
terr == Terrain.HIGH_GRASS ||
|
||||
terr == Terrain.FURROWED_GRASS)) {
|
||||
i.remove();
|
||||
} else {
|
||||
GameScene.add(Blob.seed(i, 10, Regrowth.class));
|
||||
Level.set( cell, Terrain.GRASS );
|
||||
GameScene.updateMap( cell );
|
||||
Char ch = Actor.findChar(cell);
|
||||
if (ch != null){
|
||||
processSoulMark(ch, chargesPerCast());
|
||||
Buff.prolong( ch, Roots.class, 4f * chrgUsed );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
totChrgUsed += chrgUsed;
|
||||
Random.shuffle(cells);
|
||||
|
||||
if (chargesPerCast() >= 3){
|
||||
Lotus l = new Lotus();
|
||||
l.setLevel(buffedLvl());
|
||||
if (cells.contains(target)){
|
||||
cells.remove((Integer)target);
|
||||
l.pos = target;
|
||||
GameScene.add(l);
|
||||
} else {
|
||||
for (int i = bolt.path.size()-1; i >= 0; i--){
|
||||
if (cells.contains(bolt.path.get(i))){
|
||||
cells.remove((Integer)bolt.path.get(i));
|
||||
l.pos = bolt.path.get(i);
|
||||
GameScene.add(l);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//places grass along center of cone
|
||||
for (int cell : bolt.path){
|
||||
if (grassToPlace > 0 && cells.contains(cell)){
|
||||
if (Random.Float() > furrowedChance) {
|
||||
Level.set(cell, Terrain.HIGH_GRASS);
|
||||
} else {
|
||||
Level.set(cell, Terrain.FURROWED_GRASS);
|
||||
}
|
||||
GameScene.updateMap( cell );
|
||||
grassToPlace--;
|
||||
//moves cell to the back
|
||||
cells.remove((Integer)cell);
|
||||
cells.add(cell);
|
||||
}
|
||||
}
|
||||
|
||||
if (!cells.isEmpty() && Random.Float() > furrowedChance &&
|
||||
(chrgUsed == 3 || (chrgUsed == 2 && Random.Int(2) == 0))){
|
||||
int cell = cells.remove(0);
|
||||
Dungeon.level.plant( Random.Int(2) == 0 ? new Seedpod.Seed() : new Dewcatcher.Seed(), cell);
|
||||
}
|
||||
|
||||
if (!cells.isEmpty() && Random.Float() > furrowedChance && chrgUsed == 3){
|
||||
int cell = cells.remove(0);
|
||||
Dungeon.level.plant((Plant.Seed) Generator.randomUsingDefaults(Generator.Category.SEED), cell);
|
||||
}
|
||||
|
||||
if (!cells.isEmpty() && Random.Float() > furrowedChance &&
|
||||
(chrgUsed >= 2 || (chrgUsed == 1 && Random.Int(2) == 0))){
|
||||
int cell = cells.remove(0);
|
||||
Dungeon.level.plant((Plant.Seed) Generator.randomUsingDefaults(Generator.Category.SEED), cell);
|
||||
}
|
||||
|
||||
for (int cell : cells){
|
||||
if (grassToPlace <= 0 || bolt.path.contains(cell)) break;
|
||||
|
||||
if (Random.Float() > furrowedChance) {
|
||||
Level.set(cell, Terrain.HIGH_GRASS);
|
||||
} else {
|
||||
Level.set(cell, Terrain.FURROWED_GRASS);
|
||||
}
|
||||
GameScene.updateMap( cell );
|
||||
grassToPlace--;
|
||||
}
|
||||
|
||||
if (furrowedChance < 1f) {
|
||||
totChrgUsed += chrgUsed;
|
||||
}
|
||||
}
|
||||
|
||||
private int chargeLimit( int heroLevel ){
|
||||
if (level() >= 12){
|
||||
private int chargeLimit( int heroLvl ){
|
||||
if (level() >= 10){
|
||||
return Integer.MAX_VALUE;
|
||||
} else {
|
||||
//4 charges per hero level at +0, with another 2-4 each upgrade from +1 to +9.
|
||||
//then +7 at +10, +16 at +11, and infinite at +12.
|
||||
return Math.round(((4 + 2*level())*heroLevel) * (11f/12f + 1f/(12f-level())));
|
||||
//8 charges at base, plus:
|
||||
//2/3.33/5/7/10/14/20/30/50/110/infinite charges per hero level, based on wand level
|
||||
float lvl = buffedLvl();
|
||||
return Math.round(8 + heroLvl * (2+lvl) * (1f + (lvl/(10 - lvl))));
|
||||
}
|
||||
}
|
||||
|
||||
private void spreadRegrowth(int cell, float strength){
|
||||
if (strength >= 0 && Dungeon.level.passable[cell]){
|
||||
affectedCells.add(cell);
|
||||
if (strength >= 1.5f) {
|
||||
spreadRegrowth(cell + PathFinder.CIRCLE8[left(direction)], strength - 1.5f);
|
||||
spreadRegrowth(cell + PathFinder.CIRCLE8[direction], strength - 1.5f);
|
||||
spreadRegrowth(cell + PathFinder.CIRCLE8[right(direction)], strength-1.5f);
|
||||
} else {
|
||||
visualCells.add(cell);
|
||||
}
|
||||
} else if (!Dungeon.level.passable[cell])
|
||||
visualCells.add(cell);
|
||||
}
|
||||
|
||||
private void placePlants(float numPlants, float numDews, float numPods, float numStars){
|
||||
Iterator<Integer> cells = affectedCells.iterator();
|
||||
Level floor = Dungeon.level;
|
||||
|
||||
while(cells.hasNext() && Random.Float() <= numPlants){
|
||||
Plant.Seed seed = (Plant.Seed) Generator.randomUsingDefaults(Generator.Category.SEED);
|
||||
floor.plant(seed, cells.next());
|
||||
|
||||
numPlants --;
|
||||
}
|
||||
|
||||
while (cells.hasNext() && Random.Float() <= numDews){
|
||||
floor.plant(new Dewcatcher.Seed(), cells.next());
|
||||
numDews --;
|
||||
}
|
||||
|
||||
while (cells.hasNext() && Random.Float() <= numPods){
|
||||
floor.plant(new Seedpod.Seed(), cells.next());
|
||||
numPods --;
|
||||
}
|
||||
|
||||
while (cells.hasNext() && Random.Float() <= numStars){
|
||||
floor.plant(new Starflower.Seed(), cells.next());
|
||||
numStars --;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int left(int direction){
|
||||
return direction == 0 ? 7 : direction-1;
|
||||
}
|
||||
|
||||
private int right(int direction){
|
||||
return direction == 7 ? 0 : direction+1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHit(MagesStaff staff, Char attacker, Char defender, int damage) {
|
||||
new Blooming().proc(staff, attacker, defender, damage);
|
||||
|
@ -197,62 +198,43 @@ public class WandOfRegrowth extends Wand {
|
|||
|
||||
protected void fx( Ballistica bolt, Callback callback ) {
|
||||
|
||||
affectedCells = new HashSet<>();
|
||||
visualCells = new HashSet<>();
|
||||
|
||||
int maxDist = Math.round(1.2f + chargesPerCast()*.8f);
|
||||
// 4/6/8 distance
|
||||
int maxDist = 2 + 2*chargesPerCast();
|
||||
int dist = Math.min(bolt.dist, maxDist);
|
||||
|
||||
for (int i = 0; i < PathFinder.CIRCLE8.length; i++){
|
||||
if (bolt.sourcePos+PathFinder.CIRCLE8[i] == bolt.path.get(1)){
|
||||
direction = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cone = new ConeAOE( bolt.sourcePos, bolt.path.get(dist),
|
||||
maxDist,
|
||||
20 + 10*chargesPerCast(),
|
||||
collisionProperties | Ballistica.STOP_TARGET);
|
||||
|
||||
float strength = maxDist;
|
||||
for (int c : bolt.subPath(1, dist)) {
|
||||
strength--; //as we start at dist 1, not 0.
|
||||
if (Dungeon.level.passable[c]) {
|
||||
affectedCells.add(c);
|
||||
spreadRegrowth(c + PathFinder.CIRCLE8[left(direction)], strength - 1);
|
||||
spreadRegrowth(c + PathFinder.CIRCLE8[direction], strength - 1);
|
||||
spreadRegrowth(c + PathFinder.CIRCLE8[right(direction)], strength - 1);
|
||||
} else {
|
||||
visualCells.add(c);
|
||||
}
|
||||
}
|
||||
|
||||
//going to call this one manually
|
||||
visualCells.remove(bolt.path.get(dist));
|
||||
|
||||
for (int cell : visualCells){
|
||||
//this way we only get the cells at the tip, much better performance.
|
||||
//cast to cells at the tip, rather than all cells, better performance.
|
||||
for (Ballistica ray : cone.rays){
|
||||
((MagicMissile)curUser.sprite.parent.recycle( MagicMissile.class )).reset(
|
||||
MagicMissile.FOLIAGE_CONE,
|
||||
curUser.sprite,
|
||||
cell,
|
||||
ray.path.get(ray.dist),
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
//final zap at half distance, for timing of the actual wand effect
|
||||
MagicMissile.boltFromChar( curUser.sprite.parent,
|
||||
MagicMissile.FOLIAGE_CONE,
|
||||
curUser.sprite,
|
||||
bolt.path.get(dist/2),
|
||||
callback );
|
||||
|
||||
Sample.INSTANCE.play( Assets.Sounds.ZAP );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int initialCharges() {
|
||||
return 1;
|
||||
protected int chargesPerCast() {
|
||||
//consumes 30% of current charges, rounded up, with a minimum of one.
|
||||
return Math.max(1, (int)Math.ceil(curCharges*0.3f));
|
||||
}
|
||||
|
||||
@Override
|
||||
//consumes all available charges, needs at least one.
|
||||
protected int chargesPerCast() {
|
||||
return Math.max(1, curCharges);
|
||||
public String statsDesc() {
|
||||
return Messages.get(this, "stats_desc", chargesPerCast());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -354,4 +336,89 @@ public class WandOfRegrowth extends Wand {
|
|||
|
||||
}
|
||||
|
||||
public static class Lotus extends NPC {
|
||||
|
||||
{
|
||||
alignment = Alignment.ALLY;
|
||||
properties.add(Property.IMMOVABLE);
|
||||
|
||||
spriteClass = LotusSprite.class;
|
||||
|
||||
viewDistance = 1;
|
||||
}
|
||||
|
||||
private int wandLvl = 0;
|
||||
|
||||
private void setLevel( int lvl ){
|
||||
wandLvl = lvl;
|
||||
HP = HT = lvl*4;
|
||||
}
|
||||
|
||||
public boolean inRange(int pos){
|
||||
return Dungeon.level.trueDistance(this.pos, pos) <= wandLvl;
|
||||
}
|
||||
|
||||
public float seedPreservation(){
|
||||
return 0.25f + 0.05f*wandLvl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteract(Char c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean act() {
|
||||
super.act();
|
||||
throwItem();
|
||||
|
||||
if (--HP <= 0){
|
||||
destroy();
|
||||
sprite.die();
|
||||
}
|
||||
|
||||
spend(TICK);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damage( int dmg, Object src ) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add( Buff buff ) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
Dungeon.observe();
|
||||
GameScene.updateFog(pos, viewDistance+1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInvulnerable(Class effect) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return Messages.get(this, "desc", wandLvl, (int)(seedPreservation()*100), (int)(seedPreservation()*100) );
|
||||
}
|
||||
|
||||
private static final String WAND_LVL = "wand_lvl";
|
||||
|
||||
@Override
|
||||
public void storeInBundle(Bundle bundle) {
|
||||
super.storeInBundle(bundle);
|
||||
bundle.put(WAND_LVL, wandLvl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle(Bundle bundle) {
|
||||
super.restoreFromBundle(bundle);
|
||||
wandLvl = bundle.getInt(WAND_LVL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,12 +22,14 @@
|
|||
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.darts;
|
||||
|
||||
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.actors.buffs.PinCushion;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfRegrowth;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.plants.Blindweed;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.plants.Dreamfoil;
|
||||
|
@ -105,6 +107,7 @@ public abstract class TippedDart extends Dart {
|
|||
|
||||
@Override
|
||||
protected void rangedHit(Char enemy, int cell) {
|
||||
targetPos = cell;
|
||||
super.rangedHit( enemy, cell);
|
||||
|
||||
//need to spawn a dart
|
||||
|
@ -122,6 +125,8 @@ public abstract class TippedDart extends Dart {
|
|||
}
|
||||
}
|
||||
|
||||
private static int targetPos = -1;
|
||||
|
||||
@Override
|
||||
protected float durabilityPerUse() {
|
||||
float use = super.durabilityPerUse();
|
||||
|
@ -130,6 +135,30 @@ public abstract class TippedDart extends Dart {
|
|||
use /= 2f;
|
||||
}
|
||||
|
||||
//checks both destination and source position
|
||||
float lotusPreserve = 0f;
|
||||
if (targetPos != -1){
|
||||
for (Char ch : Actor.chars()){
|
||||
if (ch instanceof WandOfRegrowth.Lotus){
|
||||
WandOfRegrowth.Lotus l = (WandOfRegrowth.Lotus) ch;
|
||||
if (l.inRange(targetPos)){
|
||||
lotusPreserve = Math.max(lotusPreserve, l.seedPreservation());
|
||||
}
|
||||
}
|
||||
}
|
||||
targetPos = -1;
|
||||
}
|
||||
int p = curUser == null ? Dungeon.hero.pos : curUser.pos;
|
||||
for (Char ch : Actor.chars()){
|
||||
if (ch instanceof WandOfRegrowth.Lotus){
|
||||
WandOfRegrowth.Lotus l = (WandOfRegrowth.Lotus) ch;
|
||||
if (l.inRange(p)){
|
||||
lotusPreserve = Math.max(lotusPreserve, l.seedPreservation());
|
||||
}
|
||||
}
|
||||
}
|
||||
use *= (1f - lotusPreserve);
|
||||
|
||||
return use;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfStrength;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfEnchantment;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfIntuition;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfRegrowth;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfWarding;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Door;
|
||||
|
@ -792,6 +793,15 @@ public abstract class Level implements Bundlable {
|
|||
|
||||
GameScene.plantSeed( pos );
|
||||
|
||||
for (Char ch : Actor.chars()){
|
||||
if (ch instanceof WandOfRegrowth.Lotus
|
||||
&& ((WandOfRegrowth.Lotus) ch).inRange(pos)
|
||||
&& Actor.findChar(pos) != null){
|
||||
plant.trigger();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return plant;
|
||||
}
|
||||
|
||||
|
@ -1100,19 +1110,19 @@ public abstract class Level implements Bundlable {
|
|||
fieldOfView[p+i] = true;
|
||||
}
|
||||
|
||||
for (Mob ward : mobs){
|
||||
if (ward instanceof WandOfWarding.Ward){
|
||||
if (ward.fieldOfView == null || ward.fieldOfView.length != length()){
|
||||
ward.fieldOfView = new boolean[length()];
|
||||
Dungeon.level.updateFieldOfView( ward, ward.fieldOfView );
|
||||
for (Mob m : mobs){
|
||||
if (m instanceof WandOfWarding.Ward || m instanceof WandOfRegrowth.Lotus){
|
||||
if (m.fieldOfView == null || m.fieldOfView.length != length()){
|
||||
m.fieldOfView = new boolean[length()];
|
||||
Dungeon.level.updateFieldOfView( m, m.fieldOfView );
|
||||
}
|
||||
for (Mob m : mobs){
|
||||
if (ward.fieldOfView[m.pos] && !fieldOfView[m.pos] &&
|
||||
!Dungeon.hero.mindVisionEnemies.contains(m)){
|
||||
Dungeon.hero.mindVisionEnemies.add(m);
|
||||
for (Mob m1 : mobs){
|
||||
if (m.fieldOfView[m1.pos] && !fieldOfView[m1.pos] &&
|
||||
!Dungeon.hero.mindVisionEnemies.contains(m1)){
|
||||
Dungeon.hero.mindVisionEnemies.add(m1);
|
||||
}
|
||||
}
|
||||
BArray.or(fieldOfView, ward.fieldOfView, fieldOfView);
|
||||
BArray.or(fieldOfView, m.fieldOfView, fieldOfView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ public class Blindweed extends Plant {
|
|||
|
||||
{
|
||||
image = 11;
|
||||
seedClass = Seed.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -37,6 +37,7 @@ public class Dreamfoil extends Plant {
|
|||
|
||||
{
|
||||
image = 7;
|
||||
seedClass = Seed.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -40,6 +40,7 @@ public class Earthroot extends Plant {
|
|||
|
||||
{
|
||||
image = 8;
|
||||
seedClass = Seed.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -41,6 +41,7 @@ public class Fadeleaf extends Plant {
|
|||
|
||||
{
|
||||
image = 10;
|
||||
seedClass = Seed.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -38,6 +38,7 @@ public class Firebloom extends Plant {
|
|||
|
||||
{
|
||||
image = 1;
|
||||
seedClass = Seed.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -37,6 +37,7 @@ public class Icecap extends Plant {
|
|||
|
||||
{
|
||||
image = 4;
|
||||
seedClass = Seed.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,6 +31,7 @@ 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.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfRegrowth;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
|
@ -40,6 +41,7 @@ import com.watabou.noosa.audio.Sample;
|
|||
import com.watabou.utils.Bundlable;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.PathFinder;
|
||||
import com.watabou.utils.Random;
|
||||
import com.watabou.utils.Reflection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -51,6 +53,8 @@ public abstract class Plant implements Bundlable {
|
|||
public int image;
|
||||
public int pos;
|
||||
|
||||
protected Class<? extends Plant.Seed> seedClass;
|
||||
|
||||
public void trigger(){
|
||||
|
||||
Char ch = Actor.findChar(pos);
|
||||
|
@ -72,6 +76,22 @@ public abstract class Plant implements Bundlable {
|
|||
CellEmitter.get( pos ).burst( LeafParticle.GENERAL, 6 );
|
||||
}
|
||||
|
||||
float seedChance = 0f;
|
||||
for (Char c : Actor.chars()){
|
||||
if (c instanceof WandOfRegrowth.Lotus){
|
||||
WandOfRegrowth.Lotus l = (WandOfRegrowth.Lotus) c;
|
||||
if (l.inRange(pos)){
|
||||
seedChance = Math.max(seedChance, l.seedPreservation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Random.Float() < seedChance){
|
||||
if (seedClass != null && seedClass != Rotberry.Seed.class) {
|
||||
Dungeon.level.drop(Reflection.newInstance(seedClass), pos).sprite.drop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final String POS = "pos";
|
||||
|
|
|
@ -35,6 +35,7 @@ public class Rotberry extends Plant {
|
|||
|
||||
{
|
||||
image = 0;
|
||||
seedClass = Seed.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -36,6 +36,7 @@ public class Sorrowmoss extends Plant {
|
|||
|
||||
{
|
||||
image = 6;
|
||||
seedClass = Seed.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -35,6 +35,7 @@ public class Starflower extends Plant {
|
|||
|
||||
{
|
||||
image = 9;
|
||||
seedClass = Seed.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,6 +33,7 @@ public class Stormvine extends Plant {
|
|||
|
||||
{
|
||||
image = 5;
|
||||
seedClass = Seed.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -41,6 +41,7 @@ public class Sungrass extends Plant {
|
|||
|
||||
{
|
||||
image = 3;
|
||||
seedClass = Seed.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,6 +42,7 @@ public class Swiftthistle extends Plant {
|
|||
|
||||
{
|
||||
image = 2;
|
||||
seedClass = Seed.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2020 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.sprites;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.LeafParticle;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfRegrowth;
|
||||
import com.watabou.noosa.MovieClip;
|
||||
import com.watabou.noosa.TextureFilm;
|
||||
import com.watabou.noosa.particles.Emitter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
//TODO implement on WIP sprite
|
||||
public class LotusSprite extends MobSprite {
|
||||
|
||||
private ArrayList<Emitter> grassVfx;
|
||||
|
||||
public LotusSprite(){
|
||||
super();
|
||||
|
||||
perspectiveRaise = 0.2f;
|
||||
|
||||
texture( Assets.Sprites.LOTUS );
|
||||
|
||||
TextureFilm frames = new TextureFilm( texture, 17, 14 );
|
||||
|
||||
idle = new MovieClip.Animation( 1, true );
|
||||
idle.frames( frames, 0 );
|
||||
|
||||
run = new MovieClip.Animation( 1, true );
|
||||
run.frames( frames, 0 );
|
||||
|
||||
attack = new MovieClip.Animation( 1, false );
|
||||
attack.frames( frames, 0 );
|
||||
|
||||
die = new MovieClip.Animation( 1, false );
|
||||
die.frames( frames, 0 );
|
||||
|
||||
play( idle );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void link( Char ch ) {
|
||||
super.link( ch );
|
||||
|
||||
renderShadow = false;
|
||||
|
||||
if (grassVfx == null && ch instanceof WandOfRegrowth.Lotus){
|
||||
WandOfRegrowth.Lotus l = (WandOfRegrowth.Lotus) ch;
|
||||
grassVfx = new ArrayList<>();
|
||||
for (int i = 0; i < Dungeon.level.length(); i++){
|
||||
if (!Dungeon.level.solid[i] && l.inRange(i)) {
|
||||
Emitter e = CellEmitter.get(i);
|
||||
e.pour(LeafParticle.LEVEL_SPECIFIC, 0.5f);
|
||||
grassVfx.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void turnTo(int from, int to) {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
visible = true;
|
||||
super.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void die() {
|
||||
super.die();
|
||||
|
||||
if (grassVfx != null){
|
||||
for (Emitter e : grassVfx){
|
||||
e.on = false;
|
||||
}
|
||||
grassVfx = null;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user