Added static entities

Added StaticEntity class generated from DS1 objects -- belong to Map Zones and render per-tile
Fixed paths for EntType OBJECT and MONSTER
This commit is contained in:
Collin Smith 2019-02-13 02:42:07 -08:00
parent e5e6be00ce
commit a0983e852c
6 changed files with 212 additions and 24 deletions

View File

@ -32,8 +32,8 @@ public class Entity {
private static final boolean DEBUG_STATE = DEBUG && true;
protected enum EntType {
OBJECT("OBJECT"),
MONSTER("MONSTER"),
OBJECT("OBJECTS"),
MONSTER("MONSTERS"),
PLAYER("CHARS");
public final String PATH;

View File

@ -0,0 +1,119 @@
package gdx.diablo.entity;
import com.badlogic.gdx.Gdx;
import gdx.diablo.Diablo;
import gdx.diablo.codec.excel.Objects;
import gdx.diablo.map.DS1;
public class StaticEntity extends Entity {
private static final String TAG = "StaticEntity";
Objects.Entry object;
public StaticEntity(String type, Objects.Entry object) {
super(type, EntType.OBJECT);
this.object = object;
init();
}
public static StaticEntity create(DS1 ds1, DS1.Object obj) {
assert obj.type == DS1.Object.STATIC_TYPE;
int id = Diablo.files.obj.getType2(ds1.getAct(), obj.id);
Objects.Entry object = Diablo.files.objects.get(id);
if (object == null) return null; // TODO: Which ones fall under this case?
if (!object.Draw) return null; // TODO: Not yet
String type = object.Token;
return new StaticEntity(type, object);
}
@Override
protected void update() {
super.update();
int mode = Diablo.files.ObjMode.index(this.mode);
//System.out.println(getName() + " " + this.mode + "(" + mode + ") " + object.FrameDelta[mode]);
animation.setLooping(object.CycleAnim[mode]);
animation.setFrame(object.Start[mode]);
animation.setFrameDelta(object.FrameDelta[mode]); // FIXME: anim framedelta looks too quick
}
public String getName() {
return object == null ? toString() : object.Name + "(" + object.Id + ")";
}
private void init() {
switch (object.InitFn) {
case 0:
break;
case 1: case 2: case 3: case 4: case 5: case 6: case 7:
break;
case 8: // torch
setMode("ON");
// FIXME: Set random start frame?
//int framesPerDir = animation.getNumFramesPerDir();
//animation.setFrame(MathUtils.random(0, framesPerDir - 1));
break;
case 9 : case 10: case 11: case 12: case 13: case 14: case 15: case 16:
break;
case 17: // waypoint
// TODO: Automatically sets on
setMode("ON");
break;
case 18:
case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28:
case 29: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: case 38:
case 39: case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48:
case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58:
case 59: case 60: case 61: case 62: case 63: case 64: case 65: case 66: case 67: case 68:
case 69: case 70: case 71: case 72: case 73: case 74: case 75: case 76: case 77: case 78:
case 79:
break;
default:
Gdx.app.error(TAG, "Invalid InitFn for " + getName() + ": " + object.InitFn);
}
}
private void operate() {
switch (object.OperateFn) {
case 0:
break;
case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9:
case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19:
case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29:
case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39:
case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49:
case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: case 59:
case 60: case 61: case 62: case 63: case 64: case 65: case 66: case 67: case 68: case 69:
case 70: case 71: case 72: case 73:
break;
default:
Gdx.app.error(TAG, "Invalid OperateFn for " + getName() + ": " + object.OperateFn);
}
}
private void populate() {
switch (object.PopulateFn) {
case 0:
break;
case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9:
break;
default:
Gdx.app.error(TAG, "Invalid PopulateFn for " + getName() + ": " + object.PopulateFn);
}
}
private void client() {
switch (object.ClientFn) {
case 0:
break;
case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9:
case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
break;
default:
Gdx.app.error(TAG, "Invalid ClientFn for " + getName() + ": " + object.ClientFn);
}
}
}

View File

@ -20,6 +20,8 @@ import gdx.diablo.Diablo;
import gdx.diablo.codec.excel.Levels;
import gdx.diablo.codec.excel.LvlPrest;
import gdx.diablo.codec.excel.LvlTypes;
import gdx.diablo.entity.Entity;
import gdx.diablo.entity.StaticEntity;
public class Map implements Disposable {
private static final String TAG = "Map";
@ -520,6 +522,8 @@ public class Map implements Disposable {
}
static class Zone {
static final Array<Entity> EMPTY_ARRAY = new Array<>(0);
int x, y;
int width, height;
int gridSizeX, gridSizeY;
@ -532,6 +536,7 @@ public class Map implements Disposable {
Preset presets[][];
Tile tiles[][][];
byte flags[][];
Array<Entity> entities;
Generator generator;
@ -544,14 +549,15 @@ public class Map implements Disposable {
this.gridSizeX = gridSizeX;
this.gridSizeY = gridSizeY;
tilesX = level.SizeX[diff];
tilesY = level.SizeY[diff];
width = tilesX * DT1.Tile.SUBTILE_SIZE;
height = tilesY * DT1.Tile.SUBTILE_SIZE;
gridsX = tilesX / gridSizeX;
gridsY = tilesY / gridSizeY;
presets = new Preset[gridsX][gridsY];
flags = new byte[width][height];
tilesX = level.SizeX[diff];
tilesY = level.SizeY[diff];
width = tilesX * DT1.Tile.SUBTILE_SIZE;
height = tilesY * DT1.Tile.SUBTILE_SIZE;
gridsX = tilesX / gridSizeX;
gridsY = tilesY / gridSizeY;
presets = new Preset[gridsX][gridsY];
flags = new byte[width][height];
entities = EMPTY_ARRAY;
}
/**
@ -565,12 +571,48 @@ public class Map implements Disposable {
this.gridsX = gridsX;
this.gridsY = gridsY;
tilesX = gridsX * gridSizeX;
tilesY = gridsY * gridSizeY;
width = gridsX * DT1.Tile.SUBTILE_SIZE;
height = gridsY * DT1.Tile.SUBTILE_SIZE;
presets = new Preset[gridsX][gridsY];
flags = new byte[width][height];
tilesX = gridsX * gridSizeX;
tilesY = gridsY * gridSizeY;
width = gridsX * DT1.Tile.SUBTILE_SIZE;
height = gridsY * DT1.Tile.SUBTILE_SIZE;
presets = new Preset[gridsX][gridsY];
flags = new byte[width][height];
entities = EMPTY_ARRAY;
}
private void loadEntities(DS1 ds1, int gridX, int gridY) {
if (entities == EMPTY_ARRAY) entities = new Array<>();
for (int i = 0; i < ds1.numObjects; i++) {
DS1.Object obj = ds1.objects[i];
if (obj.type != DS1.Object.STATIC_TYPE) continue;
//int id = Diablo.files.obj.getType2(ds1.getAct(), obj.id);
//Objects.Entry object = Diablo.files.objects.get(id);
//if (object == null) continue;
//if (!object.Draw) continue;
//final String token = object.Token;
//Entity entity = new Entity(token);
//entity.setAngle(0);
//animation.setLooping(object.CycleAnim[i]);
//animation.setFrame(object.Start[i]);
//animation.setFrameDelta(object.FrameDelta[i]);
StaticEntity entity = StaticEntity.create(ds1, obj);
if (entity == null) continue;
entity.position().set(x + gridX + obj.x, y + gridY + obj.y, 0);
entities.add(entity);
/*switch (object.InitFn) {
case 8:
entity.setMode("ON");
break;
case 17:
entity.setMode("ON");
break;
}*/
}
}
public void setPosition(int x, int y) {
@ -636,6 +678,7 @@ public class Map implements Disposable {
DS1 ds1 = Diablo.assets.get(TILES_PATH + preset.ds1Path);
preset.set(ds1, dt1s);
preset.copyTo(this, gridX, gridY);
loadEntities(ds1, gridX, gridY);
}
}
}

View File

@ -14,6 +14,7 @@ import com.badlogic.gdx.utils.Align;
import java.util.Arrays;
import gdx.diablo.Diablo;
import gdx.diablo.entity.Entity;
import gdx.diablo.graphics.PaletteIndexedBatch;
import gdx.diablo.map.DT1.Tile;
@ -224,6 +225,7 @@ public class MapRenderer {
case Map.SHADOW_OFFSET:
break;
case Map.WALL_OFFSET: case Map.WALL_OFFSET + 1: case Map.WALL_OFFSET + 2: case Map.WALL_OFFSET + 3:
drawObjects(batch, zone, stx, sty);
drawWall(batch, tile, px, py);
break;
case Map.TAG_OFFSET:
@ -259,6 +261,16 @@ public class MapRenderer {
batch.draw(texture, px, py, texture.getRegionWidth() + 1, texture.getRegionHeight() + 1);
}
void drawObjects(PaletteIndexedBatch batch, Map.Zone zone, int stx, int sty) {
for (Entity entity : zone.entities) {
Vector3 position = entity.position();
if ((stx <= position.x && position.x < stx + Tile.SUBTILE_SIZE)
&& (sty <= position.y && position.y < sty + Tile.SUBTILE_SIZE)) {
entity.draw(batch);
}
}
}
void drawWall(PaletteIndexedBatch batch, Map.Tile tile, int px, int py) {
if (tile == null) return;
if (Orientation.isSpecial(tile.cell.orientation)) {

View File

@ -384,6 +384,7 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
b.begin();
//map.draw(b, 0, 0, 30, 13, Diablo.VIRTUAL_WIDTH, Diablo.VIRTUAL_HEIGHT, 1.5f);
mapRenderer.render();
b.end();
// pixel offset of subtile in world-space
//int spx = + (character.x * Tile.SUBTILE_WIDTH50) - (character.y * Tile.SUBTILE_WIDTH50);
@ -394,13 +395,6 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
//player.draw(b, spx, spy);
//player.draw(b);
for (Player p : entities.values()) {
p.draw(b);
}
b.end();
b.setProjectionMatrix(Diablo.viewport.getCamera().combined);
Diablo.shapes.setAutoShapeType(true);
Diablo.shapes.setProjectionMatrix(camera.combined);
Diablo.shapes.begin(ShapeRenderer.ShapeType.Line);
@ -409,6 +403,24 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
player.drawDebug(Diablo.shapes);
Diablo.shapes.end();
b.setProjectionMatrix(camera.combined);
b.begin();
for (Player p : entities.values()) {
p.draw(b);
}
b.end();
b.setProjectionMatrix(Diablo.viewport.getCamera().combined);
//Diablo.shapes.setAutoShapeType(true);
//Diablo.shapes.setProjectionMatrix(camera.combined);
//Diablo.shapes.begin(ShapeRenderer.ShapeType.Line);
//mapRenderer.renderDebug(Diablo.shapes);
////player.drawDebug(Diablo.shapes, spx, spy);
//player.drawDebug(Diablo.shapes);
//Diablo.shapes.end();
stage.act();
stage.draw();
}
@ -419,7 +431,9 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
Diablo.assets.get(windowopenDescriptor).play();
map = Diablo.assets.get(mapDescriptor);
// FIXME: Below causes bug with debug text in MapRenderer, setting camera to screen dims fixes, but renders far too much on mobile
camera = new OrthographicCamera(Diablo.VIRTUAL_WIDTH, Diablo.VIRTUAL_HEIGHT);
//camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
mapRenderer = new MapRenderer(Diablo.batch, camera);
mapRenderer.setMap(map);
mapRenderer.resize();

View File

@ -297,7 +297,7 @@ public class MapViewer extends ApplicationAdapter {
Gdx.app.debug(TAG, Diablo.assets.getReferenceCount(asset) + " : " + asset);
}
Gdx.app.debug(TAG, "JAVA: " + Gdx.app.getJavaHeap() + " Bytes; NATIVE:" + Gdx.app.getNativeHeap() + " Bytes");
Gdx.app.debug(TAG, "JAVA: " + Gdx.app.getJavaHeap() + " Bytes; NATIVE: " + Gdx.app.getNativeHeap() + " Bytes");
}
@Override