mirror of
https://github.com/collinsmith/riiablo.git
synced 2025-03-09 20:29:17 +07:00
Added functional networking with multiple clients in a server rendered correctly
Fixed bug with Map.find(int) returning actual GridPoint -- now returns a copy Added workaround for set(String) in Cvar when generic type is String Transition to entity package with refinements
This commit is contained in:
parent
e23532266f
commit
86c4e6d8ef
@ -104,6 +104,7 @@ public class Client extends Game {
|
|||||||
private boolean forceWindowed;
|
private boolean forceWindowed;
|
||||||
private boolean forceDrawFps;
|
private boolean forceDrawFps;
|
||||||
private byte drawFpsMethod;
|
private byte drawFpsMethod;
|
||||||
|
private String realm;
|
||||||
|
|
||||||
public Client(FileHandle home) {
|
public Client(FileHandle home) {
|
||||||
this(home, Diablo.VIRTUAL_WIDTH, Diablo.VIRTUAL_HEIGHT);
|
this(home, Diablo.VIRTUAL_WIDTH, Diablo.VIRTUAL_HEIGHT);
|
||||||
@ -140,6 +141,16 @@ public class Client extends Game {
|
|||||||
forceDrawFps = b;
|
forceDrawFps = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRealm() {
|
||||||
|
return realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRealm(String realm) {
|
||||||
|
if (!this.realm.equalsIgnoreCase(realm)) {
|
||||||
|
Cvars.Client.Realm.setString(realm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create() {
|
public void create() {
|
||||||
Gdx.app.setLogLevel(Application.LOG_DEBUG);
|
Gdx.app.setLogLevel(Application.LOG_DEBUG);
|
||||||
@ -491,6 +502,13 @@ public class Client extends Game {
|
|||||||
batch.setGamma(to);
|
batch.setGamma(to);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Cvars.Client.Realm.addStateListener(new CvarStateAdapter<String>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Cvar<String> cvar, String from, String to) {
|
||||||
|
realm = to;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InputProcessor extends InputMultiplexer {
|
public static class InputProcessor extends InputMultiplexer {
|
||||||
|
@ -61,6 +61,12 @@ public class Cvars {
|
|||||||
.validator(Validator.ACCEPT_NON_NULL)
|
.validator(Validator.ACCEPT_NON_NULL)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
Cvar<String> Realm = Cvar.builder(String.class)
|
||||||
|
.alias("Client.Realm")
|
||||||
|
.description("Realm to connect to.")
|
||||||
|
.defaultValue("hydra")
|
||||||
|
.build();
|
||||||
|
|
||||||
interface Console {
|
interface Console {
|
||||||
Cvar<String> Font = Cvar.builder(String.class)
|
Cvar<String> Font = Cvar.builder(String.class)
|
||||||
.alias("Client.Console.Font")
|
.alias("Client.Console.Font")
|
||||||
|
@ -133,6 +133,11 @@ public class Cvar<T> implements SuggestionProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Workaround for issue calling set(String) when <T> is also String
|
||||||
|
public void setString(@NonNull String str) {
|
||||||
|
set(str);
|
||||||
|
}
|
||||||
|
|
||||||
public void set(@NonNull String str, @NonNull StringSerializer deserializer) {
|
public void set(@NonNull String str, @NonNull StringSerializer deserializer) {
|
||||||
try {
|
try {
|
||||||
T value = ((StringSerializer<T>) deserializer).deserialize(str);
|
T value = ((StringSerializer<T>) deserializer).deserialize(str);
|
||||||
|
46
core/src/gdx/diablo/entity/Component.java
Normal file
46
core/src/gdx/diablo/entity/Component.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package gdx.diablo.entity;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
336
core/src/gdx/diablo/entity/Entity.java
Normal file
336
core/src/gdx/diablo/entity/Entity.java
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
package gdx.diablo.entity;
|
||||||
|
|
||||||
|
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.MathUtils;
|
||||||
|
import com.badlogic.gdx.math.Vector3;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
|
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.graphics.PaletteIndexedBatch;
|
||||||
|
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_COF = DEBUG && !true;
|
||||||
|
private static final boolean DEBUG_DIRTY = DEBUG && true;
|
||||||
|
private static final boolean DEBUG_ASSETS = DEBUG && true;
|
||||||
|
private static final boolean DEBUG_STATE = DEBUG && true;
|
||||||
|
|
||||||
|
protected enum EntType {
|
||||||
|
OBJECT("OBJECT"),
|
||||||
|
MONSTER("MONSTER"),
|
||||||
|
PLAYER("CHARS");
|
||||||
|
|
||||||
|
public final String PATH;
|
||||||
|
|
||||||
|
EntType(String path) {
|
||||||
|
PATH = "data\\global\\" + path + "\\";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 final int ALL = 0xFFFF;
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDirty(int flags, int component) {
|
||||||
|
return ((1 << component) & flags) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
String type;
|
||||||
|
EntType entType;
|
||||||
|
|
||||||
|
int dirty;
|
||||||
|
String mode;
|
||||||
|
String code;
|
||||||
|
String layers[];
|
||||||
|
String weaponClass;
|
||||||
|
Vector3 position = new Vector3();
|
||||||
|
Vector3 velocity = new Vector3();
|
||||||
|
float angle = MathUtils.PI * 3 / 2;
|
||||||
|
|
||||||
|
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 void setMode(String mode) {
|
||||||
|
setMode(mode, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMode(String mode, String code) {
|
||||||
|
if (!this.mode.equalsIgnoreCase(mode)) {
|
||||||
|
if (DEBUG_STATE) Gdx.app.debug(TAG, "mode: " + this.mode + " -> " + mode);
|
||||||
|
this.mode = mode;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeaponClass(String weaponClass) {
|
||||||
|
if (!this.weaponClass.equalsIgnoreCase(weaponClass)) {
|
||||||
|
if (DEBUG_STATE) Gdx.app.debug(TAG, "weaponClass: " + this.weaponClass + " -> " + weaponClass);
|
||||||
|
this.weaponClass = weaponClass;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArmType(Component component, String armType) {
|
||||||
|
if (layers == DEFAULT_LAYERS) {
|
||||||
|
if (!DEFAULT_LAYER.equalsIgnoreCase(armType)) {
|
||||||
|
layers = ArrayUtils.clone(DEFAULT_LAYERS);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ordinal = component.ordinal();
|
||||||
|
if (layers[ordinal].equalsIgnoreCase(armType)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DEBUG_COMPONENTS) Gdx.app.debug(TAG, component + " " + layers[ordinal] + " -> " + armType);
|
||||||
|
layers[ordinal] = armType;
|
||||||
|
dirty |= (1 << ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected byte getTransform(Component component) {
|
||||||
|
return (byte) 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 position() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 velocity() {
|
||||||
|
return velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getAngle() {
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 final void invalidate() {
|
||||||
|
dirty = Dirty.ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void validate() {
|
||||||
|
if (dirty == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
|
protected void update() {
|
||||||
|
String path = getCOF();
|
||||||
|
//Gdx.app.debug(TAG, path);
|
||||||
|
|
||||||
|
COF cof = getCOFs().lookup(path);
|
||||||
|
if (DEBUG_COF) Gdx.app.debug(TAG, "" + cof);
|
||||||
|
|
||||||
|
boolean changed = updateAnimation(cof);
|
||||||
|
if (changed) {
|
||||||
|
dirty = Dirty.ALL;
|
||||||
|
animation.setDirection(getDirection());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DEBUG_DIRTY) Gdx.app.debug(TAG, "dirty layers: " + dirty);
|
||||||
|
for (int l = 0; l < cof.getNumLayers(); l++) {
|
||||||
|
COF.Layer layer = cof.getLayer(l);
|
||||||
|
final int c = layer.component;
|
||||||
|
if (!Dirty.isDirty(dirty, c)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
AssetDescriptor<DCC> 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);
|
||||||
|
|
||||||
|
byte transform = getTransform(comp);
|
||||||
|
animation.getLayer(c).setTransform(transform);
|
||||||
|
/*
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateAnimation(COF cof) {
|
||||||
|
if (animation == null) {
|
||||||
|
animation = Animation.newAnimation(cof);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return animation.reset(cof);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCOF() {
|
||||||
|
return type + mode + weaponClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected COFD2 getCOFs() {
|
||||||
|
return Diablo.cofs.active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawDebug(ShapeRenderer shapes) {
|
||||||
|
float x = +(position.x * Tile.SUBTILE_WIDTH50) - (position.y * Tile.SUBTILE_WIDTH50);
|
||||||
|
float y = -(position.x * Tile.SUBTILE_HEIGHT50) - (position.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);
|
||||||
|
|
||||||
|
// FIXME: Should be number of direction dependent, not 16, one of 4,8,16,32
|
||||||
|
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 = +(position.x * Tile.SUBTILE_WIDTH50) - (position.y * Tile.SUBTILE_WIDTH50);
|
||||||
|
float y = -(position.x * Tile.SUBTILE_HEIGHT50) - (position.y * Tile.SUBTILE_HEIGHT50);
|
||||||
|
animation.draw(batch, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean move() {
|
||||||
|
int x = Direction.getOffX(angle);
|
||||||
|
int y = Direction.getOffY(angle);
|
||||||
|
position.add(x, y, 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -3,14 +3,10 @@ package gdx.diablo.entity;
|
|||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.assets.AssetDescriptor;
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
|
||||||
import com.badlogic.gdx.math.GridPoint2;
|
|
||||||
import com.badlogic.gdx.math.MathUtils;
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||||
|
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -19,154 +15,305 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
|
|
||||||
import gdx.diablo.CharClass;
|
import gdx.diablo.CharClass;
|
||||||
import gdx.diablo.Diablo;
|
import gdx.diablo.Diablo;
|
||||||
import gdx.diablo.codec.Animation;
|
import gdx.diablo.ItemCodes;
|
||||||
import gdx.diablo.codec.COF;
|
import gdx.diablo.codec.COFD2;
|
||||||
import gdx.diablo.codec.D2S;
|
import gdx.diablo.codec.D2S;
|
||||||
import gdx.diablo.codec.DCC;
|
|
||||||
import gdx.diablo.codec.excel.Armor;
|
import gdx.diablo.codec.excel.Armor;
|
||||||
import gdx.diablo.codec.excel.ItemEntry;
|
|
||||||
import gdx.diablo.codec.excel.PlrMode;
|
|
||||||
import gdx.diablo.codec.excel.PlrType;
|
|
||||||
import gdx.diablo.codec.excel.WeaponClass;
|
|
||||||
import gdx.diablo.codec.excel.Weapons;
|
import gdx.diablo.codec.excel.Weapons;
|
||||||
import gdx.diablo.graphics.PaletteIndexedBatch;
|
|
||||||
import gdx.diablo.item.BodyLoc;
|
import gdx.diablo.item.BodyLoc;
|
||||||
import gdx.diablo.item.Item;
|
import gdx.diablo.item.Item;
|
||||||
|
import gdx.diablo.server.Connect;
|
||||||
|
|
||||||
public class Player {
|
public class Player extends Entity {
|
||||||
private static final String TAG = "Player";
|
private static final String TAG = "Player";
|
||||||
private static final boolean DEBUG = true;
|
private static final boolean DEBUG = true;
|
||||||
private static final boolean DEBUG_COF = DEBUG && !true;
|
private static final boolean DEBUG_STATE = DEBUG && true;
|
||||||
private static final boolean DEBUG_EQUIPPED = DEBUG && true;
|
|
||||||
private static final boolean DEBUG_INVENTORY = DEBUG && true;
|
|
||||||
|
|
||||||
private static final String CHARS = "data\\global\\chars\\";
|
|
||||||
|
|
||||||
public static final int MAX_NAME_LENGTH = 15;
|
public static final int MAX_NAME_LENGTH = 15;
|
||||||
|
|
||||||
D2S d2s;
|
public enum Slot {
|
||||||
String name;
|
HEAD, NECK, TORS, RARM, LARM, RRIN, LRIN, BELT, FEET, GLOV;
|
||||||
GridPoint2 origin;
|
|
||||||
float angle;
|
|
||||||
|
|
||||||
int plrModeId;
|
public BodyLoc toBodyLoc(boolean alternate) {
|
||||||
PlrMode.Entry plrMode;
|
return toBodyLoc(this, alternate);
|
||||||
|
}
|
||||||
|
|
||||||
int plrTypeId;
|
public static BodyLoc toBodyLoc(Slot slot, boolean alternate) {
|
||||||
PlrType.Entry plrType;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//int weaponClassId;
|
boolean alternate;
|
||||||
WeaponClass.Entry weaponClass;
|
boolean ignoreUpdate;
|
||||||
|
byte[] transforms;
|
||||||
boolean dirty;
|
EnumMap<BodyLoc, Item> equipped = new EnumMap<>(BodyLoc.class);
|
||||||
String cofId;
|
Array<Item> inventory = new Array<>();
|
||||||
Animation anim;
|
public Stats stats;
|
||||||
|
|
||||||
EnumMap<BodyLoc, Item> equipped;
|
|
||||||
Array<Item> inventory;
|
|
||||||
boolean usingAlternate;
|
|
||||||
final Set<SlotListener> SLOT_LISTENERS = new CopyOnWriteArraySet<>();
|
final Set<SlotListener> SLOT_LISTENERS = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
public Player(D2S d2s) {
|
public Player(String name, CharClass clazz) {
|
||||||
this.d2s = d2s;
|
this(name, clazz.id);
|
||||||
name = d2s.name;
|
}
|
||||||
plrTypeId = d2s.charClass;
|
|
||||||
plrType = Diablo.files.PlrType.get(plrTypeId);
|
|
||||||
origin = new GridPoint2();
|
|
||||||
init();
|
|
||||||
//setWeaponClass("hth");
|
|
||||||
|
|
||||||
equipped = d2s.items.equipped;
|
public Player(D2S d2s) {
|
||||||
|
super(Diablo.files.PlrType.get(d2s.charClass).Token, EntType.PLAYER);
|
||||||
|
setMode("TN");
|
||||||
|
|
||||||
|
stats = new D2SStats(d2s);
|
||||||
|
loadEquipped(d2s.items.equipped);
|
||||||
|
loadInventory(d2s.items.inventory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player(String name, int classId) {
|
||||||
|
super(Diablo.files.PlrType.get(classId).Token, EntType.PLAYER);
|
||||||
|
setMode("TN");
|
||||||
|
|
||||||
|
stats = new StatsImpl(name, classId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player(Connect connect) {
|
||||||
|
this(connect.name, connect.classId);
|
||||||
|
|
||||||
|
ignoreUpdate = true;
|
||||||
|
transforms = connect.colors;
|
||||||
|
setWeaponClass("1HS");
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
String code = ItemCodes.getCode(connect.composites[i] & 0xFF);
|
||||||
|
if (code == null) code = ItemCodes.getCode(ItemCodes.LIT);
|
||||||
|
setArmType(Component.valueOf(i), code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadEquipped(EnumMap<BodyLoc, Item> items) {
|
||||||
|
equipped.putAll(items);
|
||||||
for (Map.Entry<BodyLoc, Item> entry : equipped.entrySet()) {
|
for (Map.Entry<BodyLoc, Item> entry : equipped.entrySet()) {
|
||||||
entry.getValue().load();
|
entry.getValue().load();
|
||||||
if (DEBUG_EQUIPPED) Gdx.app.debug(TAG, entry.getKey() + ": " + entry.getValue());
|
//if (DEBUG_EQUIPPED) Gdx.app.debug(TAG, entry.getKey() + ": " + entry.getValue());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inventory = d2s.items.inventory;
|
private void loadInventory(Array<Item> items) {
|
||||||
for (Item item : inventory) {
|
inventory.addAll(items);
|
||||||
|
for (Item item : items) {
|
||||||
item.load();
|
item.load();
|
||||||
if (DEBUG_INVENTORY) Gdx.app.debug(TAG, item.gridX + "," + item.gridY + ": " + item);
|
//if (DEBUG_INVENTORY) Gdx.app.debug(TAG, item.gridX + "," + item.gridY + ": " + item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player(String name, CharClass clazz) {
|
public Item getSlot(Slot slot) {
|
||||||
this.name = name;
|
BodyLoc loc = slot.toBodyLoc(alternate);
|
||||||
plrTypeId = clazz.id;
|
return getSlot(loc);
|
||||||
plrType = Diablo.files.PlrType.get(plrTypeId);
|
|
||||||
origin = new GridPoint2();
|
|
||||||
init();
|
|
||||||
//setWeaponClass("hth");
|
|
||||||
dirty = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init() {
|
public Item getSlot(BodyLoc loc) {
|
||||||
setMode("TN");
|
return equipped.get(loc);
|
||||||
setAngle(MathUtils.PI * 3 / 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getClassId() {
|
public Item setSlot(Slot slot, Item item) {
|
||||||
return d2s.charClass;
|
Preconditions.checkState(item == null || getSlot(slot) == null, "Slot must be empty first!");
|
||||||
|
BodyLoc loc = slot.toBodyLoc(alternate);
|
||||||
|
return setSlot(loc, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CharClass getCharClass() {
|
public Item setSlot(BodyLoc loc, Item item) {
|
||||||
return CharClass.get(d2s.charClass);
|
Item oldItem = equipped.put(loc, item);
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
//invalidate();
|
||||||
return d2s.name;
|
//setArmType(slot, item.base.alternateGfx);
|
||||||
}
|
int components = loc.components();
|
||||||
|
if (components > 0) dirty |= components;
|
||||||
|
updateWeaponClass();
|
||||||
|
|
||||||
public int getLevel() {
|
notifySlotChanged(loc, oldItem, item);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Item getBodyLoc(BodyLoc bodyLoc) {
|
|
||||||
return equipped.get(bodyLoc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Item setBodyLoc(BodyLoc bodyLoc, Item item) {
|
|
||||||
Preconditions.checkState(item == null || getBodyLoc(bodyLoc) == null, "Slot must be empty first!");
|
|
||||||
Item oldItem = equipped.put(bodyLoc, item);
|
|
||||||
for (SlotListener l : SLOT_LISTENERS) l.onChanged(this, bodyLoc, oldItem, item);
|
|
||||||
return oldItem;
|
return oldItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected byte getTransform(Component component) {
|
||||||
|
if (ignoreUpdate) {
|
||||||
|
return transforms[component.ordinal()];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (component) {
|
||||||
|
case HD: return packTransform(Slot.HEAD);
|
||||||
|
case TR:
|
||||||
|
case RA:
|
||||||
|
case LA:
|
||||||
|
case S1:
|
||||||
|
case S2: return packTransform(Slot.TORS);
|
||||||
|
// TODO: Shield/weapons?
|
||||||
|
default: return super.getTransform(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte packTransform(Slot slot) {
|
||||||
|
Item item = getSlot(slot);
|
||||||
|
if (item == null) return super.getTransform(null);
|
||||||
|
return (byte) ((item.base.Transform << 5) | (item.charColorIndex & 0x1F));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Array<Item> getInventory() {
|
||||||
|
return inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
||||||
|
if (ignoreUpdate) {
|
||||||
|
super.update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_STATE) {
|
||||||
|
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 : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean move() {
|
||||||
|
if (!mode.equalsIgnoreCase("WL")
|
||||||
|
&& !mode.equalsIgnoreCase("RN")
|
||||||
|
&& !mode.equalsIgnoreCase("TW")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.move();
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
public boolean addSlotListener(SlotListener l) {
|
||||||
boolean added = SLOT_LISTENERS.add(l);
|
boolean added = SLOT_LISTENERS.add(l);
|
||||||
return added;
|
return added;
|
||||||
@ -186,218 +333,165 @@ public class Player {
|
|||||||
return !empty;
|
return !empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item getComponentSlot(int component) {
|
|
||||||
switch (component) {
|
|
||||||
case COF.Component.HD: return getBodyLoc(BodyLoc.HEAD);
|
|
||||||
case COF.Component.TR:
|
|
||||||
case COF.Component.RA:
|
|
||||||
case COF.Component.LA:
|
|
||||||
case COF.Component.S1:
|
|
||||||
case COF.Component.S2: return getBodyLoc(BodyLoc.TORS);
|
|
||||||
// TODO: Shield/weapons?
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Array<Item> getInventory() {
|
|
||||||
return inventory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAlternate() {
|
|
||||||
return usingAlternate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAlternate(boolean b) {
|
|
||||||
if (usingAlternate != b) {
|
|
||||||
usingAlternate = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Player obtain(D2S d2s) {
|
|
||||||
return new Player(d2s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new ToStringBuilder(this)
|
|
||||||
.append("name", name)
|
|
||||||
.append("origin", origin)
|
|
||||||
.append("plrMode", plrMode)
|
|
||||||
.append("plrType", plrType)
|
|
||||||
.append("weaponClass", weaponClass)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMode(String code) {
|
|
||||||
setMode(Diablo.files.PlrMode.index(code));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMode(int plrModeId) {
|
|
||||||
if (this.plrModeId != plrModeId || plrMode == null) {
|
|
||||||
this.plrModeId = plrModeId;
|
|
||||||
plrMode = Diablo.files.PlrMode.get(plrModeId);
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
public void setWeaponClass(String code) {
|
|
||||||
setWeaponClass(Diablo.files.WeaponClass.index(code));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWeaponClass(int weaponClassId) {
|
|
||||||
if (this.weaponClassId != weaponClassId || weaponClass == null) {
|
|
||||||
this.weaponClassId = weaponClassId;
|
|
||||||
weaponClass = Diablo.files.WeaponClass.get(weaponClassId);
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void setAngle(float rad) {
|
|
||||||
if (this.angle != rad) {
|
|
||||||
this.angle = rad;
|
|
||||||
if (anim != null) anim.setDirection(getDirection());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDirection() {
|
|
||||||
return Direction.radiansToDirection(angle, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GridPoint2 getOrigin() {
|
|
||||||
return origin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update() {
|
|
||||||
if (!dirty) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirty = false;
|
|
||||||
|
|
||||||
String[] components = new String[COF.Component.NUM_COMPONENTS];
|
|
||||||
Item rHand, lHand;
|
|
||||||
if (!usingAlternate) {
|
|
||||||
rHand = getBodyLoc(BodyLoc.RARM);
|
|
||||||
lHand = getBodyLoc(BodyLoc.LARM);
|
|
||||||
} else {
|
|
||||||
rHand = getBodyLoc(BodyLoc.RARM2);
|
|
||||||
lHand = getBodyLoc(BodyLoc.LARM2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: custom code for barbarian _1or2handed
|
|
||||||
if (rHand != null) {
|
|
||||||
ItemEntry entry = rHand.base;
|
|
||||||
components[entry.component] = entry.alternateGfx;
|
|
||||||
if (entry instanceof Weapons.Entry) {
|
|
||||||
weaponClass = Diablo.files.WeaponClass.get(((Weapons.Entry) entry).wclass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lHand != null) {
|
|
||||||
ItemEntry entry = lHand.base;
|
|
||||||
components[entry.component] = entry.alternateGfx;
|
|
||||||
if (entry instanceof Weapons.Entry) {
|
|
||||||
weaponClass = Diablo.files.WeaponClass.get(((Weapons.Entry) entry).wclass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (weaponClass == null) {
|
|
||||||
weaponClass = Diablo.files.WeaponClass.get("hth");
|
|
||||||
}
|
|
||||||
|
|
||||||
Item head = getBodyLoc(BodyLoc.HEAD);
|
|
||||||
components[COF.Component.HD] = head != null ? head.base.alternateGfx : null;
|
|
||||||
|
|
||||||
Item body = getBodyLoc(BodyLoc.TORS);
|
|
||||||
if (body != null) {
|
|
||||||
Armor.Entry armor = body.getBase();
|
|
||||||
components[COF.Component.TR] = Diablo.files.ArmType.get(armor.Torso).Token;
|
|
||||||
components[COF.Component.LG] = Diablo.files.ArmType.get(armor.Legs).Token;
|
|
||||||
components[COF.Component.RA] = Diablo.files.ArmType.get(armor.rArm).Token;
|
|
||||||
components[COF.Component.LA] = Diablo.files.ArmType.get(armor.lArm).Token;
|
|
||||||
components[COF.Component.S1] = Diablo.files.ArmType.get(armor.lSPad).Token;
|
|
||||||
components[COF.Component.S2] = Diablo.files.ArmType.get(armor.rSPad).Token;
|
|
||||||
} else {
|
|
||||||
components[COF.Component.TR] =
|
|
||||||
components[COF.Component.LG] =
|
|
||||||
components[COF.Component.RA] =
|
|
||||||
components[COF.Component.LA] =
|
|
||||||
components[COF.Component.S1] =
|
|
||||||
components[COF.Component.S2] = "lit";
|
|
||||||
}
|
|
||||||
|
|
||||||
String cofId = plrType.Token + plrMode.Token + weaponClass.Code;
|
|
||||||
if (DEBUG_COF) Gdx.app.debug(TAG, "COF: " + this.cofId + " -> " + cofId);
|
|
||||||
COF cof = Diablo.cofs.chars_cof.lookup(cofId);
|
|
||||||
this.cofId = cofId;
|
|
||||||
|
|
||||||
// FIXME: dispose/unload old animation layer
|
|
||||||
//if (animation != null) animation.dispose();
|
|
||||||
|
|
||||||
Animation oldAnim = anim;
|
|
||||||
anim = Animation.newAnimation(cof);
|
|
||||||
// TODO: This might be a problem
|
|
||||||
anim.setDirection(oldAnim != null ? oldAnim.getDirection() : getDirection());
|
|
||||||
|
|
||||||
for (int i = 0; i < cof.getNumLayers(); i++) {
|
|
||||||
COF.Layer layer = cof.getLayer(i);
|
|
||||||
String component = Diablo.files.Composit.get(layer.component).Token;
|
|
||||||
String armorClass = components[layer.component];
|
|
||||||
if (armorClass == null) continue;
|
|
||||||
|
|
||||||
String weaponClass = layer.weaponClass;
|
|
||||||
String path = CHARS + plrType.Token + "\\" + component + "\\" + plrType.Token + component + armorClass + plrMode.Token + weaponClass + ".dcc";
|
|
||||||
|
|
||||||
AssetDescriptor<DCC> descriptor = new AssetDescriptor<>(path, DCC.class);
|
|
||||||
Diablo.assets.load(descriptor);
|
|
||||||
Diablo.assets.finishLoadingAsset(descriptor);
|
|
||||||
DCC dcc = Diablo.assets.get(descriptor);
|
|
||||||
anim.setLayer(layer.component, dcc);
|
|
||||||
|
|
||||||
Item item = getComponentSlot(layer.component);
|
|
||||||
if (item != null) {
|
|
||||||
anim.getLayer(layer.component).setTransform(item.charColormap, item.charColorIndex);
|
|
||||||
/*
|
|
||||||
int trans = item.charTransformation;
|
|
||||||
if (trans != 0xFFFFFFFF) {
|
|
||||||
anim.getLayer(layer.component).setTransform(trans >>> 8);
|
|
||||||
anim.getLayer(layer.component).setTransformColor(trans & 0xFF);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void move() {
|
|
||||||
switch (plrModeId) {
|
|
||||||
case 2: case 3: case 6:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int x = Direction.getOffX(angle);
|
|
||||||
int y = Direction.getOffY(angle);
|
|
||||||
origin.add(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(PaletteIndexedBatch batch, int x, int y) {
|
|
||||||
update();
|
|
||||||
anim.act();
|
|
||||||
anim.draw(batch, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void drawDebug(ShapeRenderer shapes, int x, int y) {
|
|
||||||
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 interface SlotListener {
|
public interface SlotListener {
|
||||||
void onChanged(Player player, BodyLoc bodyLoc, Item oldItem, Item item);
|
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 interface Stats {
|
||||||
|
int getClassId();
|
||||||
|
CharClass getCharClass();
|
||||||
|
String getName();
|
||||||
|
int getLevel();
|
||||||
|
long getExperience();
|
||||||
|
int getStrength();
|
||||||
|
int getDexterity();
|
||||||
|
int getVitality();
|
||||||
|
int getEnergy();
|
||||||
|
int getFireResistance();
|
||||||
|
int getColdResistance();
|
||||||
|
int getLightningResistance();
|
||||||
|
int getPoisonResistance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class StatsImpl implements Stats {
|
||||||
|
final String name;
|
||||||
|
final int classId;
|
||||||
|
StatsImpl(String name, int classId) {
|
||||||
|
this.name = name;
|
||||||
|
this.classId = classId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getClassId() {
|
||||||
|
return classId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharClass getCharClass() {
|
||||||
|
return CharClass.get(getClassId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLevel() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getExperience() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getStrength() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDexterity() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getVitality() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEnergy() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFireResistance() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColdResistance() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLightningResistance() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPoisonResistance() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class D2SStats implements Stats {
|
||||||
|
public final D2S d2s;
|
||||||
|
D2SStats(D2S d2s) {
|
||||||
|
this.d2s = d2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getClassId() {
|
||||||
|
return d2s.charClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharClass getCharClass() {
|
||||||
|
return CharClass.get(getClassId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,6 +363,7 @@ public class Map implements Disposable {
|
|||||||
public GridPoint2 find(int id) {
|
public GridPoint2 find(int id) {
|
||||||
GridPoint2 origin = zones.first().presets[0][0].ds1.find(id);
|
GridPoint2 origin = zones.first().presets[0][0].ds1.find(id);
|
||||||
if (origin == null) return null;
|
if (origin == null) return null;
|
||||||
|
origin = origin.cpy();
|
||||||
origin.x *= DT1.Tile.SUBTILE_SIZE;
|
origin.x *= DT1.Tile.SUBTILE_SIZE;
|
||||||
origin.y *= DT1.Tile.SUBTILE_SIZE;
|
origin.y *= DT1.Tile.SUBTILE_SIZE;
|
||||||
return origin.add(DT1.Tile.SUBTILE_CENTER);
|
return origin.add(DT1.Tile.SUBTILE_CENTER);
|
||||||
|
@ -16,7 +16,7 @@ import java.text.NumberFormat;
|
|||||||
import gdx.diablo.Cvars;
|
import gdx.diablo.Cvars;
|
||||||
import gdx.diablo.Diablo;
|
import gdx.diablo.Diablo;
|
||||||
import gdx.diablo.codec.DC6;
|
import gdx.diablo.codec.DC6;
|
||||||
import gdx.diablo.entity3.Player;
|
import gdx.diablo.entity.Player;
|
||||||
import gdx.diablo.loader.DC6Loader;
|
import gdx.diablo.loader.DC6Loader;
|
||||||
import gdx.diablo.screen.GameScreen;
|
import gdx.diablo.screen.GameScreen;
|
||||||
import gdx.diablo.widget.Button;
|
import gdx.diablo.widget.Button;
|
||||||
|
@ -22,7 +22,7 @@ import gdx.diablo.codec.DC6;
|
|||||||
import gdx.diablo.codec.excel.BodyLocs;
|
import gdx.diablo.codec.excel.BodyLocs;
|
||||||
import gdx.diablo.codec.excel.Inventory;
|
import gdx.diablo.codec.excel.Inventory;
|
||||||
import gdx.diablo.codec.util.BBox;
|
import gdx.diablo.codec.util.BBox;
|
||||||
import gdx.diablo.entity3.Player;
|
import gdx.diablo.entity.Player;
|
||||||
import gdx.diablo.graphics.PaletteIndexedBatch;
|
import gdx.diablo.graphics.PaletteIndexedBatch;
|
||||||
import gdx.diablo.item.BodyLoc;
|
import gdx.diablo.item.BodyLoc;
|
||||||
import gdx.diablo.item.Item;
|
import gdx.diablo.item.Item;
|
||||||
@ -309,7 +309,7 @@ public class InventoryPanel extends WidgetGroup implements Disposable {
|
|||||||
Item cursor = Diablo.cursor.getItem();
|
Item cursor = Diablo.cursor.getItem();
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
if (!ArrayUtils.contains(cursor.type.BodyLoc, bodyPart)) {
|
if (!ArrayUtils.contains(cursor.type.BodyLoc, bodyPart)) {
|
||||||
Diablo.audio.play("sorceress_impossible_1", false);
|
Diablo.audio.play(gameScreen.player.stats.getCharClass().name().toLowerCase() + "_impossible_1", false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ import gdx.diablo.CharClass;
|
|||||||
import gdx.diablo.Diablo;
|
import gdx.diablo.Diablo;
|
||||||
import gdx.diablo.codec.Animation;
|
import gdx.diablo.codec.Animation;
|
||||||
import gdx.diablo.codec.DC6;
|
import gdx.diablo.codec.DC6;
|
||||||
import gdx.diablo.entity3.Player;
|
import gdx.diablo.entity.Player;
|
||||||
import gdx.diablo.graphics.PaletteIndexedBatch;
|
import gdx.diablo.graphics.PaletteIndexedBatch;
|
||||||
import gdx.diablo.loader.DC6Loader;
|
import gdx.diablo.loader.DC6Loader;
|
||||||
import gdx.diablo.widget.CharButton;
|
import gdx.diablo.widget.CharButton;
|
||||||
|
@ -22,7 +22,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
|||||||
import com.badlogic.gdx.scenes.scene2d.utils.UIUtils;
|
import com.badlogic.gdx.scenes.scene2d.utils.UIUtils;
|
||||||
import com.badlogic.gdx.utils.Align;
|
import com.badlogic.gdx.utils.Align;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.utils.ObjectMap;
|
import com.badlogic.gdx.utils.IntMap;
|
||||||
import com.badlogic.gdx.utils.Timer;
|
import com.badlogic.gdx.utils.Timer;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
@ -34,7 +34,7 @@ import java.io.PrintWriter;
|
|||||||
|
|
||||||
import gdx.diablo.Diablo;
|
import gdx.diablo.Diablo;
|
||||||
import gdx.diablo.Keys;
|
import gdx.diablo.Keys;
|
||||||
import gdx.diablo.entity3.Player;
|
import gdx.diablo.entity.Player;
|
||||||
import gdx.diablo.graphics.PaletteIndexedBatch;
|
import gdx.diablo.graphics.PaletteIndexedBatch;
|
||||||
import gdx.diablo.graphics.PaletteIndexedColorDrawable;
|
import gdx.diablo.graphics.PaletteIndexedColorDrawable;
|
||||||
import gdx.diablo.key.MappedKey;
|
import gdx.diablo.key.MappedKey;
|
||||||
@ -49,6 +49,7 @@ import gdx.diablo.panel.InventoryPanel;
|
|||||||
import gdx.diablo.panel.MobilePanel;
|
import gdx.diablo.panel.MobilePanel;
|
||||||
import gdx.diablo.panel.StashPanel;
|
import gdx.diablo.panel.StashPanel;
|
||||||
import gdx.diablo.server.Connect;
|
import gdx.diablo.server.Connect;
|
||||||
|
import gdx.diablo.server.ConnectResponse;
|
||||||
import gdx.diablo.server.Disconnect;
|
import gdx.diablo.server.Disconnect;
|
||||||
import gdx.diablo.server.Message;
|
import gdx.diablo.server.Message;
|
||||||
import gdx.diablo.server.MoveTo;
|
import gdx.diablo.server.MoveTo;
|
||||||
@ -92,7 +93,7 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
|
|||||||
|
|
||||||
//Char character;
|
//Char character;
|
||||||
public Player player;
|
public Player player;
|
||||||
ObjectMap<String, Player> otherPlayers = new ObjectMap<>();
|
IntMap<Player> entities = new IntMap<>();
|
||||||
Timer.Task updateTask;
|
Timer.Task updateTask;
|
||||||
|
|
||||||
Socket socket;
|
Socket socket;
|
||||||
@ -132,7 +133,7 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
|
|||||||
this.fontColor = Diablo.colors.white;
|
this.fontColor = Diablo.colors.white;
|
||||||
this.cursor = new TextureRegionDrawable(Diablo.textures.white);
|
this.cursor = new TextureRegionDrawable(Diablo.textures.white);
|
||||||
}});
|
}});
|
||||||
output.setDebug(true);
|
//output.setDebug(true);
|
||||||
output.setSize(Diablo.VIRTUAL_WIDTH * 0.75f, Diablo.fonts.fontformal12.getLineHeight() * 8);
|
output.setSize(Diablo.VIRTUAL_WIDTH * 0.75f, Diablo.fonts.fontformal12.getLineHeight() * 8);
|
||||||
output.setPosition(10, Diablo.VIRTUAL_HEIGHT - 10, Align.topLeft);
|
output.setPosition(10, Diablo.VIRTUAL_HEIGHT - 10, Align.topLeft);
|
||||||
output.setAlignment(Align.topLeft);
|
output.setAlignment(Align.topLeft);
|
||||||
@ -321,20 +322,30 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
|
|||||||
Connect connect = packet.readValue(Connect.class);
|
Connect connect = packet.readValue(Connect.class);
|
||||||
output.appendText(Diablo.string.format(3641, connect.name));
|
output.appendText(Diablo.string.format(3641, connect.name));
|
||||||
output.appendText("\n");
|
output.appendText("\n");
|
||||||
Player q = player.clone();
|
|
||||||
q.setOrigin(player.origin().cpy());
|
// FIXME: Default position is in subtiles? Divide 5 temp fix
|
||||||
otherPlayers.put(connect.name, q);
|
Player connector = new Player(connect);
|
||||||
|
GridPoint2 startPos = map.find(Map.ID.TOWN_ENTRY_1);
|
||||||
|
connector.position().set(startPos.x, startPos.y, 0);
|
||||||
|
entities.put(connect.id, connector);
|
||||||
break;
|
break;
|
||||||
case Packets.DISCONNECT:
|
case Packets.DISCONNECT:
|
||||||
Disconnect disconnect = packet.readValue(Disconnect.class);
|
Disconnect disconnect = packet.readValue(Disconnect.class);
|
||||||
output.appendText(Diablo.string.format(3642, disconnect.name));
|
output.appendText(Diablo.string.format(3642, disconnect.name));
|
||||||
output.appendText("\n");
|
output.appendText("\n");
|
||||||
otherPlayers.remove(disconnect.name);
|
entities.remove(disconnect.id);
|
||||||
break;
|
break;
|
||||||
case Packets.MOVETO:
|
case Packets.MOVETO:
|
||||||
MoveTo moveTo = packet.readValue(MoveTo.class);
|
MoveTo moveTo = packet.readValue(MoveTo.class);
|
||||||
Player p = otherPlayers.get(moveTo.name);
|
Player p = entities.get(moveTo.id);
|
||||||
if (p != null) p.origin().set(moveTo.x, moveTo.y);
|
if (p != null) {
|
||||||
|
p.position().set(moveTo.x, moveTo.y, 0);
|
||||||
|
p.setAngle(moveTo.angle);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Packets.CONNECT_RESPONSE:
|
||||||
|
ConnectResponse connectResponse = packet.readValue(ConnectResponse.class);
|
||||||
|
entities.put(connectResponse.id, player);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -357,9 +368,9 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
|
|||||||
//int spx = + (player.getOrigin().x * Tile.SUBTILE_WIDTH50) - (player.getOrigin().y * Tile.SUBTILE_WIDTH50);
|
//int spx = + (player.getOrigin().x * Tile.SUBTILE_WIDTH50) - (player.getOrigin().y * Tile.SUBTILE_WIDTH50);
|
||||||
//int spy = - (player.getOrigin().x * Tile.SUBTILE_HEIGHT50) - (player.getOrigin().y * Tile.SUBTILE_HEIGHT50);
|
//int spy = - (player.getOrigin().x * Tile.SUBTILE_HEIGHT50) - (player.getOrigin().y * Tile.SUBTILE_HEIGHT50);
|
||||||
//player.draw(b, spx, spy);
|
//player.draw(b, spx, spy);
|
||||||
player.draw(b);
|
//player.draw(b);
|
||||||
|
|
||||||
for (Player p : otherPlayers.values()) {
|
for (Player p : entities.values()) {
|
||||||
p.draw(b);
|
p.draw(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,8 +409,7 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
|
|||||||
|
|
||||||
//character.x = origin.x;
|
//character.x = origin.x;
|
||||||
//character.y = origin.y;
|
//character.y = origin.y;
|
||||||
player.origin().set(origin);
|
player.position().set(origin.x, origin.y, 0);
|
||||||
Gdx.app.debug(TAG, player.toString());
|
|
||||||
|
|
||||||
Keys.Esc.addStateListener(mappedKeyStateListener);
|
Keys.Esc.addStateListener(mappedKeyStateListener);
|
||||||
Keys.Inventory.addStateListener(mappedKeyStateListener);
|
Keys.Inventory.addStateListener(mappedKeyStateListener);
|
||||||
@ -414,15 +424,22 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
|
|||||||
Gdx.app.log(TAG, "connecting to " + socket.getRemoteAddress() + "...");
|
Gdx.app.log(TAG, "connecting to " + socket.getRemoteAddress() + "...");
|
||||||
in = IOUtils.buffer(new InputStreamReader(socket.getInputStream()));
|
in = IOUtils.buffer(new InputStreamReader(socket.getInputStream()));
|
||||||
out = new PrintWriter(socket.getOutputStream(), true);
|
out = new PrintWriter(socket.getOutputStream(), true);
|
||||||
|
|
||||||
|
String connect = Packets.build(new Connect(player));
|
||||||
|
out.println(connect);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTask = Timer.schedule(new Timer.Task() {
|
updateTask = Timer.schedule(new Timer.Task() {
|
||||||
|
GridPoint2 position = new GridPoint2();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (UIUtils.shift()) return;
|
if (UIUtils.shift()) return;
|
||||||
player.move();
|
boolean moved = player.move();
|
||||||
mapRenderer.setPosition(player.origin());
|
position.set((int) player.position().x, (int) player.position().y);
|
||||||
String moveTo = Packets.build(new MoveTo(player.stats.getName(), player.origin()));
|
mapRenderer.setPosition(position);
|
||||||
|
if (!moved) return;
|
||||||
|
String moveTo = Packets.build(new MoveTo(position, player.getAngle()));
|
||||||
out.println(moveTo);
|
out.println(moveTo);
|
||||||
}
|
}
|
||||||
}, 0, 1 / 25f);
|
}, 0, 1 / 25f);
|
||||||
@ -463,7 +480,7 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pause() {
|
public void pause() {
|
||||||
escapePanel.setVisible(true);
|
//escapePanel.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,7 +39,7 @@ import java.net.SocketTimeoutException;
|
|||||||
|
|
||||||
import gdx.diablo.Diablo;
|
import gdx.diablo.Diablo;
|
||||||
import gdx.diablo.codec.DC6;
|
import gdx.diablo.codec.DC6;
|
||||||
import gdx.diablo.entity3.Player;
|
import gdx.diablo.entity.Player;
|
||||||
import gdx.diablo.graphics.PaletteIndexedBatch;
|
import gdx.diablo.graphics.PaletteIndexedBatch;
|
||||||
import gdx.diablo.loader.DC6Loader;
|
import gdx.diablo.loader.DC6Loader;
|
||||||
import gdx.diablo.server.Account;
|
import gdx.diablo.server.Account;
|
||||||
@ -280,7 +280,7 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
Net.HttpRequest request = new HttpRequestBuilder()
|
Net.HttpRequest request = new HttpRequestBuilder()
|
||||||
.newRequest()
|
.newRequest()
|
||||||
.method(Net.HttpMethods.POST)
|
.method(Net.HttpMethods.POST)
|
||||||
.url("http://hydra:6112/create-session")
|
.url("http://" + Diablo.client.getRealm() + ":6112/create-session")
|
||||||
.jsonContent(new Session.Builder() {{
|
.jsonContent(new Session.Builder() {{
|
||||||
name = tfGameName.getText();
|
name = tfGameName.getText();
|
||||||
password = tfPassword.getText();
|
password = tfPassword.getText();
|
||||||
@ -462,7 +462,7 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
Net.HttpRequest request = new HttpRequestBuilder()
|
Net.HttpRequest request = new HttpRequestBuilder()
|
||||||
.newRequest()
|
.newRequest()
|
||||||
.method(Net.HttpMethods.GET)
|
.method(Net.HttpMethods.GET)
|
||||||
.url("http://hydra:6112/get-sessions")
|
.url("http://" + Diablo.client.getRealm() + ":6112/get-sessions")
|
||||||
.build();
|
.build();
|
||||||
Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() {
|
Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -528,7 +528,7 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
socket = Gdx.net.newClientSocket(Net.Protocol.TCP, "hydra", 6113, new SocketHints());
|
socket = Gdx.net.newClientSocket(Net.Protocol.TCP, Diablo.client.getRealm(), 6113, new SocketHints());
|
||||||
in = IOUtils.buffer(new InputStreamReader(socket.getInputStream()));
|
in = IOUtils.buffer(new InputStreamReader(socket.getInputStream()));
|
||||||
out = new PrintWriter(socket.getOutputStream(), true);
|
out = new PrintWriter(socket.getOutputStream(), true);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
@ -115,7 +115,7 @@ public class LoginScreen extends ScreenAdapter {
|
|||||||
Net.HttpRequest request = new HttpRequestBuilder()
|
Net.HttpRequest request = new HttpRequestBuilder()
|
||||||
.newRequest()
|
.newRequest()
|
||||||
.method(Net.HttpMethods.POST)
|
.method(Net.HttpMethods.POST)
|
||||||
.url("http://hydra:6112/login")
|
.url("http://" + Diablo.client.getRealm() + ":6112/login")
|
||||||
.jsonContent(new Account.Builder() {{ account = "test"; }})
|
.jsonContent(new Account.Builder() {{ account = "test"; }})
|
||||||
.build();
|
.build();
|
||||||
Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() {
|
Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() {
|
||||||
|
@ -17,7 +17,7 @@ import com.badlogic.gdx.utils.Array;
|
|||||||
import gdx.diablo.Diablo;
|
import gdx.diablo.Diablo;
|
||||||
import gdx.diablo.codec.D2S;
|
import gdx.diablo.codec.D2S;
|
||||||
import gdx.diablo.codec.DC6;
|
import gdx.diablo.codec.DC6;
|
||||||
import gdx.diablo.entity3.Player;
|
import gdx.diablo.entity.Player;
|
||||||
import gdx.diablo.graphics.PaletteIndexedBatch;
|
import gdx.diablo.graphics.PaletteIndexedBatch;
|
||||||
import gdx.diablo.loader.DC6Loader;
|
import gdx.diablo.loader.DC6Loader;
|
||||||
import gdx.diablo.widget.SelectButton;
|
import gdx.diablo.widget.SelectButton;
|
||||||
|
@ -17,7 +17,7 @@ import com.badlogic.gdx.utils.Array;
|
|||||||
import gdx.diablo.Diablo;
|
import gdx.diablo.Diablo;
|
||||||
import gdx.diablo.codec.D2S;
|
import gdx.diablo.codec.D2S;
|
||||||
import gdx.diablo.codec.DC6;
|
import gdx.diablo.codec.DC6;
|
||||||
import gdx.diablo.entity3.Player;
|
import gdx.diablo.entity.Player;
|
||||||
import gdx.diablo.graphics.PaletteIndexedBatch;
|
import gdx.diablo.graphics.PaletteIndexedBatch;
|
||||||
import gdx.diablo.loader.DC6Loader;
|
import gdx.diablo.loader.DC6Loader;
|
||||||
import gdx.diablo.server.Account;
|
import gdx.diablo.server.Account;
|
||||||
|
@ -1,13 +1,29 @@
|
|||||||
package gdx.diablo.server;
|
package gdx.diablo.server;
|
||||||
|
|
||||||
|
import gdx.diablo.entity.Player;
|
||||||
|
|
||||||
public class Connect {
|
public class Connect {
|
||||||
|
|
||||||
|
public int id;
|
||||||
public String name;
|
public String name;
|
||||||
|
public int classId;
|
||||||
|
public byte[] composites;
|
||||||
|
public byte[] colors;
|
||||||
|
|
||||||
private Connect() {}
|
private Connect() {}
|
||||||
|
|
||||||
public Connect(String name) {
|
public Connect(String name, int classId, byte[] composites, byte[] colors) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.classId = classId;
|
||||||
|
this.composites = composites;
|
||||||
|
this.colors = colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Connect(Player player) {
|
||||||
|
Player.D2SStats stats = (Player.D2SStats) player.stats;
|
||||||
|
this.name = stats.d2s.name;
|
||||||
|
this.classId = stats.d2s.charClass;
|
||||||
|
this.composites = stats.d2s.composites;
|
||||||
|
this.colors = stats.d2s.colors;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
13
core/src/gdx/diablo/server/ConnectResponse.java
Normal file
13
core/src/gdx/diablo/server/ConnectResponse.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package gdx.diablo.server;
|
||||||
|
|
||||||
|
public class ConnectResponse {
|
||||||
|
|
||||||
|
public int id;
|
||||||
|
|
||||||
|
private ConnectResponse() {}
|
||||||
|
|
||||||
|
public ConnectResponse(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,11 +2,13 @@ package gdx.diablo.server;
|
|||||||
|
|
||||||
public class Disconnect {
|
public class Disconnect {
|
||||||
|
|
||||||
|
public int id;
|
||||||
public String name;
|
public String name;
|
||||||
|
|
||||||
private Disconnect() {}
|
private Disconnect() {}
|
||||||
|
|
||||||
public Disconnect(String name) {
|
public Disconnect(int id, String name) {
|
||||||
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
core/src/gdx/diablo/server/Event.java
Normal file
16
core/src/gdx/diablo/server/Event.java
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package gdx.diablo.server;
|
||||||
|
|
||||||
|
import gdx.diablo.Diablo;
|
||||||
|
|
||||||
|
public class Event {
|
||||||
|
|
||||||
|
public int id;
|
||||||
|
public String[] args;
|
||||||
|
|
||||||
|
private Event() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Diablo.string.format(id, (Object[]) args);
|
||||||
|
}
|
||||||
|
}
|
@ -4,16 +4,17 @@ import com.badlogic.gdx.math.GridPoint2;
|
|||||||
|
|
||||||
public class MoveTo {
|
public class MoveTo {
|
||||||
|
|
||||||
public String name;
|
public int id;
|
||||||
public int x;
|
public int x;
|
||||||
public int y;
|
public int y;
|
||||||
|
public float angle;
|
||||||
|
|
||||||
private MoveTo() {}
|
private MoveTo() {}
|
||||||
|
|
||||||
public MoveTo(String name, GridPoint2 origin) {
|
public MoveTo(GridPoint2 origin, float angle) {
|
||||||
this.name = name;
|
|
||||||
x = origin.x;
|
x = origin.x;
|
||||||
y = origin.y;
|
y = origin.y;
|
||||||
|
this.angle = angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,16 @@ public class Packets {
|
|||||||
public static final int CONNECT = 2;
|
public static final int CONNECT = 2;
|
||||||
public static final int DISCONNECT = 3;
|
public static final int DISCONNECT = 3;
|
||||||
public static final int MOVETO = 4;
|
public static final int MOVETO = 4;
|
||||||
|
public static final int CONNECT_RESPONSE = 5;
|
||||||
|
|
||||||
private static final ObjectIntMap<Class> MAP;
|
private static final ObjectIntMap<Class> MAP;
|
||||||
static {
|
static {
|
||||||
MAP = new ObjectIntMap<>();
|
MAP = new ObjectIntMap<>();
|
||||||
MAP.put(Message.class, 1);
|
MAP.put(Message.class, 1);
|
||||||
MAP.put(Connect.class, 2);
|
MAP.put(Connect.class, 2);
|
||||||
MAP.put(Disconnect.class, 3);
|
MAP.put(Disconnect.class, 3);
|
||||||
MAP.put(MoveTo.class, 4);
|
MAP.put(MoveTo.class, 4);
|
||||||
|
MAP.put(ConnectResponse.class, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> T parse(Class<T> type, String json) {
|
public static <T> T parse(Class<T> type, String json) {
|
||||||
|
@ -6,6 +6,7 @@ import com.badlogic.gdx.math.MathUtils;
|
|||||||
import com.badlogic.gdx.net.ServerSocket;
|
import com.badlogic.gdx.net.ServerSocket;
|
||||||
import com.badlogic.gdx.net.Socket;
|
import com.badlogic.gdx.net.Socket;
|
||||||
import com.badlogic.gdx.utils.Disposable;
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
|
import com.badlogic.gdx.utils.IntMap;
|
||||||
import com.badlogic.gdx.utils.Json;
|
import com.badlogic.gdx.utils.Json;
|
||||||
import com.badlogic.gdx.utils.JsonReader;
|
import com.badlogic.gdx.utils.JsonReader;
|
||||||
|
|
||||||
@ -18,6 +19,8 @@ import java.util.List;
|
|||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import gdx.diablo.entity.Entity;
|
||||||
|
|
||||||
public class Server implements Disposable, Runnable {
|
public class Server implements Disposable, Runnable {
|
||||||
private static final String TAG = "Server";
|
private static final String TAG = "Server";
|
||||||
|
|
||||||
@ -30,6 +33,7 @@ public class Server implements Disposable, Runnable {
|
|||||||
Thread connectionListener;
|
Thread connectionListener;
|
||||||
int port;
|
int port;
|
||||||
String name;
|
String name;
|
||||||
|
IntMap<Entity> entities = new IntMap<>(); // TODO: synchronize
|
||||||
|
|
||||||
public Server(int port) {
|
public Server(int port) {
|
||||||
this(port, "");
|
this(port, "");
|
||||||
@ -52,7 +56,7 @@ public class Server implements Disposable, Runnable {
|
|||||||
while (!kill.get()) {
|
while (!kill.get()) {
|
||||||
try {
|
try {
|
||||||
Socket socket = server.accept(null);
|
Socket socket = server.accept(null);
|
||||||
new Client(socket, "Tirant").start();
|
new Client(socket).start();
|
||||||
Gdx.app.log(name, "connection from " + socket.getRemoteAddress());
|
Gdx.app.log(name, "connection from " + socket.getRemoteAddress());
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
Gdx.app.log(name, t.getMessage(), t);
|
Gdx.app.log(name, t.getMessage(), t);
|
||||||
@ -123,12 +127,13 @@ public class Server implements Disposable, Runnable {
|
|||||||
Socket socket;
|
Socket socket;
|
||||||
BufferedReader in;
|
BufferedReader in;
|
||||||
PrintWriter out;
|
PrintWriter out;
|
||||||
String name;
|
|
||||||
|
|
||||||
public Client(Socket socket, String name) {
|
int id;
|
||||||
|
Connect connect;
|
||||||
|
|
||||||
|
public Client(Socket socket) {
|
||||||
super(clientThreads, "Client-" + String.format("%08X", MathUtils.random(1, Integer.MAX_VALUE - 1)));
|
super(clientThreads, "Client-" + String.format("%08X", MathUtils.random(1, Integer.MAX_VALUE - 1)));
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
this.name = name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -137,7 +142,18 @@ public class Server implements Disposable, Runnable {
|
|||||||
in = IOUtils.buffer(new InputStreamReader(socket.getInputStream()));
|
in = IOUtils.buffer(new InputStreamReader(socket.getInputStream()));
|
||||||
out = new PrintWriter(socket.getOutputStream(), true);
|
out = new PrintWriter(socket.getOutputStream(), true);
|
||||||
|
|
||||||
String connect = Packets.build(new Connect(name));
|
connect = Packets.parse(Connect.class, in.readLine());
|
||||||
|
id = connect.id = entities.size + 1;
|
||||||
|
entities.put(id, null);
|
||||||
|
|
||||||
|
String connectResponse = Packets.build(new ConnectResponse(id));
|
||||||
|
out.println(connectResponse);
|
||||||
|
for (Client client : clients) {
|
||||||
|
out.println(Packets.build(client.connect));
|
||||||
|
}
|
||||||
|
|
||||||
|
String connect = Packets.build(this.connect);
|
||||||
|
Gdx.app.log(getName(), connect);
|
||||||
for (Client client : clients) {
|
for (Client client : clients) {
|
||||||
client.out.println(connect);
|
client.out.println(connect);
|
||||||
//client.out.println("CONNECT " + socket.getRemoteAddress());
|
//client.out.println("CONNECT " + socket.getRemoteAddress());
|
||||||
@ -160,6 +176,9 @@ public class Server implements Disposable, Runnable {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Packets.MOVETO:
|
case Packets.MOVETO:
|
||||||
|
MoveTo moveTo = packet.readValue(MoveTo.class);
|
||||||
|
moveTo.id = id;
|
||||||
|
input = Packets.build(moveTo);
|
||||||
for (Client client : clients) {
|
for (Client client : clients) {
|
||||||
if (client == this) continue;
|
if (client == this) continue;
|
||||||
client.out.println(input);
|
client.out.println(input);
|
||||||
@ -171,10 +190,11 @@ public class Server implements Disposable, Runnable {
|
|||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
Gdx.app.log(getName(), "ERROR " + socket.getRemoteAddress() + ": " + t.getMessage());
|
Gdx.app.log(getName(), "ERROR " + socket.getRemoteAddress() + ": " + t.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
|
entities.remove(id);
|
||||||
clients.remove(this);
|
clients.remove(this);
|
||||||
String message = "DISCONNECT " + socket.getRemoteAddress();
|
String message = "DISCONNECT " + socket.getRemoteAddress();
|
||||||
Gdx.app.log(getName(), message);
|
Gdx.app.log(getName(), message);
|
||||||
String disconnect = Packets.build(new Disconnect(name));
|
String disconnect = Packets.build(new Disconnect(id, connect.name));
|
||||||
for (Client client : clients) {
|
for (Client client : clients) {
|
||||||
client.out.println(disconnect);
|
client.out.println(disconnect);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ public class BNetConnectDialog extends Dialog {
|
|||||||
Net.HttpRequest request = new HttpRequestBuilder()
|
Net.HttpRequest request = new HttpRequestBuilder()
|
||||||
.newRequest()
|
.newRequest()
|
||||||
.method(Net.HttpMethods.GET)
|
.method(Net.HttpMethods.GET)
|
||||||
.url("http://hydra:6112/find-server")
|
.url("http://" + Diablo.client.getRealm() + ":6112/find-server")
|
||||||
.build();
|
.build();
|
||||||
Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() {
|
Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -20,7 +20,7 @@ import gdx.diablo.BlendMode;
|
|||||||
import gdx.diablo.Diablo;
|
import gdx.diablo.Diablo;
|
||||||
import gdx.diablo.codec.excel.Inventory;
|
import gdx.diablo.codec.excel.Inventory;
|
||||||
import gdx.diablo.codec.excel.ItemEntry;
|
import gdx.diablo.codec.excel.ItemEntry;
|
||||||
import gdx.diablo.entity3.Player;
|
import gdx.diablo.entity.Player;
|
||||||
import gdx.diablo.graphics.PaletteIndexedBatch;
|
import gdx.diablo.graphics.PaletteIndexedBatch;
|
||||||
import gdx.diablo.item.Item;
|
import gdx.diablo.item.Item;
|
||||||
|
|
||||||
|
@ -13,9 +13,11 @@ import com.badlogic.gdx.utils.Json;
|
|||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.net.URL;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
@ -31,6 +33,9 @@ public class ServerBrowser extends ApplicationAdapter {
|
|||||||
new HeadlessApplication(new ServerBrowser(), config);
|
new HeadlessApplication(new ServerBrowser(), config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final boolean EXT_HOST = true;
|
||||||
|
private String host;
|
||||||
|
|
||||||
private final Json json = new Json();
|
private final Json json = new Json();
|
||||||
private Map<String, Session> sessions = new ConcurrentHashMap<>();
|
private Map<String, Session> sessions = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@ -43,15 +48,39 @@ public class ServerBrowser extends ApplicationAdapter {
|
|||||||
|
|
||||||
ServerBrowser() {}
|
ServerBrowser() {}
|
||||||
|
|
||||||
|
private static String getIp() {
|
||||||
|
if (!EXT_HOST) {
|
||||||
|
try {
|
||||||
|
InetAddress address = InetAddress.getLocalHost();
|
||||||
|
return address.getHostAddress();
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
Gdx.app.error(TAG, e.getMessage(), e);
|
||||||
|
return "hydra";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedReader in = null;
|
||||||
|
try {
|
||||||
|
in = new BufferedReader(new InputStreamReader(new URL("http://checkip.amazonaws.com").openStream()));
|
||||||
|
return in.readLine();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Gdx.app.error(TAG, e.getMessage(), e);
|
||||||
|
return "hydra";
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create() {
|
public void create() {
|
||||||
final Calendar calendar = Calendar.getInstance();
|
final Calendar calendar = Calendar.getInstance();
|
||||||
DateFormat format = DateFormat.getDateTimeInstance();
|
DateFormat format = DateFormat.getDateTimeInstance();
|
||||||
Gdx.app.log(TAG, format.format(calendar.getTime()));
|
Gdx.app.log(TAG, format.format(calendar.getTime()));
|
||||||
|
|
||||||
|
host = getIp();
|
||||||
try {
|
try {
|
||||||
InetAddress address = InetAddress.getLocalHost();
|
InetAddress address = InetAddress.getLocalHost();
|
||||||
Gdx.app.log(TAG, "IP Address: " + address.getHostAddress());
|
Gdx.app.log(TAG, "IP Address: " + host);
|
||||||
Gdx.app.log(TAG, "Host Name: " + address.getHostName());
|
Gdx.app.log(TAG, "Host Name: " + address.getHostName());
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
Gdx.app.error(TAG, e.getMessage(), e);
|
Gdx.app.error(TAG, e.getMessage(), e);
|
||||||
@ -143,7 +172,7 @@ public class ServerBrowser extends ApplicationAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Session session = builder.build();
|
Session session = builder.build();
|
||||||
session.host = "hydra";
|
session.host = host;
|
||||||
session.port = 6114 + sessions.size();
|
session.port = 6114 + sessions.size();
|
||||||
sessions.put(session.getName(), session);
|
sessions.put(session.getName(), session);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user