diff --git a/core/src/main/assets/plants.png b/core/src/main/assets/plants.png
deleted file mode 100644
index 3ca895faa..000000000
Binary files a/core/src/main/assets/plants.png and /dev/null differ
diff --git a/core/src/main/assets/terrain_features.png b/core/src/main/assets/terrain_features.png
new file mode 100644
index 000000000..a70872c7a
Binary files /dev/null and b/core/src/main/assets/terrain_features.png differ
diff --git a/core/src/main/assets/traps.png b/core/src/main/assets/traps.png
deleted file mode 100644
index 3cfda1376..000000000
Binary files a/core/src/main/assets/traps.png and /dev/null differ
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java
index 79dcae763..9ad977ae9 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java
@@ -97,9 +97,8 @@ public class Assets {
public static final String ROT_HEART= "rot_heart.png";
public static final String GUARD = "guard.png";
- public static final String ITEMS = "items.png";
- public static final String PLANTS = "plants.png";
- public static final String TRAPS = "traps.png";
+ public static final String ITEMS = "items.png";
+ public static final String TERRAIN_FEATURES = "terrain_features.png";
public static final String TILES_SEWERS = "tiles0.png";
public static final String TILES_PRISON = "tiles1.png";
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java
index 5aacac451..0287bb614 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java
@@ -734,19 +734,19 @@ public abstract class Level implements Bundlable {
map[pos] == Terrain.EMPTY_DECO) {
map[pos] = Terrain.GRASS;
flamable[pos] = true;
- GameScene.updateMap( pos );
}
plant = seed.couch( pos );
plants.put( pos, plant );
- GameScene.add( plant );
+ GameScene.updateMap( pos );
return plant;
}
public void uproot( int pos ) {
plants.remove(pos);
+ GameScene.updateMap( pos );
}
public Trap setTrap( Trap trap, int pos ){
@@ -757,7 +757,7 @@ public abstract class Level implements Bundlable {
}
trap.set( pos );
traps.put( pos, trap );
- GameScene.add(trap);
+ GameScene.updateMap( pos );
return trap;
}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java
index b632ef82a..dacab602f 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java
@@ -216,9 +216,6 @@ public class PrisonBossLevel extends Level {
}
private void resetTraps(){
- for (Trap trap : traps.values()){
- trap.sprite.kill();
- }
traps.clear();
for (int i = 0; i < length(); i++){
@@ -273,7 +270,6 @@ public class PrisonBossLevel extends Level {
for (Plant plant : plants.values()){
if (safeArea == null || !safeArea.inside(cellToPoint(plant.pos))){
plants.remove(plant.pos);
- plant.sprite.kill();
}
}
}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/Trap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/Trap.java
index 8eb923a5d..1c6a51903 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/Trap.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/Trap.java
@@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.traps;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
+import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.TrapSprite;
import com.watabou.noosa.audio.Sample;
import com.watabou.noosa.tweeners.AlphaTweener;
@@ -54,6 +55,7 @@ public abstract class Trap implements Bundlable {
sprite.alpha( 0 );
sprite.parent.add( new AlphaTweener( sprite, 1, 0.6f));
}
+ GameScene.updateMap(pos);
return this;
}
@@ -61,6 +63,7 @@ public abstract class Trap implements Bundlable {
visible = false;
if (sprite != null)
sprite.visible = false;
+ GameScene.updateMap(pos);
return this;
}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/plants/Plant.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/plants/Plant.java
index 5d7b51d36..0d5cb2738 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/plants/Plant.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/plants/Plant.java
@@ -38,7 +38,6 @@ 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.sprites.PlantSprite;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundlable;
import com.watabou.utils.Bundle;
@@ -52,8 +51,6 @@ public abstract class Plant implements Bundlable {
public int image;
public int pos;
-
- public PlantSprite sprite;
public void trigger(){
@@ -71,8 +68,7 @@ public abstract class Plant implements Bundlable {
public void wither() {
Dungeon.level.uproot( pos );
-
- sprite.kill();
+
if (Dungeon.visible[pos]) {
CellEmitter.get( pos ).burst( LeafParticle.GENERAL, 6 );
}
@@ -142,7 +138,7 @@ public abstract class Plant implements Bundlable {
@Override
protected void onThrow( int cell ) {
- if (Dungeon.level.map[cell] == Terrain.ALCHEMY || Level.pit[cell]) {
+ if (Dungeon.level.map[cell] == Terrain.ALCHEMY || Level.pit[cell] || Dungeon.level.traps.get(cell) != null) {
super.onThrow( cell );
} else {
Dungeon.level.plant( this, cell );
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 fb0dbf519..727cc5bb8 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java
@@ -71,6 +71,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.LootIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.ResumeIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane;
+import com.shatteredpixel.shatteredpixeldungeon.ui.TerrainFeaturesTilemap;
import com.shatteredpixel.shatteredpixeldungeon.ui.Toast;
import com.shatteredpixel.shatteredpixeldungeon.ui.Toolbar;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
@@ -111,6 +112,7 @@ public class GameScene extends PixelScene {
private SkinnedBlock water;
private DungeonTilemap tiles;
+ private TerrainFeaturesTilemap terrainFeatures;
private FogOfWar fog;
private HeroSprite hero;
@@ -193,30 +195,17 @@ public class GameScene extends PixelScene {
for( CustomTileVisual visual : Dungeon.level.customTiles){
addCustomTile(visual.create());
}
+
+ terrainFeatures = new TerrainFeaturesTilemap(Dungeon.level.plants, Dungeon.level.traps);
+ terrain.add(terrainFeatures);
levelVisuals = Dungeon.level.addVisuals();
add(levelVisuals);
-
- traps = new Group();
- add(traps);
-
- int size = Dungeon.level.traps.size();
- for (int i=0; i < size; i++) {
- addTrapSprite( Dungeon.level.traps.valueAt( i ) );
- }
-
- plants = new Group();
- add( plants );
-
- size = Dungeon.level.plants.size();
- for (int i=0; i < size; i++) {
- addPlantSprite( Dungeon.level.plants.valueAt( i ) );
- }
heaps = new Group();
add( heaps );
- size = Dungeon.level.heaps.size();
+ int size = Dungeon.level.heaps.size();
for (int i=0; i < size; i++) {
addHeapSprite( Dungeon.level.heaps.valueAt( i ) );
}
@@ -541,12 +530,11 @@ public class GameScene extends PixelScene {
}
private void addPlantSprite( Plant plant ) {
- (plant.sprite = (PlantSprite)plants.recycle( PlantSprite.class )).reset( plant );
+
}
private void addTrapSprite( Trap trap ) {
- (trap.sprite = (TrapSprite)traps.recycle( TrapSprite.class )).reset( trap );
- trap.sprite.visible = trap.visible;
+
}
private void addBlobSprite( final Blob gas ) {
@@ -689,12 +677,14 @@ public class GameScene extends PixelScene {
public static void updateMap() {
if (scene != null) {
scene.tiles.updateMap();
+ scene.terrainFeatures.updateMap();
}
}
public static void updateMap( int cell ) {
if (scene != null) {
scene.tiles.updateMapCell( cell );
+ scene.terrainFeatures.updateMapCell( cell );
}
}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/PlantSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/PlantSprite.java
index 1128f0b8c..a05e17ed7 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/PlantSprite.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/PlantSprite.java
@@ -44,7 +44,7 @@ public class PlantSprite extends Image {
private int pos = -1;
public PlantSprite() {
- super( Assets.PLANTS );
+ super( Assets.TERRAIN_FEATURES );
if (frames == null) {
frames = new TextureFilm( texture, 16, 16 );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/TrapSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/TrapSprite.java
index 72295d197..c9086b333 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/TrapSprite.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/TrapSprite.java
@@ -56,7 +56,7 @@ public class TrapSprite extends Image {
public TrapSprite() {
- super( Assets.TRAPS );
+ super( Assets.TERRAIN_FEATURES );
if (frames == null) {
frames = new TextureFilm( texture, 16, 16 );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/TerrainFeaturesTilemap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/TerrainFeaturesTilemap.java
new file mode 100644
index 000000000..ca359c06f
--- /dev/null
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/TerrainFeaturesTilemap.java
@@ -0,0 +1,140 @@
+/*
+ * Pixel Dungeon
+ * Copyright (C) 2012-2015 Oleg Dolya
+ *
+ * Shattered Pixel Dungeon
+ * Copyright (C) 2014-2016 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
+ */
+package com.shatteredpixel.shatteredpixeldungeon.ui;
+
+import com.shatteredpixel.shatteredpixeldungeon.Assets;
+import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
+import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
+import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap;
+import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
+import com.shatteredpixel.shatteredpixeldungeon.sprites.TrapSprite;
+import com.watabou.noosa.Image;
+import com.watabou.noosa.TextureFilm;
+import com.watabou.noosa.Tilemap;
+import com.watabou.utils.PathFinder;
+import com.watabou.utils.Random;
+import com.watabou.utils.SparseArray;
+
+public class TerrainFeaturesTilemap extends Tilemap {
+
+ public static final int SIZE = 16;
+
+ private static TerrainFeaturesTilemap instance;
+
+ private int[] map;
+ private float[] tileVariance;
+
+ private SparseArray plants;
+ private SparseArray traps;
+
+ public TerrainFeaturesTilemap(SparseArray plants, SparseArray traps) {
+ super(Assets.TERRAIN_FEATURES, new TextureFilm( Assets.TERRAIN_FEATURES, SIZE, SIZE ));
+
+ this.plants = plants;
+ this.traps = traps;
+
+ Random.seed( Dungeon.seedCurDepth());
+ tileVariance = new float[Dungeon.level.map.length];
+ for (int i = 0; i < tileVariance.length; i++)
+ tileVariance[i] = Random.Float();
+ Random.seed();
+
+ map( Dungeon.level.map, Dungeon.level.width() );
+
+ instance = this;
+ }
+
+ @Override
+ //we need to retain two arrays, map is the dungeon tilemap which we can reference.
+ // Data is our own internal image representation of the tiles, which may differ.
+ public void map(int[] data, int cols) {
+ map = data;
+ super.map(new int[data.length], cols);
+ }
+
+ @Override
+ public synchronized void updateMap() {
+ super.updateMap();
+ for (int i = 0; i < data.length; i++)
+ data[i] = getTileVisual(i ,map[i]);
+ }
+
+ @Override
+ public synchronized void updateMapCell(int cell) {
+ //update in a 3x3 grid to account for neighbours which might also be affected
+ if (Dungeon.level.insideMap(cell)) {
+ super.updateMapCell(cell - mapWidth - 1);
+ super.updateMapCell(cell + mapWidth + 1);
+ for (int i : PathFinder.NEIGHBOURS9)
+ data[cell + i] = getTileVisual(cell + i, map[cell + i]);
+
+ //unless we're at the level's edge, then just do the one tile.
+ } else {
+ super.updateMapCell(cell);
+ data[cell] = getTileVisual(cell, map[cell]);
+ }
+ }
+
+ private int getTileVisual(int pos, int tile){
+ if (traps.get(pos) != null){
+ Trap trap = traps.get(pos);
+ if (!trap.visible)
+ return -1;
+ else
+ return (trap.active ? trap.color : TrapSprite.BLACK) + (trap.shape * 16);
+ }
+
+ if (plants.get(pos) != null){
+ return plants.get(pos).image + 7*16;
+ }
+
+ if (tile == Terrain.HIGH_GRASS){
+ return 9 + 16*((Dungeon.depth-1)/5) + (tileVariance[pos] > 0.5f ? 1 : 0);
+ } else if (tile == Terrain.GRASS) {
+ return 11 + 16*((Dungeon.depth-1)/5) + (tileVariance[pos] > 0.5f ? 1 : 0);
+ } else if (tile == Terrain.EMBERS) {
+ return 13 + (tileVariance[pos] > 0.5f ? 1 : 0);
+ }
+
+ return -1;
+ }
+
+ public static Image tile(int pos, int tile ) {
+ Image img = new Image( instance.texture );
+ img.frame( instance.tileset.get( instance.getTileVisual( pos, tile ) ) );
+ return img;
+ }
+
+ @Override
+ public boolean overlapsPoint( float x, float y ) {
+ return true;
+ }
+
+ @Override
+ public boolean overlapsScreenPoint( int x, int y ) {
+ return true;
+ }
+
+ @Override
+ protected boolean needsRender(int pos) {
+ return data[pos] != -1;
+ }
+}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoPlant.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoPlant.java
index c822b03d6..670ceae66 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoPlant.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoPlant.java
@@ -20,14 +20,19 @@
*/
package com.shatteredpixel.shatteredpixeldungeon.windows;
+import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
+import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
+import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.PlantSprite;
+import com.shatteredpixel.shatteredpixeldungeon.ui.TerrainFeaturesTilemap;
public class WndInfoPlant extends WndTitledMessage {
public WndInfoPlant( Plant plant ) {
- super(new PlantSprite( plant.image ), plant.plantName, plant.desc());
+ super(TerrainFeaturesTilemap.tile( plant.pos, Dungeon.level.map[plant.pos]),
+ plant.plantName, plant.desc());
}
}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoTrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoTrap.java
index df2dc4cf1..bc8f6947f 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoTrap.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoTrap.java
@@ -20,15 +20,16 @@
*/
package com.shatteredpixel.shatteredpixeldungeon.windows;
+import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
-import com.shatteredpixel.shatteredpixeldungeon.sprites.TrapSprite;
+import com.shatteredpixel.shatteredpixeldungeon.ui.TerrainFeaturesTilemap;
public class WndInfoTrap extends WndTitledMessage {
public WndInfoTrap(Trap trap) {
- super(new TrapSprite( trap.color + (trap.shape * 16) ),
+ super(TerrainFeaturesTilemap.tile( trap.pos, Dungeon.level.map[trap.pos]),
trap.name,
(!trap.active ? Messages.get(WndInfoTrap.class, "inactive") + "\n\n" : "") + trap.desc());