diff --git a/SPD-classes/src/main/java/com/watabou/gltextures/SmartTexture.java b/SPD-classes/src/main/java/com/watabou/gltextures/SmartTexture.java index dab0dfdd4..067440b94 100644 --- a/SPD-classes/src/main/java/com/watabou/gltextures/SmartTexture.java +++ b/SPD-classes/src/main/java/com/watabou/gltextures/SmartTexture.java @@ -40,6 +40,14 @@ public class SmartTexture extends Texture { public Bitmap bitmap; public Atlas atlas; + + protected SmartTexture( ) { + super(); + //useful for subclasses which want to manage their own texture data + // in cases where android.graphics.bitmap isn't fast enough. + + //subclasses which use this MUST also override reload() + } public SmartTexture( Bitmap bitmap ) { this( bitmap, NEAREST, CLAMP, false ); @@ -92,8 +100,9 @@ public class SmartTexture extends Texture { public void delete() { super.delete(); - - bitmap.recycle(); + + if (bitmap != null) + bitmap.recycle(); bitmap = null; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java index a0c143384..b728e6f63 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java @@ -23,7 +23,9 @@ package com.shatteredpixel.shatteredpixeldungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Awareness; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Light; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MindVision; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith; @@ -656,8 +658,12 @@ public class Dungeon { Rankings.INSTANCE.submit( true, cause ); } + + public static void observe(){ + observe( hero.viewDistance+1 ); + } - public static void observe() { + public static void observe( int dist ) { if (level == null) { return; @@ -668,19 +674,22 @@ public class Dungeon { int cx = hero.pos % level.width(); int cy = hero.pos / level.width(); - //Add one to account for hero's previous position - int viewDist = hero.viewDistance+1; - int ax = Math.max( 0, cx - viewDist ); - int bx = Math.min( cx + viewDist, level.width() - 1 ); - int ay = Math.max( 0, cy - viewDist ); - int by = Math.min( cy + viewDist, level.height() - 1 ); + int ax = Math.max( 0, cx - dist ); + int bx = Math.min( cx + dist, level.width() - 1 ); + int ay = Math.max( 0, cy - dist ); + int by = Math.min( cy + dist, level.height() - 1 ); int len = bx - ax + 1; int pos = ax + ay * level.width(); for (int y = ay; y <= by; y++, pos+=level.width()) { BArray.or( level.visited, visible, pos, len, level.visited ); } - + + if (hero.buff(MindVision.class) != null || hero.buff(Awareness.class) != null) + GameScene.updateFog(); + else + GameScene.updateFog(ax, ay, len, by-ay); + GameScene.afterObserve(); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/FogOfWar.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/FogOfWar.java index bf0d5be71..9589cf963 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/FogOfWar.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/FogOfWar.java @@ -20,14 +20,17 @@ */ package com.shatteredpixel.shatteredpixeldungeon; -import android.graphics.Bitmap; -import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import android.opengl.GLES20; + import com.watabou.gltextures.SmartTexture; import com.watabou.gltextures.TextureCache; import com.watabou.glwrap.Texture; import com.watabou.noosa.Image; +import com.watabou.utils.Rect; -import java.util.Arrays; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; public class FogOfWar extends Image { @@ -36,13 +39,13 @@ public class FogOfWar extends Image { private static final int MAPPED = 0xcc442211; private static final int INVISIBLE = 0xFF000000; - private int[] pixels; - private int pWidth; private int pHeight; private int width2; private int height2; + + public Rect updated; public FogOfWar( int mapWidth, int mapHeight ) { @@ -65,59 +68,129 @@ public class FogOfWar extends Image { width = width2 * size; height = height2 * size; - texture( new FogTexture() ); + texture( new FogTexture(width2, height2) ); scale.set( DungeonTilemap.SIZE, DungeonTilemap.SIZE ); x = y = -size / 2; + + updated = new Rect(0, 0, pWidth, pHeight); } public void updateVisibility( boolean[] visible, boolean[] visited, boolean[] mapped ) { - - if (pixels == null) { - pixels = new int[width2 * height2]; - Arrays.fill( pixels, INVISIBLE ); - } - - for (int i=1; i < pHeight - 1; i++) { - int pos = (pWidth - 1) * i; - for (int j=1; j < pWidth - 1; j++) { - pos++; - int c = INVISIBLE; - if (visible[pos] && visible[pos - (pWidth - 1)] && - visible[pos - 1] && visible[pos - (pWidth - 1) - 1]) { - c = VISIBLE; + + if (updated.isEmpty()) + return; + + FogTexture fog = (FogTexture)texture; + + for (int i=updated.top; i < updated.bottom; i++) { + int cell = (pWidth - 1) * i + updated.left; + fog.pixels.position((width2) * i + updated.left); + for (int j=updated.left; j < updated.right; j++) { + if (cell < pWidth || cell >= Dungeon.level.length()) { + fog.pixels.put(INVISIBLE); } else - if (visited[pos] && visited[pos - (pWidth - 1)] && - visited[pos - 1] && visited[pos - (pWidth - 1) - 1]) { - c = VISITED; + if (visible[cell] && visible[cell - (pWidth - 1)] && + visible[cell - 1] && visible[cell - (pWidth - 1) - 1]) { + fog.pixels.put(VISIBLE); + } else + if (visited[cell] && visited[cell - (pWidth - 1)] && + visited[cell - 1] && visited[cell - (pWidth - 1) - 1]) { + fog.pixels.put(VISITED); } else - if (mapped[pos] && mapped[pos - (pWidth - 1)] && - mapped[pos - 1] && mapped[pos - (pWidth - 1) - 1]) { - c = MAPPED; + if (mapped[cell] && mapped[cell - (pWidth - 1)] && + mapped[cell - 1] && mapped[cell - (pWidth - 1) - 1]) { + fog.pixels.put(MAPPED); + } else { + fog.pixels.put(INVISIBLE); } - pixels[i * width2 + j] = c; + cell++; } } - - texture.pixels( width2, height2, pixels ); + + if (updated.width() == pWidth && updated.height() == pHeight) + fog.update(); + else + fog.update(updated.top, updated.bottom); + updated.setEmpty(); + } - + + //provides a native intbuffer implementation because android.graphics.bitmap is too slow + //TODO perhaps should spin this off into something like FastEditTexture in SPD-classes private class FogTexture extends SmartTexture { + + private IntBuffer pixels; - public FogTexture() { - super( Bitmap.createBitmap( width2, height2, Bitmap.Config.ARGB_8888 ) ); + public FogTexture(int w, int h) { + super(); + width = w; + height = h; + pixels = ByteBuffer. + allocateDirect( w * h * 4 ). + order( ByteOrder.nativeOrder() ). + asIntBuffer(); + filter( Texture.LINEAR, Texture.LINEAR ); TextureCache.add( FogOfWar.class, this ); } @Override public void reload() { - super.reload(); - GameScene.afterObserve(); + int[] ids = new int[1]; + GLES20.glGenTextures( 1, ids, 0 ); + id = ids[0]; + filter( Texture.LINEAR, Texture.LINEAR ); + update(); + } + + public void update(){ + bind(); + pixels.position(0); + GLES20.glTexImage2D( + GLES20.GL_TEXTURE_2D, + 0, + GLES20.GL_RGBA, + width, + height, + 0, + GLES20.GL_RGBA, + GLES20.GL_UNSIGNED_BYTE, + pixels ); + } + + //allows partially updating the texture + public void update(int top, int bottom){ + bind(); + pixels.position(top*width); + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, + 0, + 0, + top, + width, + bottom - top, + GLES20.GL_RGBA, + GLES20.GL_UNSIGNED_BYTE, + pixels); + } + + @Override + public void delete() { + super.delete(); } } + + @Override + public void draw() { + + if (!updated.isEmpty()){ + updateVisibility(Dungeon.visible, Dungeon.level.visited, Dungeon.level.mapped); + } + + super.draw(); + } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Awareness.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Awareness.java index c8a7a2663..009437f80 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Awareness.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Awareness.java @@ -21,6 +21,7 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.buffs; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; public class Awareness extends FlavourBuff { @@ -30,5 +31,6 @@ public class Awareness extends FlavourBuff { public void detach() { super.detach(); Dungeon.observe(); + GameScene.updateFog(); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Light.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Light.java index 762757dd8..cdc87b2a0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Light.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Light.java @@ -47,7 +47,7 @@ public class Light extends FlavourBuff { @Override public void detach() { target.viewDistance = Dungeon.level.viewDistance; - Dungeon.observe(); + Dungeon.observe(DISTANCE+1); super.detach(); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/MindVision.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/MindVision.java index 62de752df..f867d2b02 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/MindVision.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/MindVision.java @@ -22,6 +22,7 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.buffs; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; public class MindVision extends FlavourBuff { @@ -48,6 +49,7 @@ public class MindVision extends FlavourBuff { public void detach() { super.detach(); Dungeon.observe(); + GameScene.updateFog(); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Guard.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Guard.java index cba4a508d..e1da91f2e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Guard.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Guard.java @@ -33,6 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.GuardSprite; import com.watabou.utils.Bundle; import com.watabou.utils.Callback; @@ -117,6 +118,7 @@ public class Guard extends Mob { if (enemy == Dungeon.hero) { Dungeon.hero.interrupt(); Dungeon.observe(); + GameScene.updateFog(); } } }), -1); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/Swap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/Swap.java index 461b8723c..b59dbc58e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/Swap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/Swap.java @@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; import com.watabou.noosa.Game; import com.watabou.noosa.Visual; @@ -92,6 +93,7 @@ public class Swap extends Actor { if (ch1 == Dungeon.hero || ch2 == Dungeon.hero) { Dungeon.observe(); + GameScene.updateFog(); } } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/RogueArmor.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/RogueArmor.java index 113facf0e..c917973c5 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/RogueArmor.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/RogueArmor.java @@ -77,6 +77,7 @@ public class RogueArmor extends ClassArmor { Sample.INSTANCE.play( Assets.SND_PUFF ); Dungeon.level.press( target, curUser ); Dungeon.observe(); + GameScene.updateFog(); curUser.spendAndNext( Actor.TICK ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/WarriorArmor.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/WarriorArmor.java index 83f161234..b769f1a9d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/WarriorArmor.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/WarriorArmor.java @@ -75,6 +75,7 @@ public class WarriorArmor extends ClassArmor { curUser.move(dest); Dungeon.level.press(dest, curUser); Dungeon.observe(); + GameScene.updateFog(); for (int i = 0; i < PathFinder.NEIGHBOURS8.length; i++) { Char mob = Actor.findChar(curUser.pos + PathFinder.NEIGHBOURS8[i]); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/EtherealChains.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/EtherealChains.java index d309a551c..2f250a41a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/EtherealChains.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/EtherealChains.java @@ -141,6 +141,7 @@ public class EtherealChains extends Artifact { })); affected.pos = newMobPos; Dungeon.observe(); + GameScene.updateFog(); curUser.spendAndNext(1f); } })); @@ -178,6 +179,7 @@ public class EtherealChains extends Artifact { curUser.spendAndNext(1f); curUser.pos = newHeroPos; Dungeon.observe(); + GameScene.updateFog(); } })); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/LloydsBeacon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/LloydsBeacon.java index 5bd09478d..aee49d1ec 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/LloydsBeacon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/LloydsBeacon.java @@ -160,6 +160,7 @@ public class LloydsBeacon extends Artifact { ScrollOfTeleportation.appear( hero, returnPos ); Dungeon.level.press( returnPos, hero ); Dungeon.observe(); + GameScene.updateFog(); } else { Buff buff = Dungeon.hero.buff(TimekeepersHourglass.timeFreeze.class); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfMagicMapping.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfMagicMapping.java index 8eef0c1ec..182094cf9 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfMagicMapping.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfMagicMapping.java @@ -69,7 +69,7 @@ public class ScrollOfMagicMapping extends Scroll { } } } - Dungeon.observe(); + GameScene.updateFog(); GLog.i( Messages.get(this, "layout") ); if (noticed) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfTeleportation.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfTeleportation.java index ff4f037de..a5b0182d3 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfTeleportation.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfTeleportation.java @@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.noosa.audio.Sample; import com.watabou.noosa.tweeners.AlphaTweener; @@ -69,6 +70,7 @@ public class ScrollOfTeleportation extends Scroll { appear( hero, pos ); Dungeon.level.press( pos, hero ); Dungeon.observe(); + GameScene.updateFog(); GLog.i( Messages.get(ScrollOfTeleportation.class, "tele") ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfPrismaticLight.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfPrismaticLight.java index 08348a2c7..a94c059db 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfPrismaticLight.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfPrismaticLight.java @@ -125,7 +125,7 @@ public class WandOfPrismaticLight extends DamageWand { if (noticed) Sample.INSTANCE.play( Assets.SND_SECRET ); - Dungeon.observe(); + GameScene.updateFog(); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisarmingTrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisarmingTrap.java index 851e34ecb..2ead3209d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisarmingTrap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisarmingTrap.java @@ -31,6 +31,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.KindOfWeapon; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Knuckles; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.TrapSprite; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.noosa.audio.Sample; @@ -55,7 +56,7 @@ public class DisarmingTrap extends Trap{ Dungeon.level.drop( item, cell ).seen = true; for (int i : PathFinder.NEIGHBOURS9) Dungeon.level.visited[cell+i] = true; - Dungeon.observe(); + GameScene.updateFog(); Sample.INSTANCE.play(Assets.SND_TELEPORT); CellEmitter.get(pos).burst(Speck.factory(Speck.LIGHT), 4); @@ -77,7 +78,7 @@ public class DisarmingTrap extends Trap{ Dungeon.level.drop(weapon, cell).seen = true; for (int i : PathFinder.NEIGHBOURS9) Dungeon.level.visited[cell+i] = true; - Dungeon.observe(); + GameScene.updateFog(); GLog.w( Messages.get(this, "disarm") ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java index fc59dc874..b203e96d8 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java @@ -409,7 +409,7 @@ public class GameScene extends PixelScene { super.update(); if (!freezeEmitters) water.offset( 0, -5 * Game.elapsed ); - + Actor.process(); if (Dungeon.hero.ready && Dungeon.hero.paralysed == 0) { @@ -665,8 +665,8 @@ public class GameScene extends PixelScene { public static void resetMap() { if (scene != null) { scene.tiles.map(Dungeon.level.map, Dungeon.level.width() ); - } + updateFog(); } public static void updateMap() { @@ -691,11 +691,21 @@ public class GameScene extends PixelScene { cancelCellSelector(); scene.addToFront( wnd ); } + + public static void updateFog(){ + if (scene != null) + scene.fog.updated.set(0, 0, Dungeon.level.width()+1, Dungeon.level.height()+1); + } + + public static void updateFog(int x, int y, int w, int h){ + if (scene != null) { + scene.fog.updated.union(x, y); + scene.fog.updated.union(x + w, y + h); + } + } public static void afterObserve() { if (scene != null) { - scene.fog.updateVisibility( Dungeon.visible, Dungeon.level.visited, Dungeon.level.mapped ); - for (Mob mob : Dungeon.level.mobs) { mob.sprite.visible = Dungeon.visible[mob.pos]; }