v1.1.0: overhauled search code and scroll of foresight

This commit is contained in:
Evan Debenham 2021-09-19 22:26:22 -04:00
parent a6bfe99b1f
commit dcbc12ae98
4 changed files with 72 additions and 40 deletions

View File

@ -159,7 +159,7 @@ actors.buffs.fireimbue.name=Imbued with Fire
actors.buffs.fireimbue.desc=You are imbued with the power of fire!\n\nAll physical attacks will have a chance to light enemies ablaze. Additionally, you are completely immune to the effects of fire.\n\nTurns of fire imbue remaining: %s. actors.buffs.fireimbue.desc=You are imbued with the power of fire!\n\nAll physical attacks will have a chance to light enemies ablaze. Additionally, you are completely immune to the effects of fire.\n\nTurns of fire imbue remaining: %s.
actors.buffs.foresight.name=Foresight actors.buffs.foresight.name=Foresight
actors.buffs.foresight.desc=Your senses are heightened, allowing you to immediately notice anything out of place.\n\nWhile under the effect of foresight your search radius is increased, and anything that enters your search radius is immediately discovered.\n\nTurns of foresight remaining: %s. actors.buffs.foresight.desc=You are somehow able to see the layout of surrounding terrain with your mind.\n\nWhile under the effect of foresight all tiles in a wide radius are revealed to you, including any secret traps or doors.\n\nTurns of foresight remaining: %s.
actors.buffs.frost.name=Frozen actors.buffs.frost.name=Frozen
actors.buffs.frost.freezes=%s freezes! actors.buffs.frost.freezes=%s freezes!

View File

@ -988,7 +988,7 @@ items.scrolls.exotic.scrollofenchantment.cancel=cancel
items.scrolls.exotic.scrollofenchantment.desc=This scroll will infuse a weapon or armor with powerful magical energy. The reader even has some degree of control over which magic is imbued. items.scrolls.exotic.scrollofenchantment.desc=This scroll will infuse a weapon or armor with powerful magical energy. The reader even has some degree of control over which magic is imbued.
items.scrolls.exotic.scrollofforesight.name=scroll of foresight items.scrolls.exotic.scrollofforesight.name=scroll of foresight
items.scrolls.exotic.scrollofforesight.desc=When this scroll is read, the detail of nearby terrain will be constantly fed to the reader's mind in crystal clarity. For the duration of this effect, searching will not be necessary, as the reader will automatically detect everything within an enhanced search radius. items.scrolls.exotic.scrollofforesight.desc=After reading this scroll, the detail of nearby terrain will be constantly fed to the reader's mind in crystal clarity. This effect lasts for a considerable amount of time, and will reveal all hidden doors or traps, making searching unnecessary.
items.scrolls.exotic.scrollofmysticalenergy.name=scroll of mystical energy items.scrolls.exotic.scrollofmysticalenergy.name=scroll of mystical energy
items.scrolls.exotic.scrollofmysticalenergy.desc=The raw magical power bound up in this parchment will, when released, charge a user's equipped artifacts over time. items.scrolls.exotic.scrollofmysticalenergy.desc=The raw magical power bound up in this parchment will, when released, charge a user's equipped artifacts over time.

View File

@ -21,12 +21,16 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.buffs; package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
public class Foresight extends FlavourBuff { public class Foresight extends FlavourBuff {
public static final float DURATION = 600f; public static final float DURATION = 250f;
public static final int DISTANCE = 8;
{ {
type = buffType.POSITIVE; type = buffType.POSITIVE;
@ -38,6 +42,20 @@ public class Foresight extends FlavourBuff {
return BuffIndicator.FORESIGHT; return BuffIndicator.FORESIGHT;
} }
@Override
public boolean attachTo(Char target) {
if (super.attachTo(target)){
//this way we get a nice VFX sweep on initial activation
if (target == Dungeon.hero){
Dungeon.level.mapped[target.pos] = false;
Dungeon.hero.search(false);
}
return true;
} else {
return false;
}
}
@Override @Override
public float iconFadePercent() { public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION); return Math.max(0, (DURATION - visualcooldown()) / DURATION);

View File

@ -140,6 +140,7 @@ import com.watabou.utils.Bundle;
import com.watabou.utils.Callback; import com.watabou.utils.Callback;
import com.watabou.utils.GameMath; import com.watabou.utils.GameMath;
import com.watabou.utils.PathFinder; import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
import com.watabou.utils.Random; import com.watabou.utils.Random;
import java.util.ArrayList; import java.util.ArrayList;
@ -1872,47 +1873,57 @@ public class Hero extends Char {
if (hasTalent(Talent.WIDE_SEARCH)) distance++; if (hasTalent(Talent.WIDE_SEARCH)) distance++;
boolean foresight = buff(Foresight.class) != null; boolean foresight = buff(Foresight.class) != null;
boolean foresightScan = foresight && !Dungeon.level.mapped[pos];
if (foresight) distance++;
if (foresightScan){
int cx = pos % Dungeon.level.width(); Dungeon.level.mapped[pos] = true;
int cy = pos / Dungeon.level.width();
int ax = cx - distance;
if (ax < 0) {
ax = 0;
} }
int bx = cx + distance;
if (bx >= Dungeon.level.width()) { if (foresight) {
bx = Dungeon.level.width() - 1; distance = Foresight.DISTANCE;
} circular = true;
int ay = cy - distance;
if (ay < 0) {
ay = 0;
}
int by = cy + distance;
if (by >= Dungeon.level.height()) {
by = Dungeon.level.height() - 1;
} }
Point c = Dungeon.level.cellToPoint(pos);
TalismanOfForesight.Foresight talisman = buff( TalismanOfForesight.Foresight.class ); TalismanOfForesight.Foresight talisman = buff( TalismanOfForesight.Foresight.class );
boolean cursed = talisman != null && talisman.isCursed(); boolean cursed = talisman != null && talisman.isCursed();
for (int y = ay; y <= by; y++) {
for (int x = ax, p = ax + y * Dungeon.level.width(); x <= bx; x++, p++) {
if (circular && Math.abs(x - cx)-1 > ShadowCaster.rounding[distance][distance - Math.abs(y - cy)]){ int[] rounding = ShadowCaster.rounding[distance];
continue;
int left, right;
int curr;
for (int y = Math.max(0, c.y - distance); y <= Math.min(Dungeon.level.height()-1, c.y + distance); y++) {
if (!circular){
left = c.x - distance;
} else if (rounding[Math.abs(c.y - y)] < Math.abs(c.y - y)) {
left = c.x - rounding[Math.abs(c.y - y)];
} else {
left = distance;
while (rounding[left] < rounding[Math.abs(c.y - y)]){
left--;
} }
left = c.x - left;
}
right = Math.min(Dungeon.level.width()-1, c.x + c.x - left);
left = Math.max(0, left);
for (curr = left + y * Dungeon.level.width(); curr <= right + y * Dungeon.level.width(); curr++){
if (fieldOfView[p] && p != pos) { if ((foresight || fieldOfView[curr]) && curr != pos) {
if (intentional) { if ((foresight && (!Dungeon.level.mapped[curr] || foresightScan))){
GameScene.effectOverFog(new CheckedCell(p, pos)); GameScene.effectOverFog(new CheckedCell(curr, foresightScan ? pos : curr));
} else if (intentional) {
GameScene.effectOverFog(new CheckedCell(curr, pos));
}
if (foresight){
Dungeon.level.mapped[curr] = true;
} }
if (Dungeon.level.secret[p]){ if (Dungeon.level.secret[curr]){
Trap trap = Dungeon.level.traps.get( p ); Trap trap = Dungeon.level.traps.get( curr );
float chance; float chance;
//searches aided by foresight always succeed, even if trap isn't searchable //searches aided by foresight always succeed, even if trap isn't searchable
@ -1932,7 +1943,7 @@ public class Hero extends Char {
chance = 0f; chance = 0f;
//unintentional trap detection scales from 40% at floor 0 to 30% at floor 25 //unintentional trap detection scales from 40% at floor 0 to 30% at floor 25
} else if (Dungeon.level.map[p] == Terrain.SECRET_TRAP) { } else if (Dungeon.level.map[curr] == Terrain.SECRET_TRAP) {
chance = 0.4f - (Dungeon.depth / 250f); chance = 0.4f - (Dungeon.depth / 250f);
//unintentional door detection scales from 20% at floor 0 to 0% at floor 20 //unintentional door detection scales from 20% at floor 0 to 0% at floor 20
@ -1942,15 +1953,15 @@ public class Hero extends Char {
if (Random.Float() < chance) { if (Random.Float() < chance) {
int oldValue = Dungeon.level.map[p]; int oldValue = Dungeon.level.map[curr];
GameScene.discoverTile( p, oldValue ); GameScene.discoverTile( curr, oldValue );
Dungeon.level.discover( p ); Dungeon.level.discover( curr );
ScrollOfMagicMapping.discover( p ); ScrollOfMagicMapping.discover( curr );
smthFound = true; if (fieldOfView[curr]) smthFound = true;
if (talisman != null){ if (talisman != null){
if (oldValue == Terrain.SECRET_TRAP){ if (oldValue == Terrain.SECRET_TRAP){
@ -1964,7 +1975,6 @@ public class Hero extends Char {
} }
} }
} }
if (intentional) { if (intentional) {
sprite.showStatus( CharSprite.DEFAULT, Messages.get(this, "search") ); sprite.showStatus( CharSprite.DEFAULT, Messages.get(this, "search") );
@ -1986,6 +1996,10 @@ public class Hero extends Char {
Sample.INSTANCE.play( Assets.Sounds.SECRET ); Sample.INSTANCE.play( Assets.Sounds.SECRET );
interrupt(); interrupt();
} }
if (foresight){
GameScene.updateFog(pos, Foresight.DISTANCE+1);
}
return smthFound; return smthFound;
} }