Changed EntityFactory API to better support networking

EntityFactory API now uses excel entry ids and lookup ids instead of references
Removed huge reliance on passing map references and instead use internal injected map and generated references
Fixed a bug where MapManager was inserting invalid entity ids that were causing a crash when searching through component mappers
This commit is contained in:
Collin Smith 2019-12-26 15:00:48 -08:00
parent 8c572da389
commit d3825290ee
10 changed files with 139 additions and 106 deletions

View File

@ -1,15 +1,19 @@
package com.riiablo.engine;
import com.artemis.ComponentMapper;
import com.artemis.annotations.Wire;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Vector2;
import com.riiablo.CharData;
import com.riiablo.CharacterClass;
import com.riiablo.Riiablo;
import com.riiablo.codec.excel.Missiles;
import com.riiablo.codec.excel.MonStats;
import com.riiablo.engine.server.component.Class;
import com.riiablo.engine.server.component.Classname;
import com.riiablo.engine.server.component.CofReference;
import com.riiablo.engine.server.component.MapWrapper;
import com.riiablo.engine.server.component.DS1ObjectWrapper;
import com.riiablo.engine.server.component.PathWrapper;
import com.riiablo.item.Item;
import com.riiablo.map.DS1;
import com.riiablo.map.Map;
@ -21,8 +25,14 @@ public abstract class EntityFactory extends PassiveSystem {
protected ComponentMapper<Class> mClass;
protected ComponentMapper<Classname> mClassname;
protected ComponentMapper<MapWrapper> mMapWrapper;
protected ComponentMapper<CofReference> mCofReference;
protected ComponentMapper<DS1ObjectWrapper> mDS1ObjectWrapper;
protected ComponentMapper<PathWrapper> mPathWrapper;
@Wire(name = "map")
protected Map map;
private final Vector2 tmpVec2 = new Vector2();
protected final int createEntity(Class.Type type, String classname) {
int id = world.create();
@ -31,29 +41,64 @@ public abstract class EntityFactory extends PassiveSystem {
return id;
}
protected final int createEntity(Class.Type type, String classname, Map map, Map.Zone zone) {
int id = createEntity(type, classname);
mMapWrapper.create(id).set(map, zone);
return id;
public final int createPlayer(String name, int classId, float x, float y) {
CharData charData = new CharData().createD2S(name, CharacterClass.get(classId));
return createPlayer(charData, tmpVec2.set(x, y));
}
public final int createObject(Map map, Map.Zone zone, Map.Preset preset, DS1.Object object, float x, float y) {
switch (object.type) {
public abstract int createPlayer(CharData charData, Vector2 position);
public final int createObject(Map.Preset preset, DS1.Object object, float x, float y) {
int entityId = createObject(preset.getDS1().getAct(), object.type, object.id, x, y);
if (entityId == Engine.INVALID_ENTITY) {
String objectType;
switch (object.type) {
case DS1.Object.DYNAMIC_TYPE:
objectType = Riiablo.files.MonPreset.getPlace(preset.getDS1().getAct(), object.id);
break;
case DS1.Object.STATIC_TYPE:
objectType = String.valueOf(Riiablo.files.obj.getObjectId(preset.getDS1().getAct(), object.id));
break;
default:
objectType = null;
}
Gdx.app.error(TAG, "Unknown entity id: " + objectType + "; " + preset + "; object=" + object);
return Engine.INVALID_ENTITY;
}
mDS1ObjectWrapper.create(entityId).set(preset.getDS1(), object);
if (object.path != null) mPathWrapper.create(entityId).path = object.path;
return entityId;
}
public final int createObject(int act, int type, int id, float x, float y) {
switch (type) {
case DS1.Object.DYNAMIC_TYPE:
return createDynamicObject(map, zone, preset, object, x, y);
return createDynamicObject(act, id, x, y);
case DS1.Object.STATIC_TYPE:
return createStaticObject(map, zone, preset, object, x, y);
return createStaticObject(act, id, x, y);
default:
Gdx.app.error(TAG, "Unexpected ds1 object type: " + object.type);
Gdx.app.error(TAG, "Unexpected ds1 object type: " + type);
return Engine.INVALID_ENTITY;
}
}
public abstract int createPlayer(Map map, Map.Zone zone, CharData charData, Vector2 position);
public abstract int createDynamicObject(Map map, Map.Zone zone, Map.Preset preset, DS1.Object object, float x, float y);
public abstract int createStaticObject(Map map, Map.Zone zone, Map.Preset preset, DS1.Object object, float x, float y);
public abstract int createMonster(Map map, Map.Zone zone, MonStats.Entry monstats, float x, float y);
public abstract int createWarp(Map map, Map.Zone zone, int index, float x, float y);
public abstract int createDynamicObject(int act, int monPresetId, float x, float y);
public abstract int createStaticObject(int act, int objId, float x, float y);
public final int createMonster(MonStats.Entry monstats, float x, float y) {
return createMonster(monstats.hcIdx, x, y);
}
public abstract int createMonster(int monsterId, float x, float y);
public abstract int createWarp(int index, float x, float y);
public abstract int createItem(Item item, Vector2 position);
public abstract int createMissile(Missiles.Entry missile, Vector2 angle, Vector2 position);
public final int createMissile(Missiles.Entry missile, Vector2 angle, Vector2 position) {
return createMissile(missile.Id, angle, position);
}
public abstract int createMissile(int missileId, Vector2 angle, Vector2 position);
}

View File

@ -25,9 +25,9 @@ import com.riiablo.engine.server.ServerEntityFactory;
import com.riiablo.engine.server.component.Box2DBody;
import com.riiablo.engine.server.component.Item;
import com.riiablo.engine.server.component.Missile;
import com.riiablo.engine.server.component.Monster;
import com.riiablo.engine.server.component.SoundEmitter;
import com.riiablo.engine.server.component.Warp;
import com.riiablo.map.DS1;
import com.riiablo.map.DT1;
import com.riiablo.map.Map;
@ -46,8 +46,8 @@ public class ClientEntityFactory extends ServerEntityFactory {
protected DialogManager dialogManager;
@Override
public int createPlayer(Map map, Map.Zone zone, CharData charData, Vector2 position) {
int id = super.createPlayer(map, zone, charData, position);
public int createPlayer(CharData charData, Vector2 position) {
int id = super.createPlayer(charData, position);
mCofComponentDescriptors.create(id);
mAnimationWrapper.create(id);
mBBoxWrapper.create(id).box = mAnimationWrapper.get(id).animation.getBox();
@ -56,17 +56,19 @@ public class ClientEntityFactory extends ServerEntityFactory {
}
@Override
public int createDynamicObject(Map map, Map.Zone zone, Map.Preset preset, DS1.Object object, float x, float y) {
return super.createDynamicObject(map, zone, preset, object, x, y);
public int createDynamicObject(int act, int monPresetId, float x, float y) {
return super.createDynamicObject(act, monPresetId, x, y);
}
@Override
public int createStaticObject(Map map, Map.Zone zone, Map.Preset preset, DS1.Object object, float x, float y) {
int id = super.createStaticObject(map, zone, preset, object, x, y);
public int createStaticObject(int act, int objId, float x, float y) {
int id = super.createStaticObject(act, objId, x, y);
Objects.Entry base = mObject.get(id).base;
String name;
if ((base.SubClass & Engine.Object.SUBCLASS_WAYPOINT) == Engine.Object.SUBCLASS_WAYPOINT) {
Map.Zone zone = map.getZone(x, y);
mMapWrapper.create(id).set(map, zone);
String levelName = Riiablo.string.lookup(zone.level.LevelName);
String objectName = Riiablo.string.lookup(base.Name);
name = String.format("%s\n%s", levelName, objectName);
@ -102,9 +104,11 @@ public class ClientEntityFactory extends ServerEntityFactory {
}
@Override
public int createMonster(Map map, Map.Zone zone, MonStats.Entry monstats, float x, float y) {
int id = super.createMonster(map, zone, monstats, x, y);
MonStats2.Entry monstats2 = mMonster.get(id).monstats2;
public int createMonster(int monsterId, float x, float y) {
int id = super.createMonster(monsterId, x, y);
Monster monster = mMonster.get(id);
MonStats.Entry monstats = monster.monstats;
MonStats2.Entry monstats2 = monster.monstats2;
String name = monstats.NameStr.equalsIgnoreCase("dummy")
? monstats.Id : Riiablo.string.lookup(monstats.NameStr);
@ -133,12 +137,12 @@ public class ClientEntityFactory extends ServerEntityFactory {
}
@Override
public int createWarp(Map map, Map.Zone zone, int index, float x, float y) {
public int createWarp(int index, float x, float y) {
final int mainIndex = DT1.Tile.Index.mainIndex(index);
final int subIndex = DT1.Tile.Index.subIndex(index);
final int orientation = DT1.Tile.Index.orientation(index);
int id = super.createWarp(map, zone, index, x, y);
int id = super.createWarp(index, x, y);
Warp warp = mWarp.get(id);
LvlWarp.Entry entry = warp.warp;
@ -193,11 +197,12 @@ public class ClientEntityFactory extends ServerEntityFactory {
}
@Override
public int createMissile(Missiles.Entry missile, Vector2 angle, Vector2 position) {
int id = super.createMissile(missile, angle, position);
public int createMissile(int missileId, Vector2 angle, Vector2 position) {
int id = super.createMissile(missileId, angle, position);
Missile missileWrapper = mMissile.get(id);
Riiablo.assets.load(missileWrapper.missileDescriptor);
Missiles.Entry missile = mMissile.get(id).missile;
if (!missile.TravelSound.isEmpty()) {
mSoundEmitter.create(id).set(Riiablo.audio.play(missile.TravelSound, true), Interpolation.pow2OutInverse);
}

View File

@ -1,6 +1,7 @@
package com.riiablo.engine.client;
import com.google.flatbuffers.ByteBufferUtil;
import com.google.flatbuffers.Table;
import com.artemis.ComponentMapper;
import com.artemis.annotations.All;
@ -11,7 +12,6 @@ import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.net.Socket;
import com.badlogic.gdx.physics.box2d.Body;
import com.riiablo.CharData;
import com.riiablo.CharacterClass;
import com.riiablo.Riiablo;
import com.riiablo.codec.excel.MonStats;
import com.riiablo.engine.Dirty;
@ -143,13 +143,10 @@ public class ClientNetworkReceiver extends IntervalSystem {
output.appendText(Riiablo.string.format(3641, charName));
output.appendText("\n");
CharData charData = new CharData().createD2S(charName, CharacterClass.get(charClass));
Vector2 origin = map.find(Map.ID.TOWN_ENTRY_1);
if (origin == null) origin = map.find(Map.ID.TOWN_ENTRY_2);
if (origin == null) origin = map.find(Map.ID.TP_LOCATION);
Map.Zone zone = map.getZone(origin);
int entityId = factory.createPlayer(map, zone, charData, origin);
int entityId = factory.createPlayer(charName, charClass, origin.x, origin.y);
syncIds.put(connection.entityId(), entityId);
int[] component = mCofComponents.get(entityId).component;
for (int i = 0; i < 16; i++) component[i] = connection.cofComponents(i);
@ -181,7 +178,6 @@ public class ClientNetworkReceiver extends IntervalSystem {
private void Disconnect(D2GS packet) {
Disconnect disconnect = (Disconnect) packet.data(new Disconnect());
int serverEntityId = disconnect.entityId();
System.out.println("serverEntityId=" + serverEntityId);
int entityId = syncIds.get(serverEntityId);
CharData data = mPlayer.get(entityId).data;
@ -224,7 +220,7 @@ public class ClientNetworkReceiver extends IntervalSystem {
DS1ObjectWrapperP ds1ObjectWrapper = findTable(sync, SyncData.DS1ObjectWrapperP, new DS1ObjectWrapperP());
if (ds1ObjectWrapper != null) {
// String objectType = Riiablo.files.obj.getType1(ds1ObjectWrapper.act(), ds1ObjectWrapper.id());
// int entityId = factory.createStaticObject(map, null, null, object, 0, 0);
// int entityId = factory.createObject(map, null, null, object, 0, 0);
// return entityId;
}
@ -233,13 +229,10 @@ public class ClientNetworkReceiver extends IntervalSystem {
case MON: {
DS1ObjectWrapperP ds1ObjectWrapper = findTable(sync, SyncData.DS1ObjectWrapperP, new DS1ObjectWrapperP());
if (ds1ObjectWrapper != null) {
Vector2 origin = map.find(Map.ID.TOWN_ENTRY_1);
if (origin == null) origin = map.find(Map.ID.TOWN_ENTRY_2);
if (origin == null) origin = map.find(Map.ID.TP_LOCATION);
Map.Zone zone = map.getZone(origin);
PositionP position = findTable(sync, SyncData.PositionP, new PositionP());
String objectType = Riiablo.files.MonPreset.getPlace(ds1ObjectWrapper.act(), ds1ObjectWrapper.id());
MonStats.Entry monstats = Riiablo.files.monstats.get(objectType);
int entityId = factory.createMonster(map, zone, monstats, 0, 0);
int entityId = factory.createMonster(monstats, position.x(), position.y());
return entityId;
}
@ -247,16 +240,8 @@ public class ClientNetworkReceiver extends IntervalSystem {
}
case PLR: {
PlayerP player = findTable(sync, SyncData.PlayerP, new PlayerP());
CharData charData = new CharData().createD2S(player.charName(), CharacterClass.get(player.charClass()));
// TODO: assert entity id is player
// TODO: add support for other entity types
Vector2 origin = map.find(Map.ID.TOWN_ENTRY_1);
if (origin == null) origin = map.find(Map.ID.TOWN_ENTRY_2);
if (origin == null) origin = map.find(Map.ID.TP_LOCATION);
Map.Zone zone = map.getZone(origin);
int entityId = factory.createPlayer(map, zone, charData, origin);
PositionP position = findTable(sync, SyncData.PositionP, new PositionP());
int entityId = factory.createPlayer(player.charName(), player.charClass(), position.x(), position.y());
cofs.setMode(entityId, Engine.Player.MODE_TN);
cofs.setWClass(entityId, Engine.WEAPON_1HS); // TODO...
return entityId;

View File

@ -3,12 +3,16 @@ package com.riiablo.engine.client;
import com.artemis.BaseEntitySystem;
import com.artemis.ComponentMapper;
import com.artemis.annotations.All;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.IntIntMap;
import com.riiablo.engine.Engine;
import com.riiablo.engine.server.component.Networked;
@All(Networked.class)
public class NetworkIdManager extends BaseEntitySystem {
private static final String TAG = "NetworkIdManager";
private static final boolean DEBUG = true;
final IntIntMap serverToEntityId = new IntIntMap();
protected ComponentMapper<Networked> mNetworked;
@ -33,6 +37,6 @@ public class NetworkIdManager extends BaseEntitySystem {
public void put(int serverEntityId, int entityId) {
mNetworked.create(entityId).serverId = serverEntityId;
serverToEntityId.put(serverEntityId, entityId);
System.out.println("put " + serverEntityId + "->" + entityId);
if (DEBUG) Gdx.app.debug(TAG, "put " + serverEntityId + "->" + entityId);
}
}

View File

@ -1,7 +1,6 @@
package com.riiablo.engine.server;
import com.artemis.ComponentMapper;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.riiablo.CharData;
@ -22,15 +21,14 @@ import com.riiablo.engine.server.component.CofAlphas;
import com.riiablo.engine.server.component.CofComponents;
import com.riiablo.engine.server.component.CofReference;
import com.riiablo.engine.server.component.CofTransforms;
import com.riiablo.engine.server.component.DS1ObjectWrapper;
import com.riiablo.engine.server.component.Interactable;
import com.riiablo.engine.server.component.Item;
import com.riiablo.engine.server.component.MapWrapper;
import com.riiablo.engine.server.component.Missile;
import com.riiablo.engine.server.component.Monster;
import com.riiablo.engine.server.component.MovementModes;
import com.riiablo.engine.server.component.Networked;
import com.riiablo.engine.server.component.Object;
import com.riiablo.engine.server.component.PathWrapper;
import com.riiablo.engine.server.component.Player;
import com.riiablo.engine.server.component.Position;
import com.riiablo.engine.server.component.Running;
@ -38,7 +36,6 @@ import com.riiablo.engine.server.component.Size;
import com.riiablo.engine.server.component.Velocity;
import com.riiablo.engine.server.component.Warp;
import com.riiablo.engine.server.component.ZoneAware;
import com.riiablo.map.DS1;
import com.riiablo.map.DT1;
import com.riiablo.map.Map;
@ -53,7 +50,6 @@ public class ServerEntityFactory extends EntityFactory {
protected ComponentMapper<Position> mPosition;
protected ComponentMapper<Velocity> mVelocity;
protected ComponentMapper<Angle> mAngle;
protected ComponentMapper<CofReference> mCofReference;
protected ComponentMapper<CofComponents> mCofComponents;
protected ComponentMapper<CofAlphas> mCofAlphas;
protected ComponentMapper<CofTransforms> mCofTransforms;
@ -61,7 +57,6 @@ public class ServerEntityFactory extends EntityFactory {
protected ComponentMapper<Object> mObject;
protected ComponentMapper<Running> mRunning;
protected ComponentMapper<Networked> mNetworked;
protected ComponentMapper<DS1ObjectWrapper> mDS1ObjectWrapper;
protected ComponentMapper<MovementModes> mMovementModes;
protected ComponentMapper<Size> mSize;
protected ComponentMapper<ZoneAware> mZoneAware;
@ -71,16 +66,17 @@ public class ServerEntityFactory extends EntityFactory {
protected ComponentMapper<Item> mItem;
protected ComponentMapper<Missile> mMissile;
protected ComponentMapper<AIWrapper> mAIWrapper;
protected ComponentMapper<PathWrapper> mPathWrapper;
protected ComponentMapper<MapWrapper> mMapWrapper;
protected ObjectInteractor objectInteractor;
protected WarpInteractor warpInteractor;
protected ItemInteractor itemInteractor;
@Override
public int createPlayer(Map map, Map.Zone zone, CharData charData, Vector2 position) {
int id = super.createEntity(Class.Type.PLR, "player", map, zone);
public int createPlayer(CharData charData, Vector2 position) {
int id = super.createEntity(Class.Type.PLR, "player");
mPlayer.create(id).data = charData;
mMapWrapper.create(id).set(map, map.getZone(position));
mPosition.create(id).position.set(position);
mVelocity.create(id).set(Engine.Player.SPEED_WALK, Engine.Player.SPEED_RUN);
@ -102,32 +98,24 @@ public class ServerEntityFactory extends EntityFactory {
}
@Override
public int createDynamicObject(Map map, Map.Zone zone, Map.Preset preset, DS1.Object object, float x, float y) {
String objectType = Riiablo.files.MonPreset.getPlace(preset.getDS1().getAct(), object.id);
public int createDynamicObject(int act, int monPresetId, float x, float y) {
String objectType = Riiablo.files.MonPreset.getPlace(act, monPresetId);
MonStats.Entry monstats = Riiablo.files.monstats.get(objectType);
if (monstats == null) {
Gdx.app.error(TAG, "Unknown dynamic entity id: " + objectType + "; " + preset + "; object=" + object);
return Engine.INVALID_ENTITY;
}
// objectType is a MonStats, MonPlace, SuperUniques
if (monstats == null) return Engine.INVALID_ENTITY;
int id = createMonster(map, zone, monstats, x, y);
mDS1ObjectWrapper.create(id).set(preset.getDS1(), object);
if (object.path != null) mPathWrapper.create(id).path = object.path;
int id = createMonster(monstats.hcIdx, x, y);
mNetworked.create(id);
return id;
}
@Override
public int createStaticObject(Map map, Map.Zone zone, Map.Preset preset, DS1.Object object, float x, float y) {
assert object.type == DS1.Object.STATIC_TYPE;
int objectType = Riiablo.files.obj.getObjectId(preset.getDS1().getAct(), object.id);
public int createStaticObject(int act, int objId, float x, float y) {
int objectType = Riiablo.files.obj.getObjectId(act, objId);
Objects.Entry base = Riiablo.files.objects.get(objectType);
if (base == null) {
Gdx.app.error(TAG, "Unknown static entity id: " + objectType + "; " + preset + "; object=" + object);
return Engine.INVALID_ENTITY;
}
if (base == null) return Engine.INVALID_ENTITY;
int id = super.createEntity(Class.Type.OBJ, base.Description, map, zone);
int id = super.createEntity(Class.Type.OBJ, base.Description);
mObject.create(id).base = base;
mPosition.create(id).position.set(x, y);
@ -140,8 +128,6 @@ public class ServerEntityFactory extends EntityFactory {
mCofTransforms.create(id);
}
mDS1ObjectWrapper.create(id).set(preset.getDS1(), object);
if (base.OperateRange > 0 && ArrayUtils.contains(base.Selectable, true)) {
mInteractable.create(id).set(base.OperateRange, objectInteractor);
}
@ -151,10 +137,11 @@ public class ServerEntityFactory extends EntityFactory {
}
@Override
public int createMonster(Map map, Map.Zone zone, MonStats.Entry monstats, float x, float y) {
public int createMonster(int monsterId, float x, float y) {
MonStats.Entry monstats = Riiablo.files.monstats.get(monsterId);
MonStats2.Entry monstats2 = Riiablo.files.monstats2.get(monstats.MonStatsEx);
int id = super.createEntity(Class.Type.MON, monstats.Id, map, zone);
int id = super.createEntity(Class.Type.MON, monstats.Id);
mMonster.create(id).set(monstats, monstats2);
mPosition.create(id).position.set(x, y);
@ -192,11 +179,12 @@ public class ServerEntityFactory extends EntityFactory {
}
@Override
public int createWarp(Map map, Map.Zone zone, int index, float x, float y) {
public int createWarp(int index, float x, float y) {
final int mainIndex = DT1.Tile.Index.mainIndex(index);
final int subIndex = DT1.Tile.Index.subIndex(index);
final int orientation = DT1.Tile.Index.orientation(index);
Map.Zone zone = map.getZone(x, y);
int dst = zone.level.Vis[mainIndex];
assert dst > 0 : "Warp to unknown level!";
int wrp = zone.level.Warp[mainIndex];
@ -206,8 +194,9 @@ public class ServerEntityFactory extends EntityFactory {
LvlWarp.Entry warp = Riiablo.files.LvlWarp.get(wrp);
int id = super.createEntity(Class.Type.WRP, "warp", map, zone);
int id = super.createEntity(Class.Type.WRP, "warp");
mWarp.create(id).set(index, warp, dstLevel);
mMapWrapper.create(id).set(map, zone);
mPosition.create(id).position.set(x, y).add(warp.OffsetX, warp.OffsetY);
@ -226,7 +215,8 @@ public class ServerEntityFactory extends EntityFactory {
}
@Override
public int createMissile(Missiles.Entry missile, Vector2 angle, Vector2 position) {
public int createMissile(int missileId, Vector2 angle, Vector2 position) {
Missiles.Entry missile = Riiablo.files.Missiles.get(missileId);
int id = super.createEntity(Class.Type.MIS, missile.Missile);
mMissile.create(id).set(missile, position, missile.Range);

View File

@ -115,7 +115,7 @@ public enum Act1MapBuilder implements MapBuilder {
for (i = 0; i < count; i++) {
int px = zone.getGlobalX(tx * DT1.Tile.SUBTILE_SIZE);
int py = zone.getGlobalY(ty * DT1.Tile.SUBTILE_SIZE);
factory.createMonster(zone.map, zone, monster, px, py);
factory.createMonster(monster, px, py);
}
}
}

View File

@ -496,7 +496,11 @@ public class Map implements Disposable {
}
public Zone getZone(Vector2 vec) {
return getZone(round(vec.x), round(vec.y));
return getZone(vec.x, vec.y);
}
public Zone getZone(float x, float y) {
return getZone(round(x), round(y));
}
public Zone getZone(int x, int y) {
@ -770,7 +774,7 @@ public class Map implements Disposable {
final int x = this.x + (warpX * DT1.Tile.SUBTILE_SIZE);
final int y = this.y + (warpY * DT1.Tile.SUBTILE_SIZE);
if (entities == EMPTY_ENTITY_ARRAY) entities = new IntArray();
int entity = map.factory.createWarp(map, this, index, x, y);
int entity = map.factory.createWarp(index, x, y);
entities.add(entity);
}
@ -1149,7 +1153,7 @@ public class Map implements Disposable {
final int y = zone.y + (ty * DT1.Tile.SUBTILE_SIZE);
for (int i = 0; i < ds1.numObjects; i++) {
DS1.Object obj = ds1.objects[i];
int entityId = zone.map.factory.createObject(zone.map, zone, this, obj, x + obj.x, y + obj.y);
int entityId = zone.map.factory.createObject(this, obj, x + obj.x, y + obj.y);
zone.addEntity(entityId); // FIXME: waypoints are placed correctly when adding 0.25f to ds1 object position -- is this consistent with others?
}
}

View File

@ -1,7 +1,9 @@
package com.riiablo.map;
import com.artemis.annotations.Wire;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntMap;
import com.riiablo.engine.Engine;
import com.riiablo.engine.EntityFactory;
import net.mostlyoriginal.api.system.core.PassiveSystem;
@ -15,7 +17,7 @@ public class MapManager extends PassiveSystem {
protected EntityFactory factory;
public void createEntities() {
for (Map.Zone zone : map.zones) {
for (Map.Zone zone : new Array.ArrayIterator<>(map.zones)) {
createWarps(zone);
createEntities(zone);
}
@ -29,8 +31,8 @@ public class MapManager extends PassiveSystem {
int hash = entry.key;
int x = zone.x + (Map.Zone.tileHashX(hash) * DT1.Tile.SUBTILE_SIZE);
int y = zone.y + (Map.Zone.tileHashY(hash) * DT1.Tile.SUBTILE_SIZE);
int id = factory.createWarp(map, zone, cell.id, x, y);
zone.entities.add(id);
int id = factory.createWarp(cell.id, x, y);
if (id != Engine.INVALID_ENTITY) zone.entities.add(id);
}
}
}
@ -51,8 +53,8 @@ public class MapManager extends PassiveSystem {
DS1 ds1 = preset.ds1;
for (int i = 0, size = ds1.numObjects; i < size; i++) {
DS1.Object object = ds1.objects[i];
int id = factory.createObject(map, zone, preset, object, x + object.x, y + object.y);
zone.entities.add(id);
int id = factory.createObject(preset, object, x + object.x, y + object.y);
if (id != Engine.INVALID_ENTITY) zone.entities.add(id);
}
}
}

View File

@ -774,7 +774,7 @@ public class GameScreen extends ScreenAdapter implements GameLoadingScreen.Loada
if (origin == null) origin = map.find(Map.ID.TOWN_ENTRY_2);
if (origin == null) origin = map.find(Map.ID.TP_LOCATION);
Map.Zone zone = map.getZone(origin);
player = engine.getSystem(ClientEntityFactory.class).createPlayer(map, zone, charData, origin);
player = factory.createPlayer(charData, origin);
engine.getSystem(EventSystem.class).dispatch(ZoneChangeEvent.obtain(player, zone));
renderer.setSrc(player);

View File

@ -23,7 +23,6 @@ import com.badlogic.gdx.utils.IntIntMap;
import com.badlogic.gdx.utils.TimeUtils;
import com.riiablo.COFs;
import com.riiablo.CharData;
import com.riiablo.CharacterClass;
import com.riiablo.Files;
import com.riiablo.Riiablo;
import com.riiablo.codec.Animation;
@ -42,6 +41,7 @@ import com.riiablo.engine.server.ServerEntityFactory;
import com.riiablo.engine.server.ServerNetworkIdManager;
import com.riiablo.engine.server.WarpInteractor;
import com.riiablo.engine.server.component.Networked;
import com.riiablo.engine.server.component.Player;
import com.riiablo.map.Act1MapBuilder;
import com.riiablo.map.DS1;
import com.riiablo.map.DS1Loader;
@ -386,14 +386,10 @@ public class D2GS extends ApplicationAdapter {
connection.cofTransformsAsByteBuffer().get(cofTransforms);
Gdx.app.log(TAG, " " + DebugUtils.toByteArray(cofTransforms));
CharData charData = new CharData().createD2S(charName, CharacterClass.get(charClass));
// Vector2 origin = map.find(Map.ID.TOWN_ENTRY_1);
// if (origin == null) origin = map.find(Map.ID.TOWN_ENTRY_2);
// if (origin == null) origin = map.find(Map.ID.TP_LOCATION);
// Map.Zone zone = map.getZone(origin);
Vector2 origin = new Vector2(132, 37); // FIXME: hacked for the time being
Map.Zone zone = map.getZone(origin);
int entityId = world.getSystem(ServerEntityFactory.class).createPlayer(map, zone, charData, origin);
Vector2 origin = map.find(Map.ID.TOWN_ENTRY_1);
if (origin == null) origin = map.find(Map.ID.TOWN_ENTRY_2);
if (origin == null) origin = map.find(Map.ID.TP_LOCATION);
int entityId = factory.createPlayer(charName, charClass, origin.x, origin.y);
player.put(packet.id, entityId);
Gdx.app.log(TAG, " entityId=" + entityId);
@ -407,6 +403,8 @@ public class D2GS extends ApplicationAdapter {
outPackets.offer(response);
Synchronize(packet.id, entityId);
CharData charData = world.getMapper(Player.class).get(entityId).data;
BroadcastConnect(packet.id, connection, charData, entityId);
}