diff --git a/core/src/gdx/diablo/assets/AssetDescriptor.java b/core/src/gdx/diablo/assets/AssetDescriptor.java deleted file mode 100644 index 1dbe6ce6..00000000 --- a/core/src/gdx/diablo/assets/AssetDescriptor.java +++ /dev/null @@ -1,26 +0,0 @@ -package gdx.diablo.assets; - -public class AssetDescriptor { - public static AssetDescriptor of(String fileName, Class type) { - return of(fileName, type, null); - } - - public static AssetDescriptor of(String fileName, Class type, AssetLoader.Parameters params) { - return new AssetDescriptor<>(fileName, type, params); - } - - public final String fileName; - public final Class type; - public final AssetLoader.Parameters params; - - public AssetDescriptor(String fileName, Class type, AssetLoader.Parameters params) { - this.fileName = fileName.replace('\\', '/'); - this.type = type; - this.params = params; - } - - @Override - public String toString() { - return fileName + ", " + type.getName(); - } -} diff --git a/core/src/gdx/diablo/assets/AssetLoader.java b/core/src/gdx/diablo/assets/AssetLoader.java deleted file mode 100644 index e931f4f8..00000000 --- a/core/src/gdx/diablo/assets/AssetLoader.java +++ /dev/null @@ -1,18 +0,0 @@ -package gdx.diablo.assets; - -import com.badlogic.gdx.assets.loaders.FileHandleResolver; -import com.badlogic.gdx.files.FileHandle; - -public abstract class AssetLoader> { - private FileHandleResolver resolver; - - public AssetLoader(FileHandleResolver resolver) { - this.resolver = resolver; - } - - public FileHandle resolve(String fileName) { - return resolver.resolve(fileName); - } - - public interface Parameters {} -} diff --git a/core/src/gdx/diablo/assets/async/AsyncExecutor.java b/core/src/gdx/diablo/assets/async/AsyncExecutor.java deleted file mode 100644 index 4e11f984..00000000 --- a/core/src/gdx/diablo/assets/async/AsyncExecutor.java +++ /dev/null @@ -1,45 +0,0 @@ -package gdx.diablo.assets.async; - -import com.badlogic.gdx.utils.Disposable; -import com.badlogic.gdx.utils.GdxRuntimeException; - -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - -public class AsyncExecutor implements Disposable { - private final ExecutorService executor; - - public AsyncExecutor(int maxConcurrent) { - executor = Executors.newFixedThreadPool(maxConcurrent, new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread thread = new Thread(r, "AsyncExecutor-Thread"); - thread.setDaemon(true); - return thread; - } - }); - } - - @Override - public void dispose() { - executor.shutdown(); - try { - executor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); - } catch (InterruptedException e) { - throw new GdxRuntimeException("Couldn't shutdown loading thread", e); - } - } - - public AsyncResult submit(final AsyncTask task) { - if (executor.isShutdown()) throw new GdxRuntimeException("Cannot run tasks on an executor that has been shutdown (disposed)"); - return new AsyncResult<>(executor.submit(new Callable() { - @Override - public T call() throws Exception { - return task.call(); - } - })); - } -} diff --git a/core/src/gdx/diablo/assets/async/AsyncResult.java b/core/src/gdx/diablo/assets/async/AsyncResult.java deleted file mode 100644 index a0f87a42..00000000 --- a/core/src/gdx/diablo/assets/async/AsyncResult.java +++ /dev/null @@ -1,28 +0,0 @@ -package gdx.diablo.assets.async; - -import com.badlogic.gdx.utils.GdxRuntimeException; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; - -public class AsyncResult { - private final Future future; - - AsyncResult(Future future) { - this.future = future; - } - - public boolean isDown() { - return future.isDone(); - } - - public T get() { - try { - return future.get(); - } catch (InterruptedException e) { - return null; - } catch (ExecutionException e) { - throw new GdxRuntimeException(e.getCause()); - } - } -} diff --git a/core/src/gdx/diablo/assets/async/AsyncTask.java b/core/src/gdx/diablo/assets/async/AsyncTask.java deleted file mode 100644 index 4e3ee53a..00000000 --- a/core/src/gdx/diablo/assets/async/AsyncTask.java +++ /dev/null @@ -1,5 +0,0 @@ -package gdx.diablo.assets.async; - -public interface AsyncTask { - T call() throws Exception; -} diff --git a/core/src/gdx/diablo/engine/component/LayerComponent.java b/core/src/gdx/diablo/engine/component/LayerComponent.java new file mode 100644 index 00000000..eed33c93 --- /dev/null +++ b/core/src/gdx/diablo/engine/component/LayerComponent.java @@ -0,0 +1,7 @@ +package gdx.diablo.engine.component; + +public class LayerComponent { + + private LayerComponent() {} + +} diff --git a/core/src/gdx/diablo/engine/component/ModeComponent.java b/core/src/gdx/diablo/engine/component/ModeComponent.java new file mode 100644 index 00000000..b22f927a --- /dev/null +++ b/core/src/gdx/diablo/engine/component/ModeComponent.java @@ -0,0 +1,7 @@ +package gdx.diablo.engine.component; + +public class ModeComponent { + + private ModeComponent() {} + +} diff --git a/core/src/gdx/diablo/engine/component/PositionComponent.java b/core/src/gdx/diablo/engine/component/PositionComponent.java new file mode 100644 index 00000000..3d9f1f33 --- /dev/null +++ b/core/src/gdx/diablo/engine/component/PositionComponent.java @@ -0,0 +1,7 @@ +package gdx.diablo.engine.component; + +public class PositionComponent { + + private PositionComponent() {} + +} diff --git a/core/src/gdx/diablo/engine/component/VelocityComponent.java b/core/src/gdx/diablo/engine/component/VelocityComponent.java new file mode 100644 index 00000000..1b83a0ec --- /dev/null +++ b/core/src/gdx/diablo/engine/component/VelocityComponent.java @@ -0,0 +1,7 @@ +package gdx.diablo.engine.component; + +public class VelocityComponent { + + private VelocityComponent() {} + +} diff --git a/core/src/gdx/diablo/engine/component/WeaponClassComponent.java b/core/src/gdx/diablo/engine/component/WeaponClassComponent.java new file mode 100644 index 00000000..90e90829 --- /dev/null +++ b/core/src/gdx/diablo/engine/component/WeaponClassComponent.java @@ -0,0 +1,7 @@ +package gdx.diablo.engine.component; + +public class WeaponClassComponent { + + private WeaponClassComponent() {} + +} diff --git a/core/src/gdx/diablo/engine/system/MovementSystem.java b/core/src/gdx/diablo/engine/system/MovementSystem.java new file mode 100644 index 00000000..aa7d59ea --- /dev/null +++ b/core/src/gdx/diablo/engine/system/MovementSystem.java @@ -0,0 +1,7 @@ +package gdx.diablo.engine.system; + +public class MovementSystem { + + private MovementSystem() {} + +} diff --git a/core/src/gdx/diablo/engine/system/RenderSysem.java b/core/src/gdx/diablo/engine/system/RenderSysem.java new file mode 100644 index 00000000..38243623 --- /dev/null +++ b/core/src/gdx/diablo/engine/system/RenderSysem.java @@ -0,0 +1,21 @@ +package gdx.diablo.engine.system; + +import com.badlogic.ashley.core.ComponentMapper; +import com.badlogic.ashley.core.Entity; +import com.badlogic.ashley.core.Family; +import com.badlogic.ashley.systems.IteratingSystem; + +import gdx.diablo.engine.component.WeaponClassComponent; + +public class WeaponSystem extends IteratingSystem { + private ComponentMapper wc = ComponentMapper.getFor(WeaponClassComponent.class); + + public WeaponSystem() { + super(Family.all(WeaponClassComponent.class).get()); + } + + @Override + protected void processEntity(Entity entity, float delta) { + + } +} diff --git a/core/src/gdx/diablo/entity2/Component.java b/core/src/gdx/diablo/entity2/Component.java deleted file mode 100644 index 9459db2e..00000000 --- a/core/src/gdx/diablo/entity2/Component.java +++ /dev/null @@ -1,46 +0,0 @@ -package gdx.diablo.entity2; - -import com.badlogic.gdx.Gdx; - -public enum Component { - HD, - TR, - LG, - RA, - LA, - RH, - LH, - SH, - S1, - S2, - S3, - S4, - S5, - S6, - S7, - S8; - - public static Component valueOf(int i) { - switch (i) { - case 0x0: return HD; - case 0x1: return TR; - case 0x2: return LG; - case 0x3: return RA; - case 0x4: return LA; - case 0x5: return RH; - case 0x6: return LH; - case 0x7: return SH; - case 0x8: return S1; - case 0x9: return S2; - case 0xA: return S3; - case 0xB: return S4; - case 0xC: return S5; - case 0xD: return S6; - case 0xE: return S7; - case 0xF: return S8; - default: - Gdx.app.error("Component", "Unknown component: " + i); - return null; - } - } -} diff --git a/core/src/gdx/diablo/entity2/Entity.java b/core/src/gdx/diablo/entity2/Entity.java deleted file mode 100644 index a042db2a..00000000 --- a/core/src/gdx/diablo/entity2/Entity.java +++ /dev/null @@ -1,87 +0,0 @@ -package gdx.diablo.entity2; - -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.math.Vector2; - -import java.util.EnumMap; - -import gdx.diablo.codec.Animation; -import gdx.diablo.graphics.PaletteIndexedBatch; - -public class Entity { - - /** - * x, y (src) - * angle (radians) - * scalar (movement speed) - * - * x, y (dst) - */ - Vector2 origin; - Vector2 velocity; - - String mode; - String code; - String armorType; - String weaponClass; - - EnumMap components = new EnumMap<>(Component.class); - Animation.COFAnimation animation; - - Entity() { - mode = code = "NU"; - armorType = "LIT"; - weaponClass = "HTH"; - } - - public void setMode(String mode) { - setMode(mode, mode); - } - - public void setMode(String mode, String code) { - this.mode = mode; - this.code = code; - } - - /* - Entity(Excel excel, String mode) { - this(excel.get(mode)); - } - - Entity(Excel excel) { - this(excel, "NU"); - } - */ - - /* - public M getMode() { - return mode; - } - - public void setMode(M mode) { - this.mode = mode; - } - - public String getCode() { - return mode.getCode(); - } - */ - - public int getX() { - return 0; - } - - public int getY() { - return 0; - } - - public void setComponent(Component component, Animation.Layer value) { - } - - public void draw(Batch batch) { - draw((PaletteIndexedBatch) batch); - } - - public void draw(PaletteIndexedBatch batch) { - } -} diff --git a/core/src/gdx/diablo/entity2/Object.java b/core/src/gdx/diablo/entity2/Object.java deleted file mode 100644 index 553b8f11..00000000 --- a/core/src/gdx/diablo/entity2/Object.java +++ /dev/null @@ -1,7 +0,0 @@ -package gdx.diablo.entity2; - -public class Object extends Entity { - public Object() { - //super(Diablo.files.ObjMode); - } -} diff --git a/core/src/gdx/diablo/entity2/Player.java b/core/src/gdx/diablo/entity2/Player.java deleted file mode 100644 index c4cf5a1f..00000000 --- a/core/src/gdx/diablo/entity2/Player.java +++ /dev/null @@ -1,115 +0,0 @@ -package gdx.diablo.entity2; - -import com.badlogic.gdx.Gdx; - -import java.util.EnumMap; - -import gdx.diablo.codec.excel.Weapons; -import gdx.diablo.item.BodyLoc; -import gdx.diablo.item.Item; - -public class Player extends Entity { - private static final String TAG = "Player"; - - public enum Slot { - HEAD, - NECK, - TORS, - RARM, - LARM, - RRIN, - LRIN, - BELT, - FEET, - GLOV; - } - - boolean dirty; - boolean alternate; - EnumMap equipped = new EnumMap<>(BodyLoc.class); - - public Player() { - //super(Diablo.files.PlrMode); - } - - public Item getSlot(Slot slot) { - switch (slot) { - case HEAD: return equipped.get(BodyLoc.HEAD); - case NECK: return equipped.get(BodyLoc.NECK); - case TORS: return equipped.get(BodyLoc.TORS); - case RARM: return equipped.get(alternate ? BodyLoc.RARM2 : BodyLoc.RARM); - case LARM: return equipped.get(alternate ? BodyLoc.LARM2 : BodyLoc.LARM); - case RRIN: return equipped.get(BodyLoc.RRIN); - case LRIN: return equipped.get(BodyLoc.LRIN); - case BELT: return equipped.get(BodyLoc.BELT); - case FEET: return equipped.get(BodyLoc.FEET); - case GLOV: return equipped.get(BodyLoc.GLOV); - default: - Gdx.app.error(TAG, "Invalid slot: " + slot); - return null; - } - } - - public void update() { - if (!dirty) { - return; - } else { - dirty = false; - } - - Item rArm = getSlot(Slot.RARM); - if (rArm != null && rArm.type.is("weap")) { - Weapons.Entry entry = rArm.getBase(); - if (entry._2handed) { - weaponClass = entry._2handedwclass; - } else { - weaponClass = entry.wclass; - } - } else { - weaponClass = "HTH"; - } - - Item lArm = getSlot(Slot.LARM); - if (lArm != null) { - if (lArm.type.is("weap") && rArm != null && rArm.type.is("weap")) { - - } else if (lArm.type.is("shld")) { - - } - } - - if (lArm != null && lArm.type.is("weap")) { - weaponClass = ((Weapons.Entry) lArm.base).wclass; - } - - // TODO: add support for barb (1js,1jt,1ss,1st) / assassin (ht1,ht2) customs - Item weapon = null; - if (rArm != null && rArm.type.is("weap")) { - weapon = rArm; - } else if (lArm != null && lArm.type.is("weap")) { - weapon = lArm; - } - - String wclass = null; - if (weapon == null) { - wclass = "hth"; - } else { - Weapons.Entry weaponEntry = weapon.getBase(); - wclass = weaponEntry.wclass; - } - - // TODO: custom code for barbarian _1or2handed - if (rArm != null && lArm != null) { - // if rArm and lArm are weapons - // if only one is weapon - /* - if (rArm.type.is("weap")) { - Weapons.Entry rArmEntry = rArm.getBase(); - - } - */ - } else if (rArm != null) { - } else if (lArm != null) { - } - } -} diff --git a/core/src/gdx/diablo/entity3/Component.java b/core/src/gdx/diablo/entity3/Component.java deleted file mode 100644 index b4d14c3e..00000000 --- a/core/src/gdx/diablo/entity3/Component.java +++ /dev/null @@ -1,46 +0,0 @@ -package gdx.diablo.entity3; - -import com.badlogic.gdx.Gdx; - -public enum Component { - HD, - TR, - LG, - RA, - LA, - RH, - LH, - SH, - S1, - S2, - S3, - S4, - S5, - S6, - S7, - S8; - - public static Component valueOf(int i) { - switch (i) { - case 0x0: return HD; - case 0x1: return TR; - case 0x2: return LG; - case 0x3: return RA; - case 0x4: return LA; - case 0x5: return RH; - case 0x6: return LH; - case 0x7: return SH; - case 0x8: return S1; - case 0x9: return S2; - case 0xA: return S3; - case 0xB: return S4; - case 0xC: return S5; - case 0xD: return S6; - case 0xE: return S7; - case 0xF: return S8; - default: - Gdx.app.error("Component", "Unknown component: " + i); - return null; - } - } -} diff --git a/core/src/gdx/diablo/entity3/Entity.java b/core/src/gdx/diablo/entity3/Entity.java deleted file mode 100644 index 97afd1fd..00000000 --- a/core/src/gdx/diablo/entity3/Entity.java +++ /dev/null @@ -1,337 +0,0 @@ -package gdx.diablo.entity3; - -import android.support.annotation.CallSuper; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.assets.AssetDescriptor; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.badlogic.gdx.math.GridPoint2; -import com.badlogic.gdx.math.MathUtils; - -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.ObjectUtils; - -import java.util.Arrays; - -import gdx.diablo.Diablo; -import gdx.diablo.codec.Animation; -import gdx.diablo.codec.COF; -import gdx.diablo.codec.COFD2; -import gdx.diablo.codec.DCC; -import gdx.diablo.entity.Direction; -import gdx.diablo.graphics.PaletteIndexedBatch; -import gdx.diablo.item.Item; -import gdx.diablo.map.DS1; -import gdx.diablo.map.DT1.Tile; - -public class Entity { - private static final String TAG = "Entity"; - private static final boolean DEBUG = true; - private static final boolean DEBUG_COMPONENTS = DEBUG && true; - private static final boolean DEBUG_DIRTY = DEBUG && true; - private static final boolean DEBUG_ASSETS = DEBUG && true; - private static final boolean DEBUG_WCLASS = DEBUG && true; - - protected enum EntType { - OBJECT, - MONSTER, - CHARS; - - public final String PATH = "data\\global\\" + name() + "\\"; - } - - public static final class Dirty { - public static final int NONE = 0; - public static final int HD = 1 << 0; - public static final int TR = 1 << 1; - public static final int LG = 1 << 2; - public static final int RA = 1 << 3; - public static final int LA = 1 << 4; - public static final int RH = 1 << 5; - public static final int LH = 1 << 6; - public static final int SH = 1 << 7; - public static final int S1 = 1 << 8; - public static final int S2 = 1 << 9; - public static final int S3 = 1 << 10; - public static final int S4 = 1 << 11; - public static final int S5 = 1 << 12; - public static final int S6 = 1 << 13; - public static final int S7 = 1 << 14; - public static final int S8 = 1 << 15; - - public static String toString(int bits) { - StringBuilder builder = new StringBuilder(); - if (bits == NONE) { - builder.append("NONE"); - } else { - if ((bits & HD) == HD) builder.append("HD").append("|"); - if ((bits & TR) == TR) builder.append("TR").append("|"); - if ((bits & LG) == LG) builder.append("LG").append("|"); - if ((bits & RA) == RA) builder.append("RA").append("|"); - if ((bits & LA) == LA) builder.append("LA").append("|"); - if ((bits & RH) == RH) builder.append("RH").append("|"); - if ((bits & LH) == LH) builder.append("LH").append("|"); - if ((bits & SH) == SH) builder.append("SH").append("|"); - if ((bits & S1) == S1) builder.append("S1").append("|"); - if ((bits & S2) == S2) builder.append("S2").append("|"); - if ((bits & S3) == S3) builder.append("S3").append("|"); - if ((bits & S4) == S4) builder.append("S4").append("|"); - if ((bits & S5) == S5) builder.append("S5").append("|"); - if ((bits & S6) == S6) builder.append("S6").append("|"); - if ((bits & S7) == S7) builder.append("S7").append("|"); - if ((bits & S8) == S8) builder.append("S8").append("|"); - if (builder.length() > 0) builder.setLength(builder.length() - 1); - } - return builder.toString(); - } - } - - private final int ALL_DIRTY = 0x0000FFFF; - protected static final String DEFAULT_LAYER = "LIT"; - private static final String[] DEFAULT_LAYERS; - static { - DEFAULT_LAYERS = new String[16]; - Arrays.fill(DEFAULT_LAYERS, DEFAULT_LAYER); - } - - GridPoint2 origin = new GridPoint2(); - float angle = MathUtils.PI * 3 / 2; - - int dirty; - String type; - String mode; - String code; - String layers[]; - String weaponClass; - - EntType entType; - Animation animation; - - Entity(String type) { - this(type, EntType.OBJECT); - } - - Entity(String type, EntType entType) { - this.type = type; - this.entType = entType; - mode = code = "NU"; - weaponClass = "HTH"; - layers = DEFAULT_LAYERS; - invalidate(); - } - - public static Entity create(DS1 ds1, DS1.Object obj) { - final int type = obj.type; - switch (type) { - case DS1.Object.DYNAMIC_TYPE: - throw new UnsupportedOperationException("Unsupported type: " + type); - case DS1.Object.STATIC_TYPE: - return null; - default: - throw new AssertionError("Unsupported type: " + type); - } - } - - public void setMode(String mode) { - setMode(mode, mode); - } - - public void setMode(String mode, String code) { - if (!this.mode.equals(mode)) { - this.mode = mode; - invalidate(); - } - - this.code = code; - } - - public void setWeaponClass(String wclass) { - if (!weaponClass.equals(wclass)) { - if (DEBUG_WCLASS) Gdx.app.debug(TAG, "wclass: " + weaponClass + " -> " + wclass); - weaponClass = wclass; - invalidate(); - } - } - - public void setArmType(Component component, String armType) { - if (layers == DEFAULT_LAYERS) { - if (!armType.equalsIgnoreCase(DEFAULT_LAYER)) { - layers = ArrayUtils.clone(DEFAULT_LAYERS); - } else { - return; - } - } - - int ordinal = component.ordinal(); - if (layers[ordinal].equalsIgnoreCase(armType)) { - return; - } - - if (DEBUG_COMPONENTS) Gdx.app.debug(TAG, "layer " + ordinal + " " + layers[ordinal] + " -> " + armType); - layers[ordinal] = armType; - dirty |= (1 << ordinal); - } - - protected Item getItem(Component component) { - return null; - } - - public final void invalidate() { - dirty = ALL_DIRTY; - } - - public final void validate() { - if (dirty == 0) { - return; - } - - update(); - } - - @CallSuper - protected void update() { - String path = type + mode + weaponClass; - Gdx.app.log(TAG, path); - - COF cof = getCOFs().lookup(path); - Gdx.app.log(TAG, ObjectUtils.toString(cof)); - - boolean changed; - if (animation == null) { - animation = Animation.newAnimation(cof); - changed = true; - } else { - changed = animation.reset(cof); - } - - if (changed) { - dirty = ALL_DIRTY; - animation.setDirection(getDirection()); - } - - if (DEBUG_DIRTY) Gdx.app.debug(TAG, "dirty layers: " + Dirty.toString(dirty)); - for (int l = 0; l < cof.getNumLayers(); l++) { - COF.Layer layer = cof.getLayer(l); - if (((1 << layer.component) & dirty) == 0) { - continue; - } - - final int c = layer.component; - final Component comp = Component.valueOf(c); - if (comp == null) continue; - String component = comp.name(); - String armType = layers[c]; - String weaponClass = layer.weaponClass; - path = entType.PATH + type + "\\" + component + "\\" + type + component + armType + mode + weaponClass + ".dcc"; - if (armType.isEmpty()) { - animation.setLayer(c, null); - continue; - } - Gdx.app.log(TAG, path); - - if (DEBUG_ASSETS) { - final AssetDescriptor descriptor = new AssetDescriptor<>(path, DCC.class); - Diablo.assets.load(descriptor); - Diablo.assets.finishLoadingAsset(descriptor); - DCC dcc = Diablo.assets.get(descriptor); - animation.setLayer(c, dcc); - - /*Runnable loader = new Runnable() { - @Override - public void run() { - if (!Diablo.assets.isLoaded(descriptor)) { - Gdx.app.postRunnable(this); - return; - } - - DCC dcc = Diablo.assets.get(descriptor); - animation.setLayer(c, dcc); - - Item item = getItem(comp); - if (item != null) { - animation.getLayer(c).setTransform(item.charColormap, item.charColorIndex); - } - } - };*/ - //Gdx.app.postRunnable(loader); - } - - //if (BodyLoc.TORS.contains(c)) { - Item item = getItem(comp); - if (item != null) { - // FIXME: colors don't look right for sorc Tirant circlet changing hair color - // putting a ruby in a white circlet not change color on item or character - // circlets and other items with hidden magic level might work different? - animation.getLayer(layer.component).setTransform(item.charColormap, item.charColorIndex); - //System.out.println(item.getName() + ": " + item.charColormap + " ; " + item.charColorIndex); - } - //} - } - - dirty = 0; - } - - protected COFD2 getCOFs() { - return Diablo.cofs.active; - } - - public void drawDebug(ShapeRenderer shapes) { - float x = +(origin.x * Tile.SUBTILE_WIDTH50) - (origin.y * Tile.SUBTILE_WIDTH50); - float y = -(origin.x * Tile.SUBTILE_HEIGHT50) - (origin.y * Tile.SUBTILE_HEIGHT50); - - final float R = 32; - shapes.setColor(Color.RED); - shapes.line(x, y, x + MathUtils.cos(angle) * R, y + MathUtils.sin(angle) * R); - - float rounded = Direction.radiansToDirection16Radians(angle); - shapes.setColor(Color.GREEN); - shapes.line(x, y, x + MathUtils.cos(rounded) * R * 0.5f, y + MathUtils.sin(rounded) * R * 0.5f); - } - - public void draw(Batch batch) { - draw((PaletteIndexedBatch) batch); - } - - public void draw(PaletteIndexedBatch batch) { - validate(); - animation.act(); - float x = +(origin.x * Tile.SUBTILE_WIDTH50) - (origin.y * Tile.SUBTILE_WIDTH50); - float y = -(origin.x * Tile.SUBTILE_HEIGHT50) - (origin.y * Tile.SUBTILE_HEIGHT50); - animation.draw(batch, x, y); - } - - public void setAngle(float rad) { - if (angle != rad) { - angle = rad; - if (animation != null) animation.setDirection(getDirection()); - } - } - - public int getDirection() { - int numDirs = animation.getNumDirections(); - return Direction.radiansToDirection(angle, numDirs); - } - - public GridPoint2 origin() { - return origin; - } - - // TODO: Delete - public void setOrigin(GridPoint2 origin) { - this.origin = origin; - } - - public void move() { - if (!mode.equalsIgnoreCase("WL") - && !mode.equalsIgnoreCase("RN") - && !mode.equalsIgnoreCase("TW")) { - return; - } - - int x = Direction.getOffX(angle); - int y = Direction.getOffY(angle); - origin.add(x, y); - } -} diff --git a/core/src/gdx/diablo/entity3/Player.java b/core/src/gdx/diablo/entity3/Player.java deleted file mode 100644 index 6426d5f2..00000000 --- a/core/src/gdx/diablo/entity3/Player.java +++ /dev/null @@ -1,353 +0,0 @@ -package gdx.diablo.entity3; - -import com.google.common.base.Preconditions; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.GdxRuntimeException; - -import org.apache.commons.lang3.ObjectUtils; - -import java.util.EnumMap; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; - -import gdx.diablo.CharClass; -import gdx.diablo.Diablo; -import gdx.diablo.codec.COFD2; -import gdx.diablo.codec.D2S; -import gdx.diablo.codec.excel.Armor; -import gdx.diablo.codec.excel.Weapons; -import gdx.diablo.item.BodyLoc; -import gdx.diablo.item.Item; - -public class Player extends Entity implements Cloneable { - @Override - public Player clone() { - try { - return (Player) super.clone(); - } catch (CloneNotSupportedException t) { - throw new GdxRuntimeException(t); - } - } - - private static final String TAG = "Player"; - private static final boolean DEBUG = true; - private static final boolean DEBUG_WCLASS = DEBUG && !true; - - public enum Slot { - HEAD, NECK, TORS, RARM, LARM, RRIN, LRIN, BELT, FEET, GLOV; - - public BodyLoc toBodyLoc(boolean alternate) { - return toBodyLoc(this, alternate); - } - - public static BodyLoc toBodyLoc(Slot slot, boolean alternate) { - switch (slot) { - case HEAD: return BodyLoc.HEAD; - case NECK: return BodyLoc.NECK; - case TORS: return BodyLoc.TORS; - case RARM: return alternate ? BodyLoc.RARM2 : BodyLoc.RARM; - case LARM: return alternate ? BodyLoc.LARM2 : BodyLoc.LARM; - case RRIN: return BodyLoc.RRIN; - case LRIN: return BodyLoc.LRIN; - case BELT: return BodyLoc.BELT; - case FEET: return BodyLoc.FEET; - case GLOV: return BodyLoc.GLOV; - default: - throw new GdxRuntimeException("Invalid slot: " + slot); - } - } - } - - D2S d2s; - boolean alternate; - EnumMap equipped = new EnumMap<>(BodyLoc.class); - Array inventory = new Array<>(); - final Set SLOT_LISTENERS = new CopyOnWriteArraySet<>(); - public Stats stats; - - - public Player(String name, CharClass clazz) { - super(Diablo.files.PlrType.get(clazz.id).Token, EntType.CHARS); - throw new UnsupportedOperationException(); - } - - public Player(D2S d2s) { - super(Diablo.files.PlrType.get(d2s.charClass).Token, EntType.CHARS); - this.d2s = d2s; - this.stats = new Stats(); - equipped.putAll(d2s.items.equipped); - inventory.addAll(d2s.items.inventory); - setMode("TN"); - - for (Map.Entry entry : equipped.entrySet()) { - entry.getValue().load(); - //if (DEBUG_EQUIPPED) Gdx.app.debug(TAG, entry.getKey() + ": " + entry.getValue()); - } - - for (Item item : inventory) { - item.load(); - //if (DEBUG_INVENTORY) Gdx.app.debug(TAG, item.gridX + "," + item.gridY + ": " + item); - } - } - - public Item getSlot(Slot slot) { - BodyLoc loc = slot.toBodyLoc(alternate); - return getSlot(loc); - } - - public Item getSlot(BodyLoc loc) { - return equipped.get(loc); - } - - public Item setSlot(Slot slot, Item item) { - Preconditions.checkState(item == null || getSlot(slot) == null, "Slot must be empty first!"); - BodyLoc loc = slot.toBodyLoc(alternate); - return setSlot(loc, item); - } - - public Item setSlot(BodyLoc loc, Item item) { - Item oldItem = equipped.put(loc, item); - - //invalidate(); - //setArmType(slot, item.base.alternateGfx); - int components = loc.components(); - if (components > 0) dirty |= components; - updateWeaponClass(); - - notifySlotChanged(loc, oldItem, item); - return oldItem; - } - - @Override - protected Item getItem(Component component) { - switch (component) { - case HD: return getSlot(Slot.HEAD); - case TR: - case RA: - case LA: - case S1: - case S2: return getSlot(Slot.TORS); - // TODO: Shield/weapons? - default: return super.getItem(component); - } - } - - public boolean isAlternate() { - return alternate; - } - - public void setAlternate(boolean b) { - if (alternate != b) { - alternate = b; - updateWeaponClass(); - Item LH = getSlot(BodyLoc.LARM); - Item RH = getSlot(BodyLoc.RARM); - Item LH2 = getSlot(BodyLoc.LARM2); - Item RH2 = getSlot(BodyLoc.RARM2); - if (b) { - notifyAlternate(LH2, RH2); - } else { - notifyAlternate(LH, RH); - } - } - } - - @Override - protected COFD2 getCOFs() { - return Diablo.cofs.chars_cof; - } - - public void update() { - updateWeaponClass(); - - Item head = getSlot(Slot.HEAD); - setArmType(Component.HD, head != null ? head.base.alternateGfx : "LIT"); - - Item body = getSlot(Slot.TORS); - if (body != null) { - Armor.Entry armor = body.getBase(); - setArmType(Component.TR, Diablo.files.ArmType.get(armor.Torso).Token); - setArmType(Component.LG, Diablo.files.ArmType.get(armor.Legs ).Token); - setArmType(Component.RA, Diablo.files.ArmType.get(armor.rArm ).Token); - setArmType(Component.LA, Diablo.files.ArmType.get(armor.lArm ).Token); - setArmType(Component.S1, Diablo.files.ArmType.get(armor.lSPad).Token); - setArmType(Component.S2, Diablo.files.ArmType.get(armor.rSPad).Token); - } else { - setArmType(Component.TR, DEFAULT_LAYER); - setArmType(Component.LG, DEFAULT_LAYER); - setArmType(Component.RA, DEFAULT_LAYER); - setArmType(Component.LA, DEFAULT_LAYER); - setArmType(Component.S1, DEFAULT_LAYER); - setArmType(Component.S2, DEFAULT_LAYER); - } - - super.update(); - } - - private void updateWeaponClass() { - Item RH = null, LH = null, SH = null; - Item rArm = getSlot(Slot.RARM); - if (rArm != null) { - if (rArm.type.is("weap")) { - RH = rArm; - } else if (rArm.type.is("shld")) { - SH = rArm; - } - } - - Item lArm = getSlot(Slot.LARM); - if (lArm != null) { - if (lArm.type.is("weap")) { - LH = lArm; - } else if (lArm.type.is("shld")) { - SH = lArm; - } - } - - if (DEBUG_WCLASS) { - Gdx.app.debug(TAG, "RH = " + RH); - Gdx.app.debug(TAG, "LH = " + LH); - Gdx.app.debug(TAG, "SH = " + SH); - } - - if (LH != null && RH != null) { - Weapons.Entry LHEntry = LH.getBase(); - Weapons.Entry RHEntry = RH.getBase(); - if ( LHEntry.wclass.equals("1hs") && RHEntry.wclass.equals("1hs")) { - setWeaponClass("1SS"); // Left Swing Right Swing - } else if (LHEntry.wclass.equals("1hs") && RHEntry.wclass.equals("1ht")) { - setWeaponClass("1ST"); // Left Swing Right Thrust - } else if (LHEntry.wclass.equals("1ht") && RHEntry.wclass.equals("1hs")) { - setWeaponClass("1JS"); // Left Jab Right Swing - } else if (LHEntry.wclass.equals("1ht") && RHEntry.wclass.equals("1ht")) { - setWeaponClass("1JT"); // Left Jab Right Thrust - } else if (LH.type.is("miss") || RH.type.is("miss")) { - setWeaponClass(LH.type.is("miss") ? LHEntry.wclass : RHEntry.wclass); - } else if (LH.type.is("h2h") || RH.type.is("h2h")) { - setWeaponClass("HT2"); // Two Hand-to-Hand - } else { - setWeaponClass("HTH"); - Gdx.app.error(TAG, String.format( - "Unknown weapon combination: LH=%s RH=%s", LHEntry.wclass, RHEntry.wclass)); - } - } else if (LH != null || RH != null) { - RH = ObjectUtils.firstNonNull(RH, LH); - LH = null; - if (RH.type.is("bow")) { - LH = RH; - RH = null; - Weapons.Entry LHEntry = LH.getBase(); - setWeaponClass(LHEntry.wclass); - } else if (RH.type.is("weap")) { // make sure weap and not e.g. misl, might not be required - Weapons.Entry RHEntry = RH.getBase(); - setWeaponClass(RHEntry.wclass); - } else { - setWeaponClass("HTH"); - } - } else { - setWeaponClass("HTH"); - } - - setArmType(Component.RH, RH != null ? RH.base.alternateGfx : ""); - setArmType(Component.LH, LH != null ? LH.base.alternateGfx : ""); - setArmType(Component.SH, SH != null ? SH.base.alternateGfx : ""); - } - - private void notifySlotChanged(BodyLoc bodyLoc, Item oldItem, Item item) { - for (SlotListener l : SLOT_LISTENERS) l.onChanged(this, bodyLoc, oldItem, item); - } - - private void notifyAlternate(Item LH, Item RH) { - for (SlotListener l : SLOT_LISTENERS) l.onAlternate(this, LH, RH); - } - - public boolean addSlotListener(SlotListener l) { - boolean added = SLOT_LISTENERS.add(l); - return added; - } - - public boolean containsSlotListener(Object o) { - return o != null && SLOT_LISTENERS.contains(o); - } - - public boolean removeSlotListener(Object o) { - return o != null && SLOT_LISTENERS.remove(o); - } - - public boolean clearSlotListeners() { - boolean empty = SLOT_LISTENERS.isEmpty(); - SLOT_LISTENERS.clear(); - return !empty; - } - - public interface SlotListener { - void onChanged(Player player, BodyLoc bodyLoc, Item oldItem, Item item); - void onAlternate(Player player, Item LH, Item RH); - } - - public static class SlotAdapter implements SlotListener { - @Override public void onChanged(Player player, BodyLoc bodyLoc, Item oldItem, Item item) {} - @Override public void onAlternate(Player player, Item LH, Item RH) {} - } - - public Array getInventory() { - return inventory; - } - - public class Stats { - public int getClassId() { - return d2s.charClass; - } - - public CharClass getCharClass() { - return CharClass.get(d2s.charClass); - } - - public String getName() { - return d2s.name; - } - - public int getLevel() { - return d2s.stats.level; - } - - public long getExperience() { - return d2s.stats.xp; - } - - public int getStrength() { - return d2s.stats.strength; - } - - public int getDexterity() { - return d2s.stats.dexterity; - } - - public int getVitality() { - return d2s.stats.vitality; - } - - public int getEnergy() { - return d2s.stats.energy; - } - - public int getFireResistance() { - return 0; - } - - public int getColdResistance() { - return 0; - } - - public int getLightningResistance() { - return 0; - } - - public int getPoisonResistance() { - return 0; - } - } -} diff --git a/core/src/gdx/diablo/map2/DS1.java b/core/src/gdx/diablo/map2/DS1.java deleted file mode 100644 index 75c5bba4..00000000 --- a/core/src/gdx/diablo/map2/DS1.java +++ /dev/null @@ -1,589 +0,0 @@ -package gdx.diablo.map2; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.math.GridPoint2; -import com.badlogic.gdx.utils.GdxRuntimeException; -import com.badlogic.gdx.utils.IntMap; -import com.badlogic.gdx.utils.StreamUtils; - -import org.apache.commons.io.EndianUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.builder.ToStringBuilder; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; - -import gdx.diablo.util.BufferUtils; - -public class DS1 { - private static final String TAG = "DS1"; - private static final boolean DEBUG = true; - private static final boolean DEBUG_FILES = DEBUG && true; - private static final boolean DEBUG_SIZES = DEBUG && true; - private static final boolean DEBUG_LAYERS = DEBUG && true; - private static final boolean DEBUG_CELLS = DEBUG && !true; - private static final boolean DEBUG_OBJECTS = DEBUG && true; - private static final boolean DEBUG_GROUPS = DEBUG && true; - private static final boolean DEBUG_PATHS = DEBUG && true; - private static final boolean DEBUG_STREAM = DEBUG && true; - private static final boolean DEBUG_PROPS = DEBUG && true; - - private static final int ACT_MAX = 5; - private static final int DWORD = 4; - - public static final int MAX_FLOOR_LAYERS = 2; - public static final int MAX_SHADOW_LAYERS = 1; - public static final int MAX_WALL_LAYERS = 4; - - public static final int FLOOR_OFFSET = 0; - public static final int SHADOW_OFFSET = FLOOR_OFFSET + MAX_FLOOR_LAYERS; - public static final int WALL_OFFSET = SHADOW_OFFSET + MAX_SHADOW_LAYERS; - public static final int MAX_LAYERS = WALL_OFFSET + MAX_WALL_LAYERS; - - public static final int WALL_LAYER = 1; - public static final int ORIENT_LAYER = 5; - public static final int FLOOR_LAYER = 9; - public static final int SHADOW_LAYER = 11; - public static final int TAG_LAYER = 12; - public static final int STREAM_LAYERS = 12; - - public static final int WALL_LAYER_1 = WALL_LAYER; - public static final int WALL_LAYER_2 = WALL_LAYER + 1; - public static final int WALL_LAYER_3 = WALL_LAYER + 2; - public static final int WALL_LAYER_4 = WALL_LAYER + 3; - - public static final int ORIENT_LAYER_1 = ORIENT_LAYER; - public static final int ORIENT_LAYER_2 = ORIENT_LAYER + 1; - public static final int ORIENT_LAYER_3 = ORIENT_LAYER + 2; - public static final int ORIENT_LAYER_4 = ORIENT_LAYER + 3; - - public static final int FLOOR_LAYER_1 = FLOOR_LAYER; - public static final int FLOOR_LAYER_2 = FLOOR_LAYER + 1; - - private static final short ORIENTATION_TABLE[] = { - 0x00, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03, 0x05, 0x05, 0x06, - 0x06, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0F, 0x10, 0x11, 0x12, 0x14 - }; - - int version; - int width; - int height; - int act; - int tagType; - - int numFiles; - String files[]; - - int numWalls; - int numFloors; - int numTags; - int numShadows; - - int numLayers; - int layerStream[]; - - int wallLine, wallLen; - Cell walls[]; - - int floorLine, floorLen; - Cell floors[]; - - int shadowLine, shadowLen; - Cell shadows[]; - - int tagLine, tagLen; - int tags[]; - - int numObjects; - Object objects[]; - - int numGroups; - Group groups[]; - - int numPaths; - Path paths[]; - - IntMap specials; - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("version", version) - .append("width", width) - .append("height", height) - .append("act", act) - .append("tagType", tagType) - .append("numFiles", numFiles) - .append("numWalls", numWalls) - .append("numFloors", numFloors) - .append("numTags", numTags) - .append("numShadows", numShadows) - .append("layerStream", Arrays.toString(Arrays.copyOf(layerStream, numLayers))) - .append("floorLine", floorLine) - .append("floorLen", floorLen) - .append("shadowLine", shadowLine) - .append("shadowLen", shadowLen) - .append("tagLine", tagLine) - .append("tagLen", tagLen) - .append("wallLine", wallLine) - .append("wallLen", wallLen) - .append("numObjects", numObjects) - .append("numGroups", numGroups) - .append("numPaths", numPaths) - .toString(); - } - - public GridPoint2 find(int id) { - return specials.get(id); - } - - public GridPoint2 find(int orientation, int mainIndex, int subIndex) { - int id = DT1.Tile.Index.create(orientation, mainIndex, subIndex); - return find(id); - } - - public static DS1 loadFromFile(FileHandle handle) { - return loadFromStream(handle.read()); - } - - public static DS1 loadFromStream(InputStream in) { - try { - DS1 ds1 = new DS1().read(in); - if (DEBUG) Gdx.app.debug(TAG, ds1.toString()); - if (ds1.version < 9 || 13 < ds1.version) { - // FIXME: version 9 <= 13 causes crash here /w 4B remaining, why? - assert in.available() == 0 : in.available() + "B available!"; - } else if (DEBUG_STREAM && in.available() > 0) { - Gdx.app.error(TAG, in.available() + "B still available in stream!"); - } - - return ds1; - } catch (Throwable t) { - throw new GdxRuntimeException("Couldn't read DS1.", t); - } finally { - StreamUtils.closeQuietly(in); - } - } - - private DS1 read(InputStream in) throws IOException { - version = EndianUtils.readSwappedInteger(in); - width = EndianUtils.readSwappedInteger(in) + 1; - height = EndianUtils.readSwappedInteger(in) + 1; - act = version < 8 ? 1 : Math.min(EndianUtils.readSwappedInteger(in) + 1, ACT_MAX); - tagType = version < 10 ? 0 : EndianUtils.readSwappedInteger(in); - numFiles = version < 3 ? 0 : EndianUtils.readSwappedInteger(in); - files = numFiles == 0 ? ArrayUtils.EMPTY_STRING_ARRAY : new String[numFiles]; - for (int i = 0; i < numFiles; i++) { - files[i] = BufferUtils.readString(in); - if (DEBUG_FILES) Gdx.app.debug(TAG, "file[" + i + "] = " + files[i]); - } - if (9 <= version && version <= 13) IOUtils.skipFully(in, 2 * DWORD); - if (version < 4) { - numWalls = 1; - numFloors = 1; - numTags = 1; - numShadows = 1; - } else { - numWalls = EndianUtils.readSwappedInteger(in); - numFloors = version < 16 ? 1 : EndianUtils.readSwappedInteger(in); - numTags = (tagType == 1 || tagType == 2) ? 1 : 0; - numShadows = 1; - } - - if (DEBUG_SIZES) Gdx.app.debug(TAG, String.format("layers: (2 * %d walls) + %d floors + %d shadow + %d tag", numWalls, numFloors, numShadows, numTags)); - - layerStream = new int[STREAM_LAYERS]; - if (version < 4) { - numLayers = 5; - layerStream[0] = WALL_LAYER; - layerStream[1] = FLOOR_LAYER; - layerStream[2] = ORIENT_LAYER; - layerStream[3] = TAG_LAYER; - layerStream[4] = SHADOW_LAYER; - } else { - numLayers = 0; - for (int i = 0; i < numWalls; i++) { - layerStream[numLayers++] = WALL_LAYER + i; - layerStream[numLayers++] = ORIENT_LAYER + i; - } - for (int i = 0; i < numFloors; i++) { - layerStream[numLayers++] = FLOOR_LAYER + i; - } - if (numShadows > 0) { - layerStream[numLayers++] = SHADOW_LAYER; - } - if (numTags > 0) { - layerStream[numLayers++] = TAG_LAYER; - } - } - - floorLine = width * numFloors; - floorLen = floorLine * height; - floors = new Cell[floorLen]; - int floorOffset[] = new int[numFloors]; - for (int i = 0; i < numFloors; i++) { - floorOffset[i] = i; - } - - shadowLine = width * numShadows; - shadowLen = shadowLine * height; - shadows = new Cell[shadowLen]; - int shadowOffset[] = new int[numShadows]; - for (int i = 0; i < numShadows; i++) { - shadowOffset[i] = i; - } - - tagLine = width * numTags; - tagLen = tagLine * height; - tags = new int[tagLen]; - int tagOffset[] = new int[numTags]; - for (int i = 0; i < numTags; i++) { - tagOffset[i] = i; - } - - wallLine = width * numWalls; - wallLen = wallLine * height; - walls = new Cell[wallLen]; - int wallOffset[] = new int[numWalls], orientationOffset[] = new int[numWalls]; - for (int i = 0; i < numWalls; i++) { - wallOffset[i] = orientationOffset[i] = i; - } - - if (DEBUG_LAYERS) Gdx.app.debug(TAG, "floorLine=" + floorLine + "; floorLen=" + floorLen); - if (DEBUG_LAYERS) Gdx.app.debug(TAG, "shadowLine=" + shadowLine + "; shadowLen=" + shadowLen); - if (DEBUG_LAYERS) Gdx.app.debug(TAG, "tagLine=" + tagLine + "; tagLen=" + tagLen); - if (DEBUG_LAYERS) Gdx.app.debug(TAG, "wallLine=" + wallLine + "; wallLen=" + wallLen); - if (DEBUG_LAYERS) Gdx.app.debug(TAG, "layerStream=" + Arrays.toString(Arrays.copyOf(layerStream, numLayers))); - - specials = new IntMap<>(); - for (int l = 0, layer, i, id; l < numLayers; l++) { - layer = layerStream[l]; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - switch (layer) { - // wall - case WALL_LAYER_1: case WALL_LAYER_2: case WALL_LAYER_3: case WALL_LAYER_4: - i = layer - WALL_LAYER; - id = wallOffset[i]; - assert walls[id] == null; - walls[id] = new Cell().read(in); - wallOffset[i] += numWalls; - break; - - // orientation - case ORIENT_LAYER_1: case ORIENT_LAYER_2: case ORIENT_LAYER_3: case ORIENT_LAYER_4: - i = layer - ORIENT_LAYER; - id = orientationOffset[i]; - Cell wall = walls[id]; - assert wall != null; - int j = EndianUtils.readSwappedInteger(in); - wall.setOrientation(version < 7 ? ORIENTATION_TABLE[j] : j); - orientationOffset[i] += numWalls; - - if (!Orientation.isSpecial(wall.orientation)) { - break; - } - - specials.put(wall.id, new GridPoint2(x, y)); - if (DEBUG_PROPS) { - int mainIndex = (wall.value & 0x03F00000) >>> 20; - int subIndex = (wall.value & 0x0000FF00) >>> 8; - int first = (wall.value & 0xFC000000) >>> 26; - int second = (wall.value & 0x000F0000) >>> 16; - int third = (wall.value & 0x000000FF); - Gdx.app.debug(TAG, String.format("%d (%2d,%2d) %08X %2d,%2d,%2d %02X %02X %X %02X %02X", - l, x, y, wall.value, - mainIndex, wall.orientation, subIndex, - first, mainIndex, second, subIndex, third)); - } - break; - - // floor - case FLOOR_LAYER_1: case FLOOR_LAYER_2: - i = layer - FLOOR_LAYER; - id = floorOffset[i]; - assert floors[id] == null; - floors[id] = new Cell().read(in); - floorOffset[i] += numFloors; - break; - - // shadow - case SHADOW_LAYER: - i = layer - SHADOW_LAYER; - id = shadowOffset[i]; - assert shadows[id] == null; - shadows[id] = new Cell().read(in); - shadowOffset[i] += numShadows; - break; - - // tag - case TAG_LAYER: - i = layer - TAG_LAYER; - id = tagOffset[i]; - tags[id] = EndianUtils.readSwappedInteger(in); - tagOffset[i] += numTags; - break; - - // error - default: - Gdx.app.error(TAG, "Unknown layer: " + layer); - } - } - } - } - - if (DEBUG_CELLS) { - for (int i = 0; i < wallLen; i++) Gdx.app.debug(TAG, "walls[" + i + "]=" + walls[i].toString()); - for (int i = 0; i < floorLen; i++) Gdx.app.debug(TAG, "floors[" + i + "]=" + floors[i].toString()); - for (int i = 0; i < shadowLen; i++) Gdx.app.debug(TAG, "shadows[" + i + "]=" + shadows[i].toString()); - Gdx.app.debug(TAG, "tags=" + Arrays.toString(tags)); - } - - int maxSubtileWidth = width * 5; - int maxSubtileHeight = height * 5; - - numObjects = version < 2 ? 0 : EndianUtils.readSwappedInteger(in); - objects = numObjects == 0 ? Object.EMPTY_OBJECT_ARRAY : new Object[numObjects]; - for (int i = 0; i < numObjects; i++) { - try { - Object object = objects[i] = new Object().read(version, in); - if (DEBUG_OBJECTS) Gdx.app.debug(TAG, object.toString()); - if (object.x < 0 || maxSubtileWidth <= object.x - || object.y < 0 || maxSubtileHeight <= object.y) { - Gdx.app.error(TAG, "Object out of DS1 bounds: " + object); - } - } catch (Throwable t) { - // Don't care, invalid object, skip it. Log it for posterity. - Gdx.app.error(TAG, t.getMessage(), t); - } - } - - if (version >= 12 && (tagType == 1 || tagType == 2)) { - if (version >= 18) IOUtils.skip(in, DWORD); - numGroups = EndianUtils.readSwappedInteger(in); - groups = numGroups == 0 ? Group.EMPTY_GROUP_ARRAY : new Group[numGroups]; - for (int i = 0; i < numGroups; i++) { - groups[i] = new Group().read(version, in); - if (DEBUG_GROUPS) Gdx.app.debug(TAG, groups[i].toString()); - } - } else { - numGroups = 0; - groups = Group.EMPTY_GROUP_ARRAY; - } - - if (version >= 14 && in.available() >= DWORD) { - numPaths = EndianUtils.readSwappedInteger(in); - paths = numPaths == 0 ? Path.EMPTY_PATH_ARRAY : new Path[numPaths]; - for (int i = 0; i < numPaths; i++) { - Path path = paths[i] = new Path().read(version, objects, in); - if (DEBUG_PATHS) Gdx.app.debug(TAG, path.toString()); - } - } else { - numPaths = 0; - paths = Path.EMPTY_PATH_ARRAY; - } - - width -= 1; - height -= 1; - return this; - } - - static class Cell { - // 0x03F00000 - private static final int MAIN_INDEX_OFFSET = 20; - private static final int MAIN_INDEX_BITS = 0x3F; - - // 0x0000FF00 - private static final int SUB_INDEX_OFFSET = 8; - private static final int SUB_INDEX_BITS = 0xFF; - - public static final int MASK_MAIN_INDEX = MAIN_INDEX_BITS << MAIN_INDEX_OFFSET; - public static final int SUB_MAIN_INDEX = SUB_INDEX_BITS << SUB_INDEX_OFFSET; - public static final int MASK_UNWALKABLE = 0x00020000; - - int id; - int value; - - short mainIndex; - short subIndex; - short orientation; - - Cell read(InputStream in) throws IOException { - value = EndianUtils.readSwappedInteger(in); - mainIndex = (short) ((value >>> MAIN_INDEX_OFFSET) & MAIN_INDEX_BITS); - subIndex = (short) ((value >>> SUB_INDEX_OFFSET) & SUB_INDEX_BITS); - orientation = Orientation.FLOOR; - id = DT1.Tile.Index.create(orientation, mainIndex, subIndex); - return updateIndex(); - } - - void setOrientation(int orientation) { - this.orientation = (short) orientation; - updateIndex(); - } - - Cell updateIndex() { - id = DT1.Tile.Index.create(orientation, mainIndex, subIndex); - return this; - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", Integer.toHexString(id)) - .append("value", Integer.toHexString(value)) - .append("mainIndex", mainIndex) - .append("subIndex", subIndex) - .append("orientation", orientation) - .build(); - } - } - - public static class Object { - public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; - - public static final int DYNAMIC_TYPE = 1; - public static final int STATIC_TYPE = 2; - - int type; - int id; - int x; - int y; - int ds1Flags; - - Object read(int version, InputStream in) throws IOException { - type = EndianUtils.readSwappedInteger(in); - id = EndianUtils.readSwappedInteger(in); - x = EndianUtils.readSwappedInteger(in); - y = EndianUtils.readSwappedInteger(in); - ds1Flags = version < 6 ? 0 : EndianUtils.readSwappedInteger(in); - return this; - } - - String getType() { - switch (type) { - case DYNAMIC_TYPE: return "DYNAMIC_TYPE"; - case STATIC_TYPE: return "STATIC_TYPE"; - default: return Integer.toString(type); - } - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("type", getType()) - .append("id", id) - .append("x", x) - .append("y", y) - .append("ds1Flags", "0x" + Integer.toHexString(ds1Flags)) - .build(); - } - } - - static class Group { - public static final Group[] EMPTY_GROUP_ARRAY = new Group[0]; - - int x; - int y; - int width; - int height; - int unk; - - Group read(int version, InputStream in) throws IOException { - if (in.available() >= DWORD) x = EndianUtils.readSwappedInteger(in); - if (in.available() >= DWORD) y = EndianUtils.readSwappedInteger(in); - if (in.available() >= DWORD) width = EndianUtils.readSwappedInteger(in); - if (in.available() >= DWORD) height = EndianUtils.readSwappedInteger(in); - if (version >= 13) { - if (in.available() >= DWORD) unk = EndianUtils.readSwappedInteger(in); - } - return this; - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("x", x) - .append("y", y) - .append("width", width) - .append("height", height) - .append("unk", unk) - .build(); - } - } - - public static class Path { - public static final Path[] EMPTY_PATH_ARRAY = new Path[0]; - - int numPoints; - Point points[]; - - int x; - int y; - - Path read(int version, Object[] objects, InputStream in) throws IOException { - numPoints = EndianUtils.readSwappedInteger(in); - points = new Point[numPoints]; - x = EndianUtils.readSwappedInteger(in); - y = EndianUtils.readSwappedInteger(in); - - Object object = null; - for (int i = 0; i < objects.length; i++) { - Object tmp = objects[i]; - if (tmp == null) continue; - if (tmp.x != x || tmp.y != y) continue; - if (object != null) Gdx.app.error(TAG, "More than one object is located at path position: " + this); - object = tmp; - } - - if (object == null) { - Gdx.app.error(TAG, "No object associated with path: " + this); - int skip = version >= 15 ? 12 : 8; - for (int p = 0; p < numPoints; p++) { - in.skip(skip); - } - - return this; - } - - for (int p = 0; p < numPoints; p++) points[p] = new Point().read(version, in); - return this; - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("x", x) - .append("y", y) - .append("numPoints", numPoints) - .append("points", Arrays.toString(points)) - .build(); - } - - static class Point { - int x; - int y; - int action; - - Point read(int version, InputStream in) throws IOException { - x = EndianUtils.readSwappedInteger(in); - y = EndianUtils.readSwappedInteger(in); - action = version < 15 ? 1 : EndianUtils.readSwappedInteger(in); - return this; - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("x", x) - .append("y", y) - .append("action", action) - .build(); - } - } - } -} diff --git a/core/src/gdx/diablo/map2/DS1Loader.java b/core/src/gdx/diablo/map2/DS1Loader.java deleted file mode 100644 index 37cb29c5..00000000 --- a/core/src/gdx/diablo/map2/DS1Loader.java +++ /dev/null @@ -1,43 +0,0 @@ -package gdx.diablo.map2; - -import com.badlogic.gdx.assets.AssetDescriptor; -import com.badlogic.gdx.assets.AssetLoaderParameters; -import com.badlogic.gdx.assets.AssetManager; -import com.badlogic.gdx.assets.loaders.AsynchronousAssetLoader; -import com.badlogic.gdx.assets.loaders.FileHandleResolver; -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.utils.Array; - -public class DS1Loader extends AsynchronousAssetLoader { - - DS1 ds1; - - public DS1Loader(FileHandleResolver resolver) { - super(resolver); - } - - @Override - public void loadAsync(AssetManager assets, String fileName, FileHandle file, DS1LoaderParameters params) { - ds1 = DS1.loadFromStream(file.read()); - } - - @Override - public DS1 loadSync(AssetManager assets, String fileName, FileHandle file, DS1LoaderParameters params) { - DS1 ds1 = this.ds1; - if (ds1 == null) { - ds1 = DS1.loadFromStream(file.read()); - } else { - this.ds1 = null; - } - - return ds1; - } - - @Override - public Array getDependencies(String fileName, FileHandle file, DS1LoaderParameters params) { - return null; - } - - public static class DS1LoaderParameters extends AssetLoaderParameters {} - -} diff --git a/core/src/gdx/diablo/map2/DT1.java b/core/src/gdx/diablo/map2/DT1.java deleted file mode 100644 index df6b7f7a..00000000 --- a/core/src/gdx/diablo/map2/DT1.java +++ /dev/null @@ -1,501 +0,0 @@ -package gdx.diablo.map2; - -import com.google.common.base.Preconditions; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.graphics.glutils.PixmapTextureData; -import com.badlogic.gdx.utils.Disposable; -import com.badlogic.gdx.utils.GdxRuntimeException; -import com.badlogic.gdx.utils.StreamUtils; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.builder.ToStringBuilder; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Arrays; - -import gdx.diablo.Diablo; -import gdx.diablo.codec.Palette; -import gdx.diablo.graphics.PaletteIndexedPixmap; -import gdx.diablo.util.BufferUtils; - -// TODO: In production, skip unused data (zeros/unknowns) -public class DT1 implements Disposable { - private static final String TAG = "DT1"; - private static final boolean DEBUG = true; - private static final boolean DEBUG_TILE_HEADERS = DEBUG && !true; - private static final boolean DEBUG_BLOCK_HEADERS = DEBUG && !true; - - private static final int X_JUMP[] = { 14, 12, 10, 8, 6, 4, 2, 0, 2, 4, 6, 8, 10, 12, 14 }; - private static final int PIXEL_WIDTH[] = { 4, 8, 12, 16, 20, 24, 28, 32, 28, 24, 20, 16, 12, 8, 4 }; - - String fileName; - Header header; - Tile tiles[]; - Texture textures[]; - - private DT1(String fileName, Header header, Tile[] tiles) { - this.fileName = fileName; - this.header = header; - this.tiles = tiles; - Diablo.dt1s.add(this); - } - - public int getVersion1() { - return header.version1; - } - - public int getVersion2() { - return header.version2; - } - - public int getNumTiles() { - return header.numTiles; - } - - public Tile getTile(int i) { - return tiles[i]; - } - - @Override - public void dispose() { - if (textures == null) return; - for (Texture texture : textures) texture.dispose(); - Diablo.dt1s.remove(this); - } - - public TextureRegion getTexture(int i) { - return new TextureRegion(textures[i]); - } - - public void prepareTextures() { - Preconditions.checkState(textures == null, "textures have already been prepared"); - textures = new Texture[header.numTiles]; - for (int i = 0; i < header.numTiles; i++) { - Texture texture = new Texture(new PixmapTextureData(tiles[i].pixmap, null, false, false, false)); - //texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear); - texture.setWrap(Texture.TextureWrap.ClampToEdge, Texture.TextureWrap.ClampToEdge); - textures[i] = tiles[i].texture = texture; - } - } - - public static DT1 loadFromFile(FileHandle handle) { - return loadFromStream(handle.path(), handle.read()); - } - - public static DT1 loadFromStream(String fileName, InputStream in) { - try { - Header header = new Header(in); - if (DEBUG) Gdx.app.debug(TAG, header.toString()); - - if (header.version1 != 0x7) - throw new GdxRuntimeException("Unknown version1: " + header.version1); - if (header.version2 != 0x6) - throw new GdxRuntimeException("Unknown version2: " + header.version2); - - Tile[] tiles = new Tile[header.numTiles]; - for (int i = 0; i < header.numTiles; i++) { - Tile tile = tiles[i] = new Tile(in); - if (DEBUG_TILE_HEADERS) Gdx.app.debug(TAG, tile.toString()); - } - - for (Tile tile : tiles) { - Block[] blockHeaders = tile.blocks = new Block[tile.numBlocks]; - for (int i = 0; i < tile.numBlocks; i++) { - blockHeaders[i] = new Block(in); - if (DEBUG_BLOCK_HEADERS) Gdx.app.debug(TAG, blockHeaders[i].toString()); - } - - for (Block blockHeader : blockHeaders) { - blockHeader.colormap = IOUtils.readFully(in, blockHeader.length); - } - - tile.createPixmap(); - } - - assert in.available() == 0; - return new DT1(fileName, header, tiles); - } catch (Throwable t) { - throw new GdxRuntimeException("Couldn't read DT1", t); - } finally { - StreamUtils.closeQuietly(in); - } - } - - private static boolean allZeros(byte[] zeros) { - for (byte b : zeros) { - if (b != 0) return false; - } - - return true; - } - - static class Header { - static final int SIZE = 276; - - int version1; - int version2; - byte zeros[]; - int numTiles; - int tileOffset; - - Header(InputStream in) throws IOException { - ByteBuffer buffer = ByteBuffer.wrap(IOUtils.readFully(in, SIZE)).order(ByteOrder.LITTLE_ENDIAN); - version1 = buffer.getInt(); - version2 = buffer.getInt(); - zeros = BufferUtils.readBytes(buffer, 260); - numTiles = buffer.getInt(); - tileOffset = buffer.getInt(); - assert !buffer.hasRemaining(); - assert allZeros(zeros) : "Expected 260 zeros, got: " + Arrays.toString(zeros); - assert tileOffset == SIZE : "Expected first tile header to be located at 276: " + tileOffset; - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("version1", version1) - .append("version2", version2) - //.append("zeros", Arrays.toString(zeros)) - .append("numTiles", numTiles) - .append("tileOffset", "0x" + Integer.toHexString(tileOffset)) - .toString(); - } - } - - public static class Tile { - static final int SIZE = 96; - - public static final int WIDTH = 160; - public static final int HEIGHT = 80; - - public static final int SUBTILE_SIZE = 5; - public static final int NUM_SUBTILES = SUBTILE_SIZE * SUBTILE_SIZE; - - public static final int SUBTILE_WIDTH = WIDTH / SUBTILE_SIZE; - public static final int SUBTILE_HEIGHT = HEIGHT / SUBTILE_SIZE; - - public static final int[][] SUBTILE_INDEX/* = { - {0, 5, 10, 15, 20}, - {1, 6, 11, 16, 21}, - {2, 7, 12, 17, 22}, - {3, 8, 13, 18, 23}, - {4, 9, 14, 19, 24}, - }*/; - static { - SUBTILE_INDEX = new int[SUBTILE_SIZE][SUBTILE_SIZE]; - for (int y = 0, i = 0; y < SUBTILE_SIZE; y++) { - for (int x = 0; x < SUBTILE_SIZE; x++, i++) { - SUBTILE_INDEX[x][y] = i; - } - } - } - - public static final int[][] SUBTILE_OFFSET/* = { - {64, 64}, {80, 56}, {96, 48}, {112, 40}, {128, 32}, - {48, 56}, {64, 48}, {80, 40}, { 96, 32}, {112, 24}, - {32, 48}, {48, 40}, {64, 32}, { 80, 24}, { 96, 16}, - {16, 40}, {32, 32}, {48, 24}, { 64, 16}, { 80, 8}, - { 0, 32}, {16, 24}, {32, 16}, { 48, 8}, { 64, 0}, - }*/; - static { - SUBTILE_OFFSET = new int[NUM_SUBTILES][2]; - final int halfSubtileWidth = SUBTILE_WIDTH / 2; - final int halfSubtileHeight = SUBTILE_HEIGHT / 2; - for (int y = 0, i = 0; y < SUBTILE_SIZE; y++) { - int px = (WIDTH / 2) - halfSubtileWidth - (y * halfSubtileWidth); - int py = HEIGHT - SUBTILE_HEIGHT - (y * halfSubtileHeight); - for (int x = 0; x < SUBTILE_SIZE; x++, i++) { - SUBTILE_OFFSET[i][0] = px; - SUBTILE_OFFSET[i][1] = py; - px += halfSubtileWidth; - py -= halfSubtileHeight; - } - } - } - - public static final int FLAG_BLOCK_WALK = 1 << 0; - public static final int FLAG_BLOCK_LIGHT_LOS = 1 << 1; - public static final int FLAG_BLOCK_JUMP = 1 << 2; - public static final int FLAG_BLOCK_PLAYER_WALK = 1 << 3; - public static final int FLAG_BLOCK_UNKNOWN1 = 1 << 4; - public static final int FLAG_BLOCK_LIGHT = 1 << 5; - public static final int FLAG_BLOCK_UNKNOWN2 = 1 << 6; - public static final int FLAG_BLOCK_UNKNOWN3 = 1 << 7; - - public int direction; - public short roofHeight; - public byte soundIndex; - public byte animated; - public int height; - public int width; - public byte zeros1[]; - public int orientation; - public int mainIndex; - public int subIndex; - public int rarity; // frame index if animated - public byte unknown[]; - public byte tileFlags[]; - public byte zeros2[]; - public int blockHeadersPointer; - public int blockDataLength; - public int numBlocks; - public byte zeros3[]; - - Block blocks[]; - Pixmap pixmap; - Texture texture; - int id; - - /** - * zeros3 is not all zeros all of the time. This might correlate with unknown. I need to figure - * out what these variables mean, I'm fairly certain zeros3 is 3 ints, or at least the second - * 4 bytes are used somewhere. - * - * data\global\tiles\expansion\Town\shrine.dt1 - * data\global\tiles\expansion\Town\trees.dt1 - * - * unknown in above is same F6 62 FF 00 (16737014) - * but zeros3 is different: - * 00 00 00 00 00 00 00 00 00 00 00 00 - * 00 00 00 00 6C B0 08 0B 00 00 00 00 - * - * data\global\tiles\expansion\Town\tent.dt1 - * F3 65 FF 00 (16737779) - * 00 00 00 00 4C 00 37 0B 00 00 00 00 - */ - Tile(InputStream in) throws IOException { - ByteBuffer buffer = ByteBuffer.wrap(IOUtils.readFully(in, SIZE)).order(ByteOrder.LITTLE_ENDIAN); - direction = buffer.getInt(); - roofHeight = buffer.getShort(); - soundIndex = buffer.get(); - animated = buffer.get(); - height = buffer.getInt(); - width = buffer.getInt(); - zeros1 = BufferUtils.readBytes(buffer, 4); - orientation = buffer.getInt(); - mainIndex = buffer.getInt(); - subIndex = buffer.getInt(); - rarity = buffer.getInt(); - unknown = BufferUtils.readBytes(buffer, 4); - tileFlags = BufferUtils.readBytes(buffer, NUM_SUBTILES); - zeros2 = BufferUtils.readBytes(buffer, 7); - blockHeadersPointer = buffer.getInt(); - blockDataLength = buffer.getInt(); - numBlocks = buffer.getInt(); - zeros3 = BufferUtils.readBytes(buffer, 12); - id = Index.create(orientation, mainIndex, subIndex); - assert !buffer.hasRemaining(); - assert allZeros(zeros1) : "Expected 4 zeros, got: " + Arrays.toString(zeros1); - assert allZeros(zeros2) : "Expected 7 zeros, got: " + Arrays.toString(zeros2); - //assert allZeros(zeros3) : "Expected 12 zeros, got: " + Arrays.toString(zeros3); - } - - public int getNumBlocks() { - return numBlocks; - } - - public Block getBlock(int i) { - return blocks[i]; - } - - public boolean isSpecial() { - return Orientation.isSpecial(orientation); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", "0x" + Integer.toHexString(id)) - .append("direction", direction) - .append("roofHeight", roofHeight) - .append("soundIndex", soundIndex) - .append("animated", animated) - .append("height", height) - .append("width", width) - //.append("zeros1", Arrays.toString(zeros1)) - .append("orientation", orientation) - .append("mainIndex", mainIndex) - .append("subIndex", subIndex) - .append("rarity", rarity) - .append("unknown", Arrays.toString(unknown)) - .append("tileFlags", Arrays.toString(tileFlags)) - //.append("zeros2", Arrays.toString(zeros2)) - .append("blockHeadersPointer", "0x" + Integer.toHexString(blockHeadersPointer)) - .append("blockDataLength", blockDataLength) - .append("numBlocks", numBlocks) - //.append("zeros3", Arrays.toString(zeros3)) - .toString(); - } - - public void createPixmap() { - Preconditions.checkState(pixmap == null, "pixmap should be null"); - int absWidth = width; - int absHeight = -height; - - if (isSpecial()) { - absWidth = WIDTH; - } - - int y_add = 96; - if (orientation == Orientation.FLOOR || orientation == Orientation.ROOF) { - if (height != 0) { - height = -80; - absHeight = 80; - y_add = 0; - } - } else if (orientation < Orientation.ROOF) { - if (height != 0) { - height += 32; - absHeight -= 32; - y_add = absHeight; - } - } - - int x0, y0, length, format; - byte[] data; - - pixmap = new PaletteIndexedPixmap(absWidth, absHeight); - for (Block block : blocks) { - x0 = block.x; - y0 = y_add + block.y; - data = block.colormap; - length = block.length; - format = block.format; - if (format == 0x0001) { - drawIsometricBlock(x0, y0, data, length); - } else { - drawRLEBlock(x0, y0, data, length); - } - } - } - - private void drawIsometricBlock(int x0, int y0, byte[] data, int length) { - if (length != 256) { - Gdx.app.error(TAG, "Blocks should be 256 bytes, was " + length); - return; - } - - int x, y = 0, n, i = 0; - while (length > 0) { - x = X_JUMP[y]; - n = PIXEL_WIDTH[y]; - length -= n; - while (n > 0) { - pixmap.drawPixel(x0 + x, y0 + y, Palette.a8(data[i])); - i++; - x++; - n--; - } - y++; - } - } - - private void drawRLEBlock(int x0, int y0, byte[] data, int length) { - int i = 0, b1, b2; - int x = 0, y = 0; - while (length > 0) { - b1 = data[i] & 0xFF; - b2 = data[i + 1] & 0xFF; - i += 2; - length -= 2; - if (b1 > 0 || b2 > 0) { - x += b1; - length -= b2; - while (b2 > 0) { - pixmap.drawPixel(x0 + x, y0 + y, Palette.a8(data[i])); - i++; - x++; - b2--; - } - } else { - x = 0; - y++; - } - } - } - - public static class Index { - private static final int MAIN_INDEX_OFFSET = 16; - private static final int MAIN_INDEX_BITS = 0xFF; - - private static final int SUB_INDEX_OFFSET = 8; - private static final int SUB_INDEX_BITS = 0xFF; - - private static final int ORIENTATION_OFFSET = 0; - private static final int ORIENTATION_BITS = 0xFF; - - public static int create(int orientation, int mainIndex, int subIndex) { - return (mainIndex & MAIN_INDEX_BITS) << MAIN_INDEX_OFFSET - | (subIndex & SUB_INDEX_BITS) << SUB_INDEX_OFFSET - | (orientation & ORIENTATION_BITS) << ORIENTATION_OFFSET; - } - - public static int mainIndex(int index) { - return (index >>> MAIN_INDEX_OFFSET) & MAIN_INDEX_BITS; - } - - public static int subIndex(int index) { - return (index >>> SUB_INDEX_OFFSET) & SUB_INDEX_BITS; - } - - public static int orientation(int index) { - return (index >>> ORIENTATION_OFFSET) & ORIENTATION_BITS; - } - } - } - - public static class Block { - static final int SIZE = 20; - - public short x; - public short y; - public byte zeros1[]; - public byte gridX; - public byte gridY; - public short format; - public int length; - public byte zeros2[]; - public int fileOffset; - - public byte colormap[]; - - Block(InputStream in) throws IOException { - ByteBuffer buffer = ByteBuffer.wrap(IOUtils.readFully(in, SIZE)).order(ByteOrder.LITTLE_ENDIAN); - x = buffer.getShort(); - y = buffer.getShort(); - zeros1 = BufferUtils.readBytes(buffer, 2); - gridX = buffer.get(); - gridY = buffer.get(); - format = buffer.getShort(); - length = buffer.getInt(); - zeros2 = BufferUtils.readBytes(buffer, 2); - fileOffset = buffer.getInt(); - assert !buffer.hasRemaining(); - assert allZeros(zeros1) : "Expected 2 zeros, got: " + Arrays.toString(zeros1); - assert allZeros(zeros2) : "Expected 2 zeros, got: " + Arrays.toString(zeros2); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("x", x) - .append("y", y) - //.append("zeros1", Arrays.toString(zeros1)) - .append("gridX", gridX) - .append("gridY", gridY) - .append("format", format) - .append("length", length) - //.append("zeros2", Arrays.toString(zeros2)) - .append("fileOffset", "0x" + Integer.toHexString(fileOffset)) - .toString(); - } - } -} diff --git a/core/src/gdx/diablo/map2/DT1Loader.java b/core/src/gdx/diablo/map2/DT1Loader.java deleted file mode 100644 index 5d34f9bb..00000000 --- a/core/src/gdx/diablo/map2/DT1Loader.java +++ /dev/null @@ -1,44 +0,0 @@ -package gdx.diablo.map2; - -import com.badlogic.gdx.assets.AssetDescriptor; -import com.badlogic.gdx.assets.AssetLoaderParameters; -import com.badlogic.gdx.assets.AssetManager; -import com.badlogic.gdx.assets.loaders.AsynchronousAssetLoader; -import com.badlogic.gdx.assets.loaders.FileHandleResolver; -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.utils.Array; - -public class DT1Loader extends AsynchronousAssetLoader { - - DT1 dt1; - - public DT1Loader(FileHandleResolver resolver) { - super(resolver); - } - - @Override - public void loadAsync(AssetManager assets, String fileName, FileHandle file, DT1LoaderParameters params) { - dt1 = DT1.loadFromStream(fileName, file.read()); - } - - @Override - public DT1 loadSync(AssetManager assets, String fileName, FileHandle file, DT1LoaderParameters params) { - DT1 dt1 = this.dt1; - if (dt1 == null) { - dt1 = DT1.loadFromStream(fileName, file.read()); - } else { - this.dt1 = null; - } - - dt1.prepareTextures(); - return dt1; - } - - @Override - public Array getDependencies(String fileName, FileHandle file, DT1LoaderParameters params) { - return null; - } - - public static class DT1LoaderParameters extends AssetLoaderParameters {} - -} diff --git a/core/src/gdx/diablo/map2/DT1s.java b/core/src/gdx/diablo/map2/DT1s.java deleted file mode 100644 index 9825ce3a..00000000 --- a/core/src/gdx/diablo/map2/DT1s.java +++ /dev/null @@ -1,72 +0,0 @@ -package gdx.diablo.map2; - -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.IntIntMap; -import com.badlogic.gdx.utils.IntMap; -import com.badlogic.gdx.utils.ObjectSet; - -public class DT1s { - // TODO: tiles and prob are both keyed with tile ID, can speed up if using one map to Pair - ObjectSet dt1s = new ObjectSet<>(); - IntMap> tiles = new IntMap<>(); - IntIntMap prob = new IntIntMap(); - - void add(DT1.Tile tile) { - //if (tile.rarity == 0) return; - Array tiles = this.tiles.get(tile.id); - if (tiles == null) this.tiles.put(tile.id, tiles = new Array<>()); - tiles.add(tile); - prob.getAndIncrement(tile.id, 0, tile.rarity); - } - - void remove(DT1.Tile tile) { - //if (tile.rarity == 0) return; - Array tiles = this.tiles.get(tile.id); - if (tiles == null) return; - tiles.removeValue(tile, true); - prob.getAndIncrement(tile.id, 0, -tile.rarity); - } - - public boolean add(DT1 dt1) { - if (!dt1s.add(dt1)) return false; - for (DT1.Tile tile : dt1.tiles) add(tile); - return true; - } - - public boolean remove(DT1 dt1) { - if (!dt1s.remove(dt1)) return false; - for (DT1.Tile tile : dt1.tiles) remove(tile); - return true; - } - - public DT1.Tile get(int orientation, int mainIndex, int subIndex) { - int id = DT1.Tile.Index.create(orientation, mainIndex, subIndex); - Array tiles = this.tiles.get(id); - return next(id, tiles); - } - - public DT1.Tile get(DS1.Cell cell) { - Array tiles = this.tiles.get(cell.id); - return next(cell.id, tiles); - } - - public DT1.Tile get(int id) { - Array tiles = this.tiles.get(id); - return next(id, tiles); - } - - private DT1.Tile next(int id, Array tiles) { - if (tiles == null) return null; - int sum = prob.get(id, 0); - int random = sum == 0 ? 0 : MathUtils.random(sum - 1); - for (DT1.Tile tile : tiles) { - random -= tile.rarity; - if (random <= 0) { - return tile; - } - } - - return null; - } -} diff --git a/core/src/gdx/diablo/map2/Map.java b/core/src/gdx/diablo/map2/Map.java deleted file mode 100644 index 3ebc1659..00000000 --- a/core/src/gdx/diablo/map2/Map.java +++ /dev/null @@ -1,461 +0,0 @@ -package gdx.diablo.map2; - -import com.google.common.base.Preconditions; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.math.GridPoint2; -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.IntMap; - -import org.apache.commons.lang3.builder.ToStringBuilder; - -import java.util.Arrays; - -import gdx.diablo.Diablo; -import gdx.diablo.codec.excel.Levels; -import gdx.diablo.codec.excel.LvlPrest; -import gdx.diablo.codec.excel.LvlTypes; - -public class Map { - private static final String TAG = "Map"; - private static final boolean DEBUG = true; - private static final boolean DEBUG_BUILD = DEBUG && true; - - public static final String TILES_PATH = "data/global/tiles/"; - - public static final int OUTDOOR_GRID_X = 8; - public static final int OUTDOOR_GRID_Y = 8; - - private static final int DIRECTION_NORTH = 0; - private static final int DIRECTION_EAST = 1; - private static final int DIRECTION_SOUTH = 2; - private static final int DIRECTION_WEST = 3; - - private static final int[] ACT_DEF = new int[]{1, 301, 529, 797, 863}; - - public static final int ID_MAP_ENTRY = DT1.Tile.Index.create(Orientation.SPECIAL_TILE_11, 30, 0); - public static final int ID_TOWN_ENTRY_1 = DT1.Tile.Index.create(Orientation.SPECIAL_TILE_10, 30, 0); - public static final int ID_TOWN_ENTRY_2 = DT1.Tile.Index.create(Orientation.SPECIAL_TILE_10, 31, 0); - public static final int ID_CORPSE_LOCATION = DT1.Tile.Index.create(Orientation.SPECIAL_TILE_10, 32, 0); - public static final int ID_TP_LOCATION = DT1.Tile.Index.create(Orientation.SPECIAL_TILE_10, 33, 0); - static IntMap ID_TO_NAME; - static { - ID_TO_NAME = new IntMap<>(); - ID_TO_NAME.put(ID_MAP_ENTRY, "ID_MAP_ENTRY"); - ID_TO_NAME.put(ID_TOWN_ENTRY_1, "ID_TOWN_ENTRY_1"); - ID_TO_NAME.put(ID_TOWN_ENTRY_2, "ID_TOWN_ENTRY_2"); - ID_TO_NAME.put(ID_CORPSE_LOCATION, "ID_CORPSE_LOCATION"); - ID_TO_NAME.put(ID_TP_LOCATION, "ID_TP_LOCATION"); - } - - public int width; - public int height; - - public static Map build(int seed, int act, int diff) { - MathUtils.random.setSeed(seed); - - Map map = new Map(); - - int def = ACT_DEF[act]; - LvlPrest.Entry preset = Diablo.files.LvlPrest.get(def); - Levels.Entry level = Diablo.files.Levels.get(preset.LevelId); - if (DEBUG_BUILD) Gdx.app.debug(TAG, level.LevelName); - - int fileId[] = new int[6]; - int numFiles = getPresets(preset, fileId); - int select = MathUtils.random(numFiles - 1); - String fileName = preset.File[select]; - if (DEBUG_BUILD) Gdx.app.debug(TAG, "Select " + fileName); - - Zone zone = map.addZone(level, diff, preset, select); - map.width = zone.width; - map.height = zone.height; - Zone prev = zone; - - level = Diablo.files.Levels.get(2); - zone = map.addZone(level, diff, 8, 8); - zone.x = prev.width - zone.width; - zone.y = -zone.height; - - Preset SB = Preset.of(Diablo.files.LvlPrest.get(4), 0); - Preset EB = Preset.of(Diablo.files.LvlPrest.get(5), 0); - Preset NB = Preset.of(Diablo.files.LvlPrest.get(6), 0); - Preset WB = Preset.of(Diablo.files.LvlPrest.get(7), 0); - Preset NWB = Preset.of(Diablo.files.LvlPrest.get(9), 0); - Preset LRC = Preset.of(Diablo.files.LvlPrest.get(27), 0); - Preset UR = Preset.of(Diablo.files.LvlPrest.get(26), 3); - Preset URNB = Preset.of(Diablo.files.LvlPrest.get(26), 1); - Preset SWB = Preset.of(Diablo.files.LvlPrest.get(8), 0); - Preset LB = Preset.of(Diablo.files.LvlPrest.get(12), 0); - Preset FILL[] = Preset.of(Diablo.files.LvlPrest.get(29)); - - for (int x = 0; x < zone.gridsX; x++) { - for (int y = 0; y < zone.gridsY; y++) { - zone.presets[x][y] = FILL[MathUtils.random(FILL.length - 1)]; - } - } - for (int y = 0; y < zone.gridsY; y++) { - zone.presets[0][y] = EB; - zone.presets[zone.gridsX - 2][y] = UR; - zone.presets[zone.gridsX - 1][y] = LRC; - } - for (int x = 1; x < zone.gridsX - 1; x++) { - zone.presets[x][0] = NB; - } - zone.presets[0][0] = NWB; - zone.presets[zone.gridsX - 2][0] = URNB; - zone.presets[zone.gridsX - 1][0] = LRC; - zone.presets[0][zone.gridsY - 1] = SWB; - zone.presets[1][zone.gridsY - 1] = SB; - zone.presets[2][zone.gridsY - 1] = SB; - zone.presets[3][zone.gridsY - 1] = LB; - - zone.presets[6][zone.gridsY - 2] = Preset.of(Diablo.files.LvlPrest.get(47), 1); - - return map; - } - - public GridPoint2 find(int id) { - return zones.first().presets[0][0].ds1.find(id); - } - - public GridPoint2 find(int orientation, int mainIndex, int subIndex) { - int id = DT1.Tile.Index.create(orientation, mainIndex, subIndex); - return find(id); - } - - public String getSpecialName(int id) { - return ID_TO_NAME.get(id, "null"); - } - - private static int getPresets(LvlPrest.Entry preset, int[] fileIds) { - int numFiles = 0; - Arrays.fill(fileIds, -1); - for (int i = 0; i < preset.File.length; i++) { - if (preset.File[i].charAt(0) != '0') { - fileIds[numFiles++] = i; - } - } - - return numFiles; - } - - Array zones = new Array<>(); - - public void load() { - for (Zone zone : zones) { - for (int x = 0; x < zone.gridsX; x++) { - for (int y = 0; y < zone.gridsY; y++) { - Map.Preset preset = zone.presets[x][y]; - if (preset == null) continue; - - Diablo.assets.load(TILES_PATH + preset.ds1Name, DS1.class); - - int DT1Mask = preset.preset.Dt1Mask; - for (int i = 0; i < Integer.SIZE; i++) { - if ((DT1Mask & (1 << i)) != 0) { - String dt1 = TILES_PATH + zone.type.File[i]; - Diablo.assets.load(dt1, DT1.class); - } - } - } - } - } - - Diablo.assets.finishLoading(); - for (Zone zone : zones) { - zone.load(); - } - } - - Zone addZone(Levels.Entry level, int diff, LvlPrest.Entry preset, int ds1) { - assert preset.LevelId != 0 : "presets should have an assigned level id"; - Zone zone = addZone(level, diff, level.SizeX[diff], level.SizeY[diff]); - zone.presets[0][0] = Preset.of(preset, ds1); - return zone; - } - - Zone addZone(Levels.Entry level, int diff, int gridSizeX, int gridSizeY) { - Zone zone = new Zone(gridSizeX, gridSizeY); - zone.level = level; - zone.type = Diablo.files.LvlTypes.get(level.LevelType); - zone.width = level.SizeX[diff]; - zone.height = level.SizeY[diff]; - zone.gridsX = zone.width / zone.gridSizeX; - zone.gridsY = zone.height / zone.gridSizeY; - zone.presets = new Preset[zone.gridsX][zone.gridsY]; - zone.flags = new byte[zone.width * DT1.Tile.SUBTILE_SIZE][zone.height * DT1.Tile.SUBTILE_SIZE]; - zones.add(zone); - return zone; - } - - Zone getZone(int x, int y) { - for (Zone zone : zones) { - if (zone.contains(x, y)) { - return zone; - } - } - - return null; - } - - static class Zone { - int x, y; - int width, height; - int gridSizeX, gridSizeY; - int gridsX, gridsY; - Levels.Entry level; - LvlTypes.Entry type; - Preset presets[][]; - Tile tiles[][][]; - byte flags[][]; - - public Zone(int gridSizeX, int gridSizeY) { - this.gridSizeX = gridSizeX; - this.gridSizeY = gridSizeY; - } - - public boolean contains(int x, int y) { - x -= this.x; - y -= this.y; - return 0 <= x && x < width - && 0 <= y && y < height; - } - - public Tile get(int layer, int x, int y) { - return tiles[layer] == null ? null : tiles[layer][x - this.x][y - this.y]; - } - - public int getLocalX(int x) { - return x - this.x; - } - - public int getLocalY(int y) { - return y - this.y; - } - - void load() { - Preconditions.checkState(tiles == null, "tiles have already been loaded"); - tiles = new Tile[DS1.MAX_LAYERS][][]; - for (int x = 0, gridX = 0, gridY = 0; x < gridsX; x++, gridX += gridSizeX, gridY = 0) { - for (int y = 0; y < gridsY; y++, gridY += gridSizeY) { - Preset preset = presets[x][y]; - DS1 ds1 = Diablo.assets.get(TILES_PATH + preset.ds1Name); - preset.load(this, ds1, gridX, gridY); - } - } - } - - @Override - public String toString() { - ToStringBuilder builder = new ToStringBuilder(this); - if (level != null) { - builder - .append("name", level.LevelName) - .append("id", level.Id); - } - - return builder - .append("x", x) - .append("y", y) - .append("width", width) - .append("height", height) - .build(); - } - } - - static class Tile { - DT1.Tile tile; - DS1.Cell cell; - //byte[] flags; - - public static Tile of(DS1.Cell cell) { - return of(Diablo.dt1s.get(cell), cell); - } - - public static Tile of(DT1.Tile tile, DS1.Cell cell) { - Tile t = new Tile(); - t.tile = tile; - t.cell = cell; - //t.flags = new byte[DT1.Tile.NUM_SUBTILES]; - return t; - } - } - - static class Preset { - LvlPrest.Entry preset; - String ds1Name; - DS1 ds1; - - public static Preset of(LvlPrest.Entry preset, int ds1) { - Preset p = new Preset(); - p.preset = preset; - p.ds1Name = preset.File[ds1]; - return p; - } - - public static Preset of(LvlPrest.Entry preset, String ds1) { - Preset p = new Preset(); - p.preset = preset; - p.ds1Name = ds1; - return p; - } - - public static Preset[] of(LvlPrest.Entry preset) { - Preset[] presets = new Preset[preset.Files]; - for (int i = 0; i < preset.Files; i++) { - presets[i] = Preset.of(preset, i); - } - - return presets; - } - - public void load(Zone zone, DS1 ds1, int x, int y) { - assert x + ds1.width <= zone.width : "x=" + x + "; ds1.width=" + ds1.width + "; zone.width=" + zone.width; - assert y + ds1.height <= zone.width : "y=" + y + "; ds1.height=" + ds1.height + "; zone.height=" + zone.height; - - this.ds1 = ds1; - loadFloors(zone, DS1.FLOOR_OFFSET, x, y, ds1); - loadWalls(zone, DS1.WALL_OFFSET, x, y, ds1); - //loadLayer(zone, FLOOR_OFFSET, x, y, ds1.floors, ds1.numFloors, ds1.floorLine); - //loadLayer(zone, SHADOW_OFFSET, x, y, ds1.shadows, ds1.numShadows, ds1.shadowLine); - //loadLayer(zone, WALL_OFFSET, x, y, ds1.walls, ds1.numWalls, ds1.wallLine); - } - - void loadLayer(Zone zone, int layer, int x, int y, DS1.Cell[] cells, int numLayers, int cellsLine) { - final int X_OFFS = x, Y_OFFS = y; - for (int i = 0, offsetX, offsetY; i < numLayers; i++, layer++) { - offsetX = X_OFFS; - offsetY = Y_OFFS; - if (zone.tiles[layer] == null) zone.tiles[layer] = new Tile[zone.width][zone.height]; - for (y = 0; y < zone.height; y++, offsetY++, offsetX = X_OFFS) { - //int ptr = i + (y * cellsLine); - for (x = 0; x < zone.width; x++, offsetX++/*, ptr += numLayers*/) { - int ptr = (y * cellsLine) + (x * numLayers); - DS1.Cell cell = cells[ptr]; - zone.tiles[layer][offsetX][offsetY] = Tile.of(cell); - } - } - } - } - - void loadFloors(Zone zone, int layer, int x, int y, DS1 ds1) { - final int X_OFFS = x, Y_OFFS = y; - for (int i = 0, offsetX, offsetY; i < ds1.numFloors; i++, layer++) { - offsetX = X_OFFS; - offsetY = Y_OFFS; - if (zone.tiles[layer] == null) zone.tiles[layer] = new Tile[zone.width][zone.height]; - for (y = 0; y < ds1.height; y++, offsetY++, offsetX = X_OFFS) { - for (x = 0; x < ds1.width; x++, offsetX++) { - int ptr = i + (y * ds1.floorLine) + (x * ds1.numFloors); - DS1.Cell cell = ds1.floors[ptr]; - - if ((cell.value & 0x00020000) != 0) { - int offsetX2 = offsetX * DT1.Tile.SUBTILE_SIZE; - int offsetY2 = offsetY * DT1.Tile.SUBTILE_SIZE; - for (int y2 = 0; y2 < DT1.Tile.SUBTILE_SIZE; y2++) { - for (int x2 = 0; x2 < DT1.Tile.SUBTILE_SIZE; x2++) { - zone.flags[offsetX2 + x2][offsetY2 + y2] |= 1; - } - } - } - - if (ds1.numFloors == 1) { - if ((ds1.floors[0].value & 0xFF) == 0) { - int offsetX2 = offsetX * DT1.Tile.SUBTILE_SIZE; - int offsetY2 = offsetY * DT1.Tile.SUBTILE_SIZE; - for (int y2 = 0; y2 < DT1.Tile.SUBTILE_SIZE; y2++) { - for (int x2 = 0; x2 < DT1.Tile.SUBTILE_SIZE; x2++) { - zone.flags[offsetX2 + x2][offsetY2 + y2] |= 1; - } - } - } - } else if (ds1.numFloors == 2) { - if ((ds1.floors[0].value & 0xFF) == 0 && (ds1.floors[1].value & 0xFF) == 0) { - int offsetX2 = offsetX * DT1.Tile.SUBTILE_SIZE; - int offsetY2 = offsetY * DT1.Tile.SUBTILE_SIZE; - for (int y2 = 0; y2 < DT1.Tile.SUBTILE_SIZE; y2++) { - for (int x2 = 0; x2 < DT1.Tile.SUBTILE_SIZE; x2++) { - zone.flags[offsetX2 + x2][offsetY2 + y2] |= 1; - } - } - } - } - - if ((cell.value & 0x80000000) != 0) { - continue; - } - - Tile tile = zone.tiles[layer][offsetX][offsetY] = Tile.of(cell); - copyFlags(zone.flags, offsetX, offsetY, tile.tile); - } - } - } - } - - void loadWalls(Zone zone, int layer, int x, int y, DS1 ds1) { - final int X_OFFS = x, Y_OFFS = y; - for (int i = 0, offsetX, offsetY; i < ds1.numWalls; i++, layer++) { - offsetX = X_OFFS; - offsetY = Y_OFFS; - if (zone.tiles[layer] == null) zone.tiles[layer] = new Tile[zone.width][zone.height]; - for (y = 0; y < ds1.height; y++, offsetY++, offsetX = X_OFFS) { - for (x = 0; x < ds1.width; x++, offsetX++) { - int ptr = i + (y * ds1.wallLine) + (x * ds1.numWalls); - DS1.Cell cell = ds1.walls[ptr]; - - if ((cell.value & DS1.Cell.MASK_UNWALKABLE) != 0) { - int offsetX2 = offsetX * DT1.Tile.SUBTILE_SIZE; - int offsetY2 = offsetY * DT1.Tile.SUBTILE_SIZE; - for (int y2 = 0; y2 < DT1.Tile.SUBTILE_SIZE; y2++) { - for (int x2 = 0; x2 < DT1.Tile.SUBTILE_SIZE; x2++) { - zone.flags[offsetX2 + x2][offsetY2 + y2] |= 1; - } - } - } - - if ((cell.value & 0x80000000) != 0) { - // This seems like all the special tiles, null usually means marker tile (start pos), - // non null usually means stuff like side of river, used for ?weather? ?rain drops? - if (!Orientation.isSpecial(cell.orientation)) { - //DT1.Tile tile = Diablo.dt1s.get(cell); - //System.out.println(x + ", " + y + " " + tile); - continue; - } - - zone.tiles[layer][offsetX][offsetY] = Tile.of(cell); - continue; - } - - if (cell.orientation == Orientation.FLOOR) { - continue; - } - - Tile tile = zone.tiles[layer][offsetX][offsetY] = Tile.of(cell); - copyFlags(zone.flags, offsetX, offsetY, tile.tile); - - // Special case, because LEFT_NORTH_CORNER_WALL don't seem to exist, but they contain - // collision data for RIGHT_NORTH_CORNER_WALL, ORing the data just in case some - // RIGHT_NORTH_CORNER_WALL actually does anything - if (cell.orientation == Orientation.RIGHT_NORTH_CORNER_WALL) { - DT1.Tile leftSide = Diablo.dt1s.get(Orientation.LEFT_NORTH_CORNER_WALL, cell.mainIndex, cell.subIndex); - copyFlags(zone.flags, offsetX, offsetY, leftSide); - } - } - } - } - } - - static void copyFlags(byte[][] flags, int tx, int ty, DT1.Tile tile) { - int offsetX = tx * DT1.Tile.SUBTILE_SIZE; - int offsetY = ty * DT1.Tile.SUBTILE_SIZE; - // Note: walkable flags are stored inverted y-axis, this corrects it - for (int y = DT1.Tile.SUBTILE_SIZE - 1, t = 0; y >= 0; y--) { - for (int x = 0; x < DT1.Tile.SUBTILE_SIZE; x++, t++) { - flags[offsetX + x][offsetY + y] |= tile.tileFlags[t]; - } - } - } - } -} diff --git a/core/src/gdx/diablo/map2/MapRenderer.java b/core/src/gdx/diablo/map2/MapRenderer.java deleted file mode 100644 index 95f34ac2..00000000 --- a/core/src/gdx/diablo/map2/MapRenderer.java +++ /dev/null @@ -1,588 +0,0 @@ -package gdx.diablo.map2; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.badlogic.gdx.math.Rectangle; - -import java.util.Arrays; - -import gdx.diablo.Diablo; -import gdx.diablo.codec.FontTBL; -import gdx.diablo.graphics.PaletteIndexedBatch; - -public class MapRenderer { - private static final String TAG = "MapRenderer"; - private static final boolean DEBUG = true; - private static final boolean DEBUG_MATH = DEBUG && !true; - private static final boolean DEBUG_BUFFER = DEBUG && true; - private static final boolean DEBUG_SUBTILE = DEBUG && true; - private static final boolean DEBUG_TILE = DEBUG && true; - private static final boolean DEBUG_CAMERA = DEBUG && true; - private static final boolean DEBUG_OVERSCAN = DEBUG && true; - private static final boolean DEBUG_GRID = DEBUG && true; - private static final boolean DEBUG_WALKABLE = DEBUG && !true; - private static final boolean DEBUG_SPECIAL = DEBUG && true; - - public static boolean RENDER_DEBUG_SUBTILE = DEBUG_SUBTILE; - public static boolean RENDER_DEBUG_TILE = DEBUG_TILE; - public static boolean RENDER_DEBUG_CAMERA = DEBUG_CAMERA; - public static boolean RENDER_DEBUG_OVERSCAN = DEBUG_OVERSCAN; - public static int RENDER_DEBUG_GRID = DEBUG_GRID ? 3 : 0; - public static int RENDER_DEBUG_WALKABLE = DEBUG_WALKABLE ? DS1.MAX_LAYERS + 1 : 0; - public static boolean RENDER_DEBUG_SPECIAL = DEBUG_SPECIAL; - - private static final Color RENDER_DEBUG_GRID_COLOR_1 = new Color(0x3f3f3f3f); - private static final Color RENDER_DEBUG_GRID_COLOR_2 = new Color(0x7f7f7f3f); - private static final Color RENDER_DEBUG_GRID_COLOR_3 = new Color(0x0000ff3f); - public static int DEBUG_GRID_MODES = 3; - - PaletteIndexedBatch batch; - OrthographicCamera camera; - Map map; - Rectangle viewBounds; - int[] viewBuffer; - float factor = -1.0f; - - final int tileWidth = DT1.Tile.WIDTH; - final int tileHeight = DT1.Tile.HEIGHT; - final int halfTileWidth = tileWidth >>> 1; - final int halfTileHeight = tileHeight >>> 1; - - final int subTileWidth = DT1.Tile.SUBTILE_WIDTH; - final int subTileHeight = DT1.Tile.SUBTILE_HEIGHT; - final int halfSubTileWidth = subTileWidth >>> 1; - final int halfSubTileHeight = subTileHeight >>> 1; - - // subtile index in world-space - int x, y; - - // subtile index in tile-space - int stx, sty; - - // subtile index in tile-space 1D - int t; - - // pixel offset of subtile in world-space - int spx, spy; - - // tile index in world-space - int tx, ty; - - // pixel offset of tile in world-space - int tpx, tpy; - - int width, height; - int tilesX, tilesY; - int renderWidth, renderHeight; - - // tile index of top right tile in render area - int startX, startY; - - // tpx and tpy of startX, startY tile in world-space - int startPx, startPy; - - private static final Color SHADOW_TINT = new Color(0, 0, 0, 0.5f); - - public MapRenderer(PaletteIndexedBatch batch, OrthographicCamera camera) { - this.batch = batch; - this.camera = camera; - viewBounds = new Rectangle(); - } - - public void setMap(Map map) { - if (this.map != map) { - this.map = map; - } - } - - public void update() { - float width = camera.viewportWidth * camera.zoom; - float height = camera.viewportHeight * camera.zoom; - float w = width * Math.abs(camera.up.y) + height * Math.abs(camera.up.x); - float h = height * Math.abs(camera.up.y) + width * Math.abs(camera.up.x); - float x = camera.position.x - w / 2; - float y = camera.position.y - h / 2; - viewBounds.set(x, y, width, height); - } - - public void setFactor(float factor) { - if (this.factor != factor) { - this.factor = factor; - updateViewBuffer(); - } - } - - private void updateViewBuffer() { - /* - int width = (int) viewBounds.width; - int height = (int) viewBounds.height; - if (factor == 0) { - // FIXME: This isn't correct, but should be sufficiently large enough - width = 8 * width; - height = 8 * height; - } else { - width *= factor; - height *= factor; - } - */ - - updateBounds(); - // This will generate an array s.t. each cell is the length of tiles to render - final int viewBufferLen = tilesX + tilesY - 1; - final int viewBufferMax = tilesX * 2 - 1; - viewBuffer = new int[viewBufferLen]; - int x, y; - for (x = 0, y = 1; y < viewBufferMax; x++, y += 2) - viewBuffer[x] = viewBuffer[viewBufferLen - 1 - x] = y; - while (viewBuffer[x] == 0) - viewBuffer[x++] = viewBufferMax; - if (DEBUG_BUFFER) Gdx.app.debug(TAG, "viewBuffer=" + Arrays.toString(viewBuffer)); - } - - public void setPosition(int x, int y) { - if (this.x != x || this.y != y) { - this.x = x; - this.y = y; - final int halfSubTileWidth = DT1.Tile.SUBTILE_WIDTH >>> 1; - final int halfSubTileHeight = DT1.Tile.SUBTILE_HEIGHT >>> 1; - int spx = (x * halfSubTileWidth) - (y * halfSubTileWidth); - int spy = -(x * halfSubTileHeight) - (y * halfSubTileHeight); - camera.position.set(spx, spy, 0); - runMath(x, y); - } - } - - public void runMath(int x, int y) { - camera.update(); - // subtile index in tile-space - stx = x < 0 - ? (x + 1) % DT1.Tile.SUBTILE_SIZE + (DT1.Tile.SUBTILE_SIZE - 1) - : x % DT1.Tile.SUBTILE_SIZE; - sty = y < 0 - ? (y + 1) % DT1.Tile.SUBTILE_SIZE + (DT1.Tile.SUBTILE_SIZE - 1) - : y % DT1.Tile.SUBTILE_SIZE; - t = DT1.Tile.SUBTILE_INDEX[stx][sty]; - - // pixel offset of subtile in world-space - spx = -halfSubTileWidth + (x * halfSubTileWidth) - (y * halfSubTileWidth); - spy = -halfSubTileHeight - (x * halfSubTileHeight) - (y * halfSubTileHeight); - - // tile index in world-space - tx = x < 0 - ? ((x + 1) / DT1.Tile.SUBTILE_SIZE) - 1 - : (x / DT1.Tile.SUBTILE_SIZE); - ty = y < 0 - ? ((y + 1) / DT1.Tile.SUBTILE_SIZE) - 1 - : (y / DT1.Tile.SUBTILE_SIZE); - - tpx = spx - DT1.Tile.SUBTILE_OFFSET[t][0]; - tpy = spy - DT1.Tile.SUBTILE_OFFSET[t][1]; - - updateBounds(); - - final int offX = tilesX >>> 1; - final int offY = tilesY >>> 1; - startX = tx + offX - offY; - startY = ty - offX - offY; - startPx = tpx + renderWidth / 2 - halfTileWidth; - startPy = tpy + renderHeight / 2 - halfTileHeight; - - if (DEBUG_MATH) { - Gdx.app.debug(TAG, String.format("(%2d,%2d){%d,%d}[%2d,%2d](%dx%d)[%dx%d] %d,%d%n", - x, y, stx, sty, tx, ty, width, height, tilesX, tilesY, spx, spy)); - } - } - - private void updateBounds() { - width = (int) camera.viewportWidth; - height = (int) camera.viewportHeight; - - int minTilesX = ((width + tileWidth - 1) / tileWidth); - int minTilesY = ((height + tileHeight - 1) / tileHeight); - if ((minTilesX & 1) == 1) minTilesX++; - if ((minTilesY & 1) == 1) minTilesY++; - tilesX = minTilesX + 3; // pad width comfortably - tilesY = minTilesY + 7; // pad height for lower walls / upper walls - renderWidth = tilesX * tileWidth; - renderHeight = tilesY * tileHeight; - assert (tilesX & 1) == 1 && (tilesY & 1) == 1; - } - - // TODO: render will overscan image in y-axis to accommodate walls, should change to wall only instead of entire frame - public void render(PaletteIndexedBatch batch) { - for (int i = 0, x, y; i < DS1.MAX_LAYERS; i++) { - int startX2 = startX; - int startY2 = startY; - int startPx2 = startPx; - int startPy2 = startPy; - for (y = 0; y < viewBuffer.length; y++) { - int dx = startX2; - int dy = startY2; - int px = startPx2; - int py = startPy2; - int size = viewBuffer[y]; - for (x = 0; x < size; x++) { - Map.Zone zone = map.getZone(dx, dy); - if (zone != null) { - //Map.Tile[][] tiles = zone.tiles[i]; - //if (tiles != null) { - Map.Tile tile = zone.get(i, dx, dy); - switch (i) { - case 0: - case 1: - //drawWalls(batch, tile, px, py, false); - drawFloors(batch, tile, px, py); - //batch.setBlendMode(BlendMode.SHADOW, SHADOW_TINT); - //drawShadows(batch, dx, dy, px, py); - //batch.resetBlendMode(); - break; - case 2: - break; - case 3: case 4: case 5: case 6: - drawWalls(batch, tile, px, py, true); - break; - default: - //... - } - //} - } - - dx++; - px += halfTileWidth; - py -= halfTileHeight; - } - - startY2++; - if (y >= tilesX - 1) { - startX2++; - startPy2 -= tileHeight; - } else { - startX2--; - startPx2 -= tileWidth; - } - } - } - } - - public void renderDebug(ShapeRenderer shapes) { - if (RENDER_DEBUG_GRID > 0) - renderDebugGrid(shapes); - - if (RENDER_DEBUG_WALKABLE > 0) - renderDebugWalkable(shapes); - - if (RENDER_DEBUG_TILE) { - shapes.setColor(Color.OLIVE); - drawDiamond(shapes, tpx, tpy, DT1.Tile.WIDTH, DT1.Tile.HEIGHT); - } - - if (RENDER_DEBUG_SUBTILE) { - shapes.setColor(Color.WHITE); - drawDiamond(shapes, spx, spy, DT1.Tile.SUBTILE_WIDTH, DT1.Tile.SUBTILE_HEIGHT); - } - - if (RENDER_DEBUG_CAMERA) { - shapes.setColor(Color.GREEN); - shapes.rect( - camera.position.x - camera.viewportWidth / 2, - camera.position.y - camera.viewportHeight / 2, - camera.viewportWidth + 1, camera.viewportHeight + 1); - } - - if (RENDER_DEBUG_OVERSCAN) { - shapes.setColor(Color.GRAY); - shapes.rect( - tpx - renderWidth / 2 + halfTileWidth, - tpy - renderHeight / 2 + halfTileHeight, - renderWidth, renderHeight); - } - } - - public void renderDebugWalkable(ShapeRenderer shapes) { - //if (RENDER_DEBUG_WALKABLE == DS1.MAX_LAYERS + 1) { - // return; - //} - - final int[] WALKABLE_ID = { - 20, 21, 22, 23, 24, - 15, 16, 17, 18, 19, - 10, 11, 12, 13, 14, - 5, 6, 7, 8, 9, - 0, 1, 2, 3, 4 - }; - - ShapeRenderer.ShapeType shapeType = shapes.getCurrentType(); - shapes.set(ShapeRenderer.ShapeType.Filled); - - int startX2 = startX; - int startY2 = startY; - int startPx2 = startPx; - int startPy2 = startPy; - int x, y; - for (y = 0; y < viewBuffer.length; y++) { - int dx = startX2; - int dy = startY2; - int px = startPx2; - int py = startPy2; - int size = viewBuffer[y]; - for (x = 0; x < size; x++) { - Map.Zone zone = map.getZone(dx, dy); - if (zone != null) { - if (RENDER_DEBUG_WALKABLE == DS1.MAX_LAYERS + 1) { - for (int sty = 0, t = 0; sty < DT1.Tile.SUBTILE_SIZE; sty++) { - for (int stx = 0; stx < DT1.Tile.SUBTILE_SIZE; stx++, t++) { - int flags = zone.flags[zone.getLocalX(dx) * DT1.Tile.SUBTILE_SIZE + stx][zone.getLocalY(dy) * DT1.Tile.SUBTILE_SIZE + sty] & 0xFF; - if (flags == 0) continue; - renderDebugWalkableTiles(shapes, px, py, t, flags); - } - } - } else { - //Map.Tile[][] tiles = zone.tiles[RENDER_DEBUG_WALKABLE - 1]; - //if (tiles != null) { - Map.Tile tile = zone.get(RENDER_DEBUG_WALKABLE - 1, dx, dy); - for (int t = 0; tile != null && tile.tile != null && t < DT1.Tile.NUM_SUBTILES; t++) { - int flags = tile.tile.tileFlags[WALKABLE_ID[t]] & 0xFF; - if (flags == 0) continue; - renderDebugWalkableTiles(shapes, px, py, t, flags); - } - //} - } - } - - dx++; - px += halfTileWidth; - py -= halfTileHeight; - } - - startY2++; - if (y >= tilesX - 1) { - startX2++; - startPy2 -= tileHeight; - } else { - startX2--; - startPx2 -= tileWidth; - } - } - - shapes.set(shapeType); - } - - private void renderDebugWalkableTiles(ShapeRenderer shapes, int px, int py, int t, int flags) { - int offX = px + DT1.Tile.SUBTILE_OFFSET[t][0]; - int offY = py + DT1.Tile.SUBTILE_OFFSET[t][1]; - - shapes.setColor(Color.CORAL); - drawDiamond(shapes, offX, offY, DT1.Tile.SUBTILE_WIDTH, DT1.Tile.SUBTILE_HEIGHT); - - offY += halfSubTileHeight; - - if ((flags & DT1.Tile.FLAG_BLOCK_WALK) != 0) { - shapes.setColor(Color.FIREBRICK); - shapes.triangle( - offX + 16, offY, - offX + 16, offY + 8, - offX + 24, offY + 4); - } - if ((flags & DT1.Tile.FLAG_BLOCK_LIGHT_LOS) != 0) { - shapes.setColor(Color.FOREST); - shapes.triangle( - offX + 16, offY, - offX + 32, offY, - offX + 24, offY + 4); - } - if ((flags & DT1.Tile.FLAG_BLOCK_JUMP) != 0) { - shapes.setColor(Color.ROYAL); - shapes.triangle( - offX + 16, offY, - offX + 32, offY, - offX + 24, offY - 4); - } - if ((flags & DT1.Tile.FLAG_BLOCK_PLAYER_WALK) != 0) { - shapes.setColor(Color.VIOLET); - shapes.triangle( - offX + 16, offY, - offX + 16, offY - 8, - offX + 24, offY - 4); - } - if ((flags & DT1.Tile.FLAG_BLOCK_UNKNOWN1) != 0) { - shapes.setColor(Color.GOLD); - shapes.triangle( - offX + 16, offY, - offX + 16, offY - 8, - offX + 8, offY - 4); - } - if ((flags & DT1.Tile.FLAG_BLOCK_LIGHT) != 0) { - shapes.setColor(Color.SKY); - shapes.triangle( - offX, offY, - offX + 16, offY, - offX + 8, offY - 4); - } - if ((flags & DT1.Tile.FLAG_BLOCK_UNKNOWN2) != 0) { - shapes.setColor(Color.WHITE); - shapes.triangle( - offX, offY, - offX + 16, offY, - offX + 8, offY + 4); - } - if ((flags & DT1.Tile.FLAG_BLOCK_UNKNOWN3) != 0) { - shapes.setColor(Color.SLATE); - shapes.triangle( - offX + 16, offY, - offX + 16, offY + 8, - offX + 8, offY + 4); - } - } - - public void renderDebugGrid(ShapeRenderer shapes) { - int x, y; - switch (RENDER_DEBUG_GRID) { - case 1: - shapes.setColor(RENDER_DEBUG_GRID_COLOR_1); - int startPx2 = startPx; - int startPy2 = startPy; - for (y = 0; y < viewBuffer.length; y++) { - int px = startPx2; - int py = startPy2; - int size = viewBuffer[y]; - for (x = 0; x < size; x++) { - for (int t = 0; t < DT1.Tile.NUM_SUBTILES; t++) { - drawDiamond(shapes, - px + DT1.Tile.SUBTILE_OFFSET[t][0], py + DT1.Tile.SUBTILE_OFFSET[t][1], - DT1.Tile.SUBTILE_WIDTH, DT1.Tile.SUBTILE_HEIGHT); - } - - px += halfTileWidth; - py -= halfTileHeight; - } - - if (y >= tilesX - 1) { - startPy2 -= tileHeight; - } else { - startPx2 -= tileWidth; - } - } - - case 2: - shapes.setColor(RENDER_DEBUG_GRID_COLOR_2); - startPx2 = startPx; - startPy2 = startPy; - for (y = 0; y < viewBuffer.length; y++) { - int px = startPx2; - int py = startPy2; - int size = viewBuffer[y]; - for (x = 0; x < size; x++) { - drawDiamond(shapes, px, py, DT1.Tile.WIDTH, DT1.Tile.HEIGHT); - px += halfTileWidth; - py -= halfTileHeight; - } - - if (y >= tilesX - 1) { - startPy2 -= tileHeight; - } else { - startPx2 -= tileWidth; - } - } - - case 3: - shapes.setColor(RENDER_DEBUG_GRID_COLOR_3); - ShapeRenderer.ShapeType shapeType = shapes.getCurrentType(); - shapes.set(ShapeRenderer.ShapeType.Filled); - final int LINE_WIDTH = 2; - int startX2 = startX; - int startY2 = startY; - startPx2 = startPx; - startPy2 = startPy; - for (y = 0; y < viewBuffer.length; y++) { - int dx = startX2; - int dy = startY2; - int px = startPx2; - int py = startPy2; - int size = viewBuffer[y]; - for (x = 0; x < size; x++) { - Map.Zone zone = map.getZone(dx, dy); - if (zone != null) { - int mod = dx < 0 - ? (dx + 1) % zone.gridSizeX + (zone.gridSizeX - 1) - : dx % zone.gridSizeX; - if (mod == 0) - shapes.rectLine(px, py + halfTileHeight, px + halfTileWidth, py + tileHeight, LINE_WIDTH); - else if (mod == zone.gridSizeX - 1) - shapes.rectLine(px + tileWidth, py + halfTileHeight, px + halfTileWidth, py, LINE_WIDTH); - - mod = dy < 0 - ? (dy + 1) % zone.gridSizeY + (zone.gridSizeY - 1) - : dy % zone.gridSizeY; - if (mod == 0) - shapes.rectLine(px + halfTileWidth, py + tileHeight, px + tileWidth, py + halfTileHeight, LINE_WIDTH); - else if (mod == zone.gridSizeY - 1) - shapes.rectLine(px + halfTileWidth, py, px, py + halfTileHeight, LINE_WIDTH); - } - - dx++; - px += halfTileWidth; - py -= halfTileHeight; - } - - startY2++; - if (y >= tilesX - 1) { - startX2++; - startPy2 -= tileHeight; - } else { - startX2--; - startPx2 -= tileWidth; - } - } - shapes.set(shapeType); - - default: - } - } - - private static void drawDiamond(ShapeRenderer shapes, float x, float y, int width, int height) { - int hw = width >>> 1; - int hh = height >>> 1; - shapes.line(x , y + hh , x + hw , y + height); - shapes.line(x + hw , y + height, x + width, y + hh ); - shapes.line(x + width, y + hh , x + hw , y ); - shapes.line(x + hw , y , x , y + hh ); - } - - private void drawFloors(PaletteIndexedBatch batch, Map.Tile tile, int px, int py) { - if (tile == null) { - return; - } - - batch.draw(tile.tile.texture, px, py, tile.tile.texture.getWidth() + 1, tile.tile.texture.getHeight() + 1); - } - - private void drawWalls(PaletteIndexedBatch batch, Map.Tile tile, int px, int py, boolean upper) { - if (tile == null) { - return; - } - - //RENDER_DEBUG_SPECIAL - if (Orientation.isSpecial(tile.cell.orientation)) { - if (!RENDER_DEBUG_SPECIAL) return; - FontTBL.BitmapFont font = Diablo.fonts.font16; - GlyphLayout layout = new GlyphLayout(font, map.getSpecialName(tile.cell.id)); - font.draw(batch, layout, - px + DT1.Tile.WIDTH / 2 - layout.width / 2, - py + DT1.Tile.HEIGHT / 2 - layout.height / 2); - return; - } - - if (tile.tile.orientation < Orientation.LEFT_WALL) { - return; - } - - batch.draw(tile.tile.texture, px, tile.tile.orientation == Orientation.ROOF ? py + tile.tile.roofHeight : py); - if (tile.tile.orientation == Orientation.RIGHT_NORTH_CORNER_WALL) { - DT1.Tile sister = Diablo.dt1s.get(Orientation.LEFT_NORTH_CORNER_WALL, tile.tile.mainIndex, tile.tile.subIndex); - batch.draw(sister.texture, px, py); - } - } -} diff --git a/core/src/gdx/diablo/map2/MapZoneLoader.java b/core/src/gdx/diablo/map2/MapZoneLoader.java deleted file mode 100644 index 91a08277..00000000 --- a/core/src/gdx/diablo/map2/MapZoneLoader.java +++ /dev/null @@ -1,20 +0,0 @@ -package gdx.diablo.map2; - -import com.badlogic.gdx.utils.async.AsyncTask; - -public class MapZoneLoader implements AsyncTask { - private static final String TAG = "MapZoneLoader"; - private static final boolean DEBUG = true; - - Map map; - - public MapZoneLoader(Map map) { - this.map = map; - } - - @Override - public Void call() { - - return null; - } -} diff --git a/core/src/gdx/diablo/map2/Orientation.java b/core/src/gdx/diablo/map2/Orientation.java deleted file mode 100644 index 6a842818..00000000 --- a/core/src/gdx/diablo/map2/Orientation.java +++ /dev/null @@ -1,109 +0,0 @@ -package gdx.diablo.map2; - -public class Orientation { - /** Floors */ - public static final int FLOOR = 0; - /** Left Wall */ - public static final int LEFT_WALL = 1; - /** Right Wall */ - public static final int RIGHT_WALL = 2; - /** Right part of north corner wall */ - public static final int RIGHT_NORTH_CORNER_WALL = 3; - /** Left part of north corner wall */ - public static final int LEFT_NORTH_CORNER_WALL = 4; - /** Left end wall */ - public static final int LEFT_END_WALL = 5; - /** Right end wall */ - public static final int RIGHT_END_WALL = 6; - /** South corner wall */ - public static final int SOUTH_CORNER_WALL = 7; - /** Left wall with door */ - public static final int LEFT_WALL_DOOR = 8; - /** Right wall with door */ - public static final int RIGHT_WALL_DOOR = 9; - /** Special Cell */ - public static final int SPECIAL_TILE_10 = 10; - /** Special Cell */ - public static final int SPECIAL_TILE_11 = 11; - /** Pillars, columns and standalone objects */ - public static final int PILLAR = 12; - /** Shadows */ - public static final int SHADOW = 13; - /** Trees */ - public static final int TREE = 14; - /** Roofs */ - public static final int ROOF = 15; - /** Lower walls equivalent to Orientation 1 - * @see #LEFT_WALL */ - public static final int LOWER_LEFT_WALL = 16; - /** Lower walls equivalent to Orientation 2 - * @see #RIGHT_WALL */ - public static final int LOWER_RIGHT_WALL = 17; - /** Lower walls equivalent to Orientation 3 and 4 - * @see #RIGHT_NORTH_CORNER_WALL - * @see #LEFT_NORTH_CORNER_WALL */ - public static final int LOWER_NORTH_CORNER_WALL = 18; - /** Lower walls equivalent to Orientation 7 - * @see #SOUTH_CORNER_WALL */ - public static final int LOWER_SOUTH_CORNER_WALL = 19; - - public static String toString(int orientation) { - switch (orientation) { - case FLOOR: return "FLOOR"; - case LEFT_WALL: return "LEFT_WALL"; - case RIGHT_WALL: return "RIGHT_WALL"; - case RIGHT_NORTH_CORNER_WALL: return "RIGHT_NORTH_CORNER_WALL"; - case LEFT_NORTH_CORNER_WALL: return "LEFT_NORTH_CORNER_WALL"; - case LEFT_END_WALL: return "LEFT_END_WALL"; - case RIGHT_END_WALL: return "RIGHT_END_WALL"; - case SOUTH_CORNER_WALL: return "SOUTH_CORNER_WALL"; - case LEFT_WALL_DOOR: return "LEFT_WALL_DOOR"; - case RIGHT_WALL_DOOR: return "RIGHT_WALL_DOOR"; - case SPECIAL_TILE_10: return "SPECIAL_TILE_10"; - case SPECIAL_TILE_11: return "SPECIAL_TILE_11"; - case PILLAR: return "PILLAR"; - case SHADOW: return "SHADOW"; - case TREE: return "TREE"; - case ROOF: return "ROOF"; - case LOWER_LEFT_WALL: return "LOWER_LEFT_WALL"; - case LOWER_RIGHT_WALL: return "LOWER_RIGHT_WALL"; - case LOWER_NORTH_CORNER_WALL: return "LOWER_NORTH_CORNER_WALL"; - case LOWER_SOUTH_CORNER_WALL: return "LOWER_SOUTH_CORNER_WALL"; - default: return "null"; - } - } - - public static int toDirection(int orientation) { - switch (orientation) { - case LEFT_WALL: case LEFT_END_WALL: case LEFT_WALL_DOOR: - return 1; - case RIGHT_WALL: case RIGHT_END_WALL: case RIGHT_WALL_DOOR: - return 2; - case FLOOR: case RIGHT_NORTH_CORNER_WALL: case LEFT_NORTH_CORNER_WALL: case PILLAR: case TREE: - return 3; - case SOUTH_CORNER_WALL: - return 4; - case ROOF: - return 5; - case LOWER_LEFT_WALL: - return 6; - case LOWER_RIGHT_WALL: - return 7; - case LOWER_NORTH_CORNER_WALL: - return 8; - case LOWER_SOUTH_CORNER_WALL: - return 9; - default: throw new AssertionError(); - } - } - - public static boolean isSpecial(int orientation) { - switch (orientation) { - case SPECIAL_TILE_10: - case SPECIAL_TILE_11: - return true; - default: - return false; - } - } -} diff --git a/core/src/gdx/diablo/net/Codec.java b/core/src/gdx/diablo/net/Codec.java new file mode 100644 index 00000000..699283a7 --- /dev/null +++ b/core/src/gdx/diablo/net/Codec.java @@ -0,0 +1,7 @@ +package gdx.diablo.net; + +public class Codec { + + private Codec() {} + +} diff --git a/core/src/gdx/diablo/net/GameLogonPacket.java b/core/src/gdx/diablo/net/GameLogonPacket.java new file mode 100644 index 00000000..5246a8dd --- /dev/null +++ b/core/src/gdx/diablo/net/GameLogonPacket.java @@ -0,0 +1,9 @@ +package gdx.diablo.net; + +import java.io.DataInputStream; + +public class ConnectPacket { + ConnectPacket(DataInputStream in) { + + } +} diff --git a/core/src/gdx/diablo/net/Packet.java b/core/src/gdx/diablo/net/Packet.java new file mode 100644 index 00000000..e82bcbd6 --- /dev/null +++ b/core/src/gdx/diablo/net/Packet.java @@ -0,0 +1,7 @@ +package gdx.diablo.net; + +public class Packet { + + private Packet() {} + +} diff --git a/core/src/gdx/diablo/net/UploadD2SPacket.java b/core/src/gdx/diablo/net/UploadD2SPacket.java new file mode 100644 index 00000000..63de2a5d --- /dev/null +++ b/core/src/gdx/diablo/net/UploadD2SPacket.java @@ -0,0 +1,7 @@ +package gdx.diablo.net; + +public class UploadD2SPacket { + + private UploadD2SPacket() {} + +} diff --git a/core/src/gdx/diablo/net/d2gs/WalkToEntityPacket.java b/core/src/gdx/diablo/net/d2gs/WalkToEntityPacket.java new file mode 100644 index 00000000..ae741f82 --- /dev/null +++ b/core/src/gdx/diablo/net/d2gs/WalkToEntityPacket.java @@ -0,0 +1,34 @@ +package gdx.diablo.net.d2gs; + +import com.google.common.io.LittleEndianDataInputStream; +import com.google.common.io.LittleEndianDataOutputStream; + +import java.io.IOException; + +import gdx.diablo.net.Codec; + +public class WalkToLocationPacket extends Codec { + static final int SIZE = 4; + + public int x; + public int y; + + WalkToLocationPacket() {} + + @Override + public void encode(LittleEndianDataOutputStream out) throws IOException { + out.writeShort(x); + out.writeShort(y); + } + + @Override + public void decode(LittleEndianDataInputStream in) throws IOException { + x = in.readUnsignedShort(); + y = in.readUnsignedShort(); + } + + @Override + public String toString() { + return x + ", " + y; + } +} diff --git a/core/src/gdx/diablo/net/d2gs/WalkToLocationPacket.java b/core/src/gdx/diablo/net/d2gs/WalkToLocationPacket.java new file mode 100644 index 00000000..7cc24b0a --- /dev/null +++ b/core/src/gdx/diablo/net/d2gs/WalkToLocationPacket.java @@ -0,0 +1,34 @@ +package gdx.diablo.net.d2gs; + +import com.google.common.io.LittleEndianDataInputStream; +import com.google.common.io.LittleEndianDataOutputStream; + +import java.io.IOException; + +import gdx.diablo.net.Codec; + +public class MoveToLocationPacket extends Codec { + static final int SIZE = 4; + + public int x; + public int y; + + MoveToLocationPacket() {} + + @Override + public void encode(LittleEndianDataOutputStream out) throws IOException { + out.writeShort(x); + out.writeShort(y); + } + + @Override + public void decode(LittleEndianDataInputStream in) throws IOException { + x = in.readUnsignedShort(); + y = in.readUnsignedShort(); + } + + @Override + public String toString() { + return x + ", " + y; + } +} diff --git a/core/src/gdx/diablo/screen/CharacterProviderScreen.java b/core/src/gdx/diablo/screen/CharacterProviderScreen.java new file mode 100644 index 00000000..b0e43535 --- /dev/null +++ b/core/src/gdx/diablo/screen/CharacterProviderScreen.java @@ -0,0 +1,13 @@ +package gdx.diablo.screen; + +import com.badlogic.gdx.ScreenAdapter; + +import gdx.diablo.entity3.Player; + +public abstract class CharacterScreenAdapter extends ScreenAdapter { + + public CharacterScreenAdapter(Player player) { + + } + +} diff --git a/core/test/gdx/diablo/net/GameLogonPacketTest.java b/core/test/gdx/diablo/net/GameLogonPacketTest.java new file mode 100644 index 00000000..548b9070 --- /dev/null +++ b/core/test/gdx/diablo/net/GameLogonPacketTest.java @@ -0,0 +1,5 @@ +import static org.junit.Assert.*; + +public class GameLogonPacketTest { + +} \ No newline at end of file diff --git a/core/test/gdx/diablo/net/d2gs/WalkToEntityPacketTest.java b/core/test/gdx/diablo/net/d2gs/WalkToEntityPacketTest.java new file mode 100644 index 00000000..187aef38 --- /dev/null +++ b/core/test/gdx/diablo/net/d2gs/WalkToEntityPacketTest.java @@ -0,0 +1,49 @@ +package gdx.diablo.net.d2gs; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +import gdx.diablo.util.DebugUtils; + +public class WalkToLocationPacketTest { + private static final int X = 0xFF; + private static final int Y = 0xFFFF; + private static final byte[] BYTES = new byte[]{(byte) 0xFF, 0x00, (byte) 0xFF, (byte) 0xFF}; + + @Test + public void encode() { + WalkToLocationPacket packet = new WalkToLocationPacket() {{ + x = X; + y = Y; + }}; + + ByteArrayOutputStream out = new ByteArrayOutputStream(WalkToLocationPacket.SIZE); + try { + packet.encode(out); + } catch (Throwable t) { + System.err.println(t.getMessage()); + } + + byte[] bytes = out.toByteArray(); + System.out.println(packet + " -> " + DebugUtils.toByteArray(bytes)); + Assert.assertArrayEquals(BYTES, bytes); + } + + @Test + public void decode() { + WalkToLocationPacket packet = new WalkToLocationPacket(); + try { + ByteArrayInputStream in = new ByteArrayInputStream(BYTES); + packet.decode(in); + } catch (Throwable t) { + System.out.println(t.getMessage()); + } + + System.out.println(DebugUtils.toByteArray(BYTES) + " -> " + packet); + Assert.assertEquals(X, packet.x); + Assert.assertEquals(Y, packet.y); + } +} \ No newline at end of file diff --git a/core/test/gdx/diablo/net/d2gs/WalkToLocationPacketTest.java b/core/test/gdx/diablo/net/d2gs/WalkToLocationPacketTest.java new file mode 100644 index 00000000..f4e3f5c5 --- /dev/null +++ b/core/test/gdx/diablo/net/d2gs/WalkToLocationPacketTest.java @@ -0,0 +1,46 @@ +package gdx.diablo.net.d2gs; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +import gdx.diablo.util.DebugUtils; + +public class MoveToLocationPacketTest { + + @Test + public void encode() { + MoveToLocationPacket packet = new MoveToLocationPacket() {{ + x = 31; + y = 63; + }}; + + ByteArrayOutputStream out = new ByteArrayOutputStream(MoveToLocationPacket.SIZE); + try { + packet.encode(out); + } catch (Throwable t) { + System.err.println(t.getMessage()); + } + + byte[] bytes = out.toByteArray(); + System.out.println(DebugUtils.toByteArray(bytes)); + Assert.assertArrayEquals(new byte[]{0x1F, 0x00, 0x3F, 0x00}, bytes); + } + + @Test + public void decode() { + MoveToLocationPacket packet = new MoveToLocationPacket(); + try { + ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{0x1F, 0x00, 0x3F, 0x00}); + packet.decode(in); + } catch (Throwable t) { + System.out.println(t.getMessage()); + } + + System.out.println(packet); + Assert.assertEquals(31, packet.x); + Assert.assertEquals(63, packet.y); + } +} \ No newline at end of file