package ru.alastar.world; import java.util.ArrayList; import java.util.HashMap; import java.util.Timer; import java.util.TimerTask; import ru.alastar.game.Entity; import ru.alastar.game.IUpdate; import ru.alastar.game.Stats; import ru.alastar.main.Main; import ru.alastar.main.net.ConnectedClient; import ru.alastar.main.net.Server; import ru.alastar.main.net.responses.AddTileResponse; import ru.alastar.main.net.responses.ChatSendResponse; import ru.alastar.main.net.responses.RemovePacket; import ru.alastar.main.net.responses.RemoveTileResponse; import ru.alastar.main.net.responses.TargetInfoResponse; import ru.alastar.main.net.responses.UpdatePlayerResponse; import ru.alastar.physics.CollisionListener; import com.alastar.game.Tile; import com.alastar.game.enums.TileType; import com.alastar.game.enums.Type; import com.alastar.game.enums.TypeId; import com.alastar.game.enums.UpdateType; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.physics.box2d.World; public class ServerWorld { public int id = 0; public String name = "GenericWorld"; public int chunkSize = 16; public HashMap<Vector3, ServerTile> tiles; public ArrayList<IUpdate> entities; public int version = 0; public int zMin = -1; public int zMax = 10; public int xMin = -1; public int xMax = 10; public int yMax = 10; public int yMin = -1; World pWorld; Timer physicsTimer; public ServerWorld(int i, String n, int xMx, int xMn, int yMx, int yMn, int zMx, int zMn) { this.id = i; this.name = n; this.xMax = xMx; this.xMin = xMn; this.yMax = yMx; this.yMin = yMn; this.zMax = zMx; this.zMin = zMn; tiles = new HashMap<Vector3, ServerTile>(); pWorld = new World(new Vector2(0, 0), true); entities = new ArrayList<IUpdate>(); physicsTimer = new Timer(); pWorld.setContactListener(new CollisionListener()); physicsTimer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { if (pWorld != null) pWorld.step(1 / 45f, 6, 2); else cancel(); } }, 0, 10); } public void CreateTile(int x, int y, int z, TileType type, boolean p) { AddTile(new ServerTile(new Vector3(x, y, z), type, p, this)); } public void AddTile(ServerTile t) { AddTileResponse r = new AddTileResponse(); ConnectedClient c; tiles.put(t.position, t); IUpdate upd; for (int i = 0; i < entities.size(); ++i) { upd = entities.get(i); if(upd != null){ if (upd.getType() == 0) { c = Server.getClient((Entity) entities.get(i)); if (c != null) { r.x = (int) t.position.x; r.y = (int) t.position.y; r.z = (int) t.position.z; r.type = t.type; Server.SendTo(c.connection, r); } } } } } //// //This function adds IUpdate! //// public void AddEntity(IUpdate i) { entities.add(i); for (int j = entities.size() - 1; j > -1; j--) { if(entities.get(j) != null){ // sanity if (entities.get(j).getPosition().dst(i.getPosition()) <= Server.syncDistance) { entities.get(j).tryAddToNear(i); i.tryAddToNear(entities.get(j)); } } } // Main.Log("[DEBUG]","Add " + e.caption + // " to ServerWorld.entities. Count: " + entities.size()); } public void RemoveEntity(IUpdate u) { RemovePacket r = new RemovePacket(); r.id = u.getId(); r.type = u.getType(); ConnectedClient c; int index = 0; IUpdate upd; for (int i = entities.size() - 1; i > -1; i--) { upd = entities.get(i); if(upd != null) // sanity { if (upd.getType() == TypeId.getTypeId(Type.Entity)) { if (u.getId() == upd.getId()) { index = i; } c = Server.getClient(((Entity) upd)); if (c != null) { Server.SendTo(c.connection, r); } } } } entities.remove(index); // Main.Log("[DEBUG]","World entitys count: " + entities.size()); } public void RemoveTile(Tile t) { RemoveTileResponse r = new RemoveTileResponse(); ConnectedClient c; IUpdate upd; for (int i = 0; i < entities.size(); ++i) { upd = entities.get(i); if (upd.getType() == 0) { if (Server.getClient((Entity) upd) != null) { c = Server.getClient((Entity) upd); r.x = (int) t.position.x; r.y = (int) t.position.y; r.z = (int) t.position.z; if (c != null) Server.SendTo(c.connection, r); } } } try { tiles.remove(t.position); } finally { } } public ServerTile GetTile(int x, int y, int z) { return tiles.get(new Vector3(x, y, z)); } public ServerTile GetTile(Vector3 xyz) { return tiles.get(xyz); } public void SendTiles(ConnectedClient c) { } public void sendAll(String msg, String caption) { ChatSendResponse r = new ChatSendResponse(); r.msg = "\'" + msg + "\'"; r.sender = caption; ConnectedClient c; for (IUpdate e1 : entities) { if (e1.getType() == 0) { c = Server.getClient((Entity) e1); if (c != null) Server.SendTo(c.connection, r); } } Main.Log("[CHAT]", "(" + this.name + ")" + caption + ":" + msg); } public void sendAll(String msg, Entity e) { for (IUpdate e1 : e.allAround) { if (e1.getType() == 0) ((Entity) e1).handleSpeech(msg, e); } } // Updates warmode public void UpdateEntity(Entity entity) { IUpdate ent; ConnectedClient c; UpdatePlayerResponse r = new UpdatePlayerResponse(); r.updType = UpdateType.Mode; r.id = entity.id; r.val = entity.warMode; for (int i = 0; i < entities.size(); ++i) { ent = entities.get(i); if (ent.getType() == 0) { c = Server.getClient((Entity) ent); if (c != null) Server.SendTo(c.connection, r); } } } public void UpdateNear(IUpdate e2) { IUpdate e; for (int i = e2.getAround().size() - 1; i > -1; i--) { e = e2.getAround().get(i); if( e != null) //sanity { if (e.getPosition().dst(e2.getPosition()) > Server.syncDistance) { e.tryRemoveNear(e2); e2.tryRemoveNear(e); UpdateNear(e2); break; } } } for (int i = entities.size() - 1; i > -1; i--) { e = entities.get(i); if(e != null) //sanity { if (e.getPosition().dst(e2.getPosition()) <= Server.syncDistance) { e.tryAddToNear(e2); e2.tryAddToNear(e); } } } } public void UpdateTargetInfo(Entity entity, Stats stats) { TargetInfoResponse r = new TargetInfoResponse(); r.id = entity.id; r.hits = stats.get("Hits").value; r.mhits = stats.get("Hits").maxValue; for (IUpdate e : entity.allAround) { if (e.getType() == 0) { if (!((Entity) e).isAI) { if (((Entity) e).target == entity) Server.SendTo(Server.getClient((Entity) e).connection, r); } } } } public World getPhysic() { return pWorld; } }