v0.8.1: reworked talisman of foresight
This commit is contained in:
parent
0e7ba4e567
commit
d22d78255f
|
@ -373,14 +373,14 @@ items.artifacts.sandalsofnature.desc_seeds=You have fed the footwear %d seeds.
|
|||
|
||||
items.artifacts.talismanofforesight.name=talisman of foresight
|
||||
items.artifacts.talismanofforesight.ac_scry=SCRY
|
||||
items.artifacts.talismanofforesight.no_charge=Your talisman isn't fully charged yet.
|
||||
items.artifacts.talismanofforesight.scry=The Talisman floods your mind with knowledge about the current floor.
|
||||
items.artifacts.talismanofforesight.desc=A smooth stone with strange engravings on it. You feel like it's watching everything around you, keeping an eye out for anything unusual.
|
||||
items.artifacts.talismanofforesight.desc_worn=When you hold the talisman you feel like your senses are heightened.
|
||||
items.artifacts.talismanofforesight.desc_cursed=The cursed talisman is intently staring into you, making it impossible to concentrate.
|
||||
items.artifacts.talismanofforesight.low_charge=The talisman requires at least 5% charge to scry.
|
||||
items.artifacts.talismanofforesight.prompt=Choose a location to scan.
|
||||
items.artifacts.talismanofforesight.levelup=Your Talisman grows stronger!
|
||||
items.artifacts.talismanofforesight.full_charge=Your Talisman is fully charged!
|
||||
items.artifacts.talismanofforesight.desc=A smooth stone with strange engravings on it. You feel like it's watching everything around you, keeping an eye out for anything hidden.
|
||||
items.artifacts.talismanofforesight.desc_worn=When you hold the talisman you feel like your senses are heightened. The talisman is slowly building charge as time passes and when you discover hidden doors or traps.\n\nThe talisman can expend its charge to 'scry' in a cone shape, which reveals all tiles and secrets in the scanned area, and will grant you vision of enemies and items for a short time.
|
||||
items.artifacts.talismanofforesight.desc_cursed=The cursed talisman is intently staring into you, dulling your senses.
|
||||
items.artifacts.talismanofforesight$foresight.name=Foresight
|
||||
items.artifacts.talismanofforesight$foresight.levelup=Your Talisman grows stronger!
|
||||
items.artifacts.talismanofforesight$foresight.full_charge=Your Talisman is fully charged!
|
||||
items.artifacts.talismanofforesight$foresight.uneasy=You feel uneasy.
|
||||
items.artifacts.talismanofforesight$foresight.desc=You feel very nervous, as if there is nearby unseen danger.
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Ankh;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TalismanOfForesight;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
|
||||
|
@ -799,6 +800,22 @@ public class Dungeon {
|
|||
}
|
||||
}
|
||||
|
||||
for (TalismanOfForesight.CharAwareness c : hero.buffs(TalismanOfForesight.CharAwareness.class)){
|
||||
Char ch = (Char) Actor.findById(c.charID);
|
||||
if (ch == null) continue;
|
||||
BArray.or( level.visited, level.heroFOV, ch.pos - 1 - level.width(), 3, level.visited );
|
||||
BArray.or( level.visited, level.heroFOV, ch.pos - 1, 3, level.visited );
|
||||
BArray.or( level.visited, level.heroFOV, ch.pos - 1 + level.width(), 3, level.visited );
|
||||
GameScene.updateFog(ch.pos, 2);
|
||||
}
|
||||
|
||||
for (TalismanOfForesight.HeapAwareness h : hero.buffs(TalismanOfForesight.HeapAwareness.class)){
|
||||
BArray.or( level.visited, level.heroFOV, h.pos - 1 - level.width(), 3, level.visited );
|
||||
BArray.or( level.visited, level.heroFOV, h.pos - 1, 3, level.visited );
|
||||
BArray.or( level.visited, level.heroFOV, h.pos - 1 + level.width(), 3, level.visited );
|
||||
GameScene.updateFog(h.pos, 2);
|
||||
}
|
||||
|
||||
GameScene.afterObserve();
|
||||
}
|
||||
|
||||
|
|
|
@ -1764,8 +1764,13 @@ public class Hero extends Char {
|
|||
|
||||
smthFound = true;
|
||||
|
||||
if (talisman != null && !talisman.isCursed())
|
||||
talisman.charge();
|
||||
if (talisman != null){
|
||||
if (oldValue == Terrain.SECRET_TRAP){
|
||||
talisman.charge(2);
|
||||
} else if (oldValue == Terrain.SECRET_DOOR){
|
||||
talisman.charge(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,12 +23,20 @@ package com.shatteredpixel.shatteredpixeldungeon.items.artifacts;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Awareness;
|
||||
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.FlavourBuff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CheckedCell;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfMagicMapping;
|
||||
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.scenes.CellSelector;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
|
||||
|
@ -58,8 +66,7 @@ public class TalismanOfForesight extends Artifact {
|
|||
@Override
|
||||
public ArrayList<String> actions( Hero hero ) {
|
||||
ArrayList<String> actions = super.actions( hero );
|
||||
if (isEquipped( hero ) && charge == chargeCap && !cursed)
|
||||
actions.add(AC_SCRY);
|
||||
if (isEquipped( hero ) && !cursed) actions.add(AC_SCRY);
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
@ -68,34 +75,9 @@ public class TalismanOfForesight extends Artifact {
|
|||
super.execute(hero, action);
|
||||
|
||||
if (action.equals(AC_SCRY)){
|
||||
|
||||
if (!isEquipped(hero)) GLog.i( Messages.get(Artifact.class, "need_to_equip") );
|
||||
else if (charge != chargeCap) GLog.i( Messages.get(this, "no_charge") );
|
||||
else {
|
||||
hero.sprite.operate(hero.pos);
|
||||
hero.busy();
|
||||
Sample.INSTANCE.play(Assets.Sounds.BEACON);
|
||||
charge = 0;
|
||||
for (int i = 0; i < Dungeon.level.length(); i++) {
|
||||
|
||||
int terr = Dungeon.level.map[i];
|
||||
if ((Terrain.flags[terr] & Terrain.SECRET) != 0) {
|
||||
|
||||
GameScene.updateMap(i);
|
||||
|
||||
if (Dungeon.level.heroFOV[i]) {
|
||||
GameScene.discoverTile(i, terr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLog.p( Messages.get(this, "scry") );
|
||||
|
||||
updateQuickslot();
|
||||
|
||||
Buff.affect(hero, Awareness.class, Awareness.DURATION);
|
||||
Dungeon.observe();
|
||||
}
|
||||
if (!isEquipped(hero)) GLog.i( Messages.get(Artifact.class, "need_to_equip") );
|
||||
else if (charge < 5) GLog.i( Messages.get(this, "low_charge") );
|
||||
else GameScene.selectCell(scry);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +89,7 @@ public class TalismanOfForesight extends Artifact {
|
|||
@Override
|
||||
public void charge(Hero target) {
|
||||
if (charge < chargeCap){
|
||||
charge += 4f;
|
||||
charge += 2f;
|
||||
if (charge >= chargeCap) {
|
||||
charge = chargeCap;
|
||||
partialCharge = 0;
|
||||
|
@ -131,7 +113,119 @@ public class TalismanOfForesight extends Artifact {
|
|||
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
||||
private float maxDist(){
|
||||
return Math.min(5 + 2*level(), (charge-3)/0.88f);
|
||||
}
|
||||
|
||||
private CellSelector.Listener scry = new CellSelector.Listener(){
|
||||
|
||||
@Override
|
||||
public void onSelect(Integer target) {
|
||||
if (target != null && target != curUser.pos){
|
||||
|
||||
//enforces at least 2 tiles of distance
|
||||
if (Dungeon.level.adjacent(target, curUser.pos)){
|
||||
target += (target - curUser.pos);
|
||||
}
|
||||
|
||||
float dist = Dungeon.level.trueDistance(curUser.pos, target);
|
||||
|
||||
if (dist >= 3 && dist > maxDist()){
|
||||
Ballistica trajectory = new Ballistica(curUser.pos, target, Ballistica.STOP_TARGET);
|
||||
int i = 0;
|
||||
while (i < trajectory.path.size()
|
||||
&& Dungeon.level.trueDistance(curUser.pos, trajectory.path.get(i)) <= maxDist()){
|
||||
target = trajectory.path.get(i);
|
||||
i++;
|
||||
}
|
||||
dist = Dungeon.level.trueDistance(curUser.pos, target);
|
||||
}
|
||||
|
||||
//starts at 200 degrees, loses 8% per tile of distance
|
||||
float angle = Math.round(200*(float)Math.pow(0.92, dist));
|
||||
ConeAOE cone = new ConeAOE(curUser.pos, target, angle);
|
||||
|
||||
int earnedExp = 0;
|
||||
boolean noticed = false;
|
||||
for (int cell : cone.cells){
|
||||
GameScene.effectOverFog(new CheckedCell( cell, curUser.pos ));
|
||||
if (Dungeon.level.discoverable[cell] && !(Dungeon.level.mapped[cell] || Dungeon.level.visited[cell])){
|
||||
Dungeon.level.mapped[cell] = true;
|
||||
earnedExp++;
|
||||
}
|
||||
|
||||
if (Dungeon.level.secret[cell]) {
|
||||
Dungeon.level.discover(cell);
|
||||
|
||||
if (Dungeon.level.heroFOV[cell]) {
|
||||
int oldValue = Dungeon.level.map[cell];
|
||||
GameScene.discoverTile(cell, Dungeon.level.map[cell]);
|
||||
Dungeon.level.discover( cell );
|
||||
ScrollOfMagicMapping.discover(cell);
|
||||
noticed = true;
|
||||
|
||||
if (oldValue == Terrain.SECRET_TRAP){
|
||||
earnedExp += 10;
|
||||
} else if (oldValue == Terrain.SECRET_DOOR){
|
||||
earnedExp += 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Char ch = Actor.findChar(cell);
|
||||
if (ch != null && ch.alignment != Char.Alignment.NEUTRAL && ch.alignment != curUser.alignment){
|
||||
Buff.append(curUser, CharAwareness.class, 5 + 2*level()).charID = ch.id();
|
||||
|
||||
if (!curUser.fieldOfView[ch.pos]){
|
||||
earnedExp += 10;
|
||||
}
|
||||
}
|
||||
|
||||
Heap h = Dungeon.level.heaps.get(cell);
|
||||
if (h != null){
|
||||
Buff.append(curUser, HeapAwareness.class, 5 + 2*level()).pos = h.pos;
|
||||
|
||||
if (!h.seen){
|
||||
earnedExp += 10;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exp += earnedExp;
|
||||
if (exp >= 100 + 50*level() && level() < levelCap) {
|
||||
exp -= 100 + 50*level();
|
||||
upgrade();
|
||||
GLog.p( Messages.get(TalismanOfForesight.class, "levelup") );
|
||||
}
|
||||
updateQuickslot();
|
||||
|
||||
charge -= 3 + dist*0.88f;
|
||||
partialCharge -= (dist*0.88f)%1f;
|
||||
if (partialCharge < 0 && charge > 0){
|
||||
partialCharge ++;
|
||||
charge --;
|
||||
}
|
||||
updateQuickslot();
|
||||
Dungeon.observe();
|
||||
Dungeon.hero.checkVisibleMobs();
|
||||
GameScene.updateFog();
|
||||
|
||||
curUser.sprite.zap(target);
|
||||
Sample.INSTANCE.play(Assets.Sounds.TELEPORT);
|
||||
if (noticed) Sample.INSTANCE.play(Assets.Sounds.SECRET);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String prompt() {
|
||||
return Messages.get(TalismanOfForesight.class, "prompt");
|
||||
}
|
||||
};
|
||||
|
||||
private static final String WARN = "warn";
|
||||
|
||||
@Override
|
||||
|
@ -143,10 +237,10 @@ public class TalismanOfForesight extends Artifact {
|
|||
@Override
|
||||
public void restoreFromBundle(Bundle bundle) {
|
||||
super.restoreFromBundle(bundle);
|
||||
warn = bundle.getInt(WARN);
|
||||
warn = bundle.getBoolean(WARN);
|
||||
}
|
||||
|
||||
private int warn = 0;
|
||||
private boolean warn = false;
|
||||
|
||||
public class Foresight extends ArtifactBuff{
|
||||
|
||||
|
@ -191,23 +285,21 @@ public class TalismanOfForesight extends Artifact {
|
|||
}
|
||||
|
||||
if (smthFound && !cursed){
|
||||
if (warn == 0){
|
||||
if (!warn){
|
||||
GLog.w( Messages.get(this, "uneasy") );
|
||||
if (target instanceof Hero){
|
||||
((Hero)target).interrupt();
|
||||
}
|
||||
warn = true;
|
||||
}
|
||||
warn = 3;
|
||||
} else {
|
||||
if (warn > 0){
|
||||
warn --;
|
||||
}
|
||||
warn = false;
|
||||
}
|
||||
|
||||
//fully charges in 2000 turns at lvl=0, scaling to 667 turns at lvl = 10.
|
||||
//fully charges in 2000 turns at lvl=0, scaling to 1000 turns at lvl = 10.
|
||||
LockedFloor lock = target.buff(LockedFloor.class);
|
||||
if (charge < chargeCap && !cursed && (lock == null || lock.regenOn())) {
|
||||
partialCharge += 0.05+(level()*0.01);
|
||||
partialCharge += 0.05f+(level()*0.005f);
|
||||
|
||||
if (partialCharge > 1 && charge < chargeCap) {
|
||||
partialCharge--;
|
||||
|
@ -215,22 +307,15 @@ public class TalismanOfForesight extends Artifact {
|
|||
updateQuickslot();
|
||||
} else if (charge >= chargeCap) {
|
||||
partialCharge = 0;
|
||||
GLog.p( Messages.get(this, "full_charge") );
|
||||
GLog.p( Messages.get(TalismanOfForesight.class, "full_charge") );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void charge(){
|
||||
charge = Math.min(charge+(2+(level()/3)), chargeCap);
|
||||
exp++;
|
||||
if (exp >= 4 && level() < levelCap) {
|
||||
upgrade();
|
||||
GLog.p( Messages.get(this, "levelup") );
|
||||
exp -= 4;
|
||||
}
|
||||
updateQuickslot();
|
||||
public void charge(int boost){
|
||||
charge = Math.min((charge+boost), chargeCap);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -245,10 +330,64 @@ public class TalismanOfForesight extends Artifact {
|
|||
|
||||
@Override
|
||||
public int icon() {
|
||||
if (warn == 0)
|
||||
return BuffIndicator.NONE;
|
||||
else
|
||||
if (warn)
|
||||
return BuffIndicator.FORESIGHT;
|
||||
else
|
||||
return BuffIndicator.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CharAwareness extends FlavourBuff {
|
||||
|
||||
public int charID;
|
||||
|
||||
private static final String ID = "id";
|
||||
|
||||
@Override
|
||||
public void detach() {
|
||||
super.detach();
|
||||
Dungeon.observe();
|
||||
GameScene.updateFog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle(Bundle bundle) {
|
||||
super.restoreFromBundle(bundle);
|
||||
charID = bundle.getInt(ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeInBundle(Bundle bundle) {
|
||||
super.storeInBundle(bundle);
|
||||
bundle.put(ID, charID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class HeapAwareness extends FlavourBuff {
|
||||
|
||||
public int pos;
|
||||
|
||||
private static final String POS = "pos";
|
||||
|
||||
@Override
|
||||
public void detach() {
|
||||
super.detach();
|
||||
Dungeon.observe();
|
||||
GameScene.updateFog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle(Bundle bundle) {
|
||||
super.restoreFromBundle(bundle);
|
||||
pos = bundle.getInt(POS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeInBundle(Bundle bundle) {
|
||||
super.storeInBundle(bundle);
|
||||
bundle.put(POS, pos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Stylus;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Torch;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TalismanOfForesight;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourglass;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.food.SmallRation;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfStrength;
|
||||
|
@ -1082,6 +1083,23 @@ public abstract class Level implements Bundlable {
|
|||
}
|
||||
}
|
||||
|
||||
for (TalismanOfForesight.CharAwareness a : c.buffs(TalismanOfForesight.CharAwareness.class)){
|
||||
Char ch = (Char) Actor.findById(a.charID);
|
||||
if (ch == null) {
|
||||
a.detach();
|
||||
continue;
|
||||
}
|
||||
int p = ch.pos;
|
||||
for (int i : PathFinder.NEIGHBOURS9)
|
||||
fieldOfView[p+i] = true;
|
||||
}
|
||||
|
||||
for (TalismanOfForesight.HeapAwareness h : c.buffs(TalismanOfForesight.HeapAwareness.class)){
|
||||
int p = h.pos;
|
||||
for (int i : PathFinder.NEIGHBOURS9)
|
||||
fieldOfView[p+i] = true;
|
||||
}
|
||||
|
||||
for (Mob ward : mobs){
|
||||
if (ward instanceof WandOfWarding.Ward){
|
||||
if (ward.fieldOfView == null || ward.fieldOfView.length != length()){
|
||||
|
|
Loading…
Reference in New Issue
Block a user