package ru.alastar.game; import java.util.ArrayList; import java.util.Timer; import java.util.TimerTask; import com.alastar.game.enums.ItemType; import com.alastar.game.enums.Type; import com.alastar.game.enums.TypeId; import com.alastar.game.enums.UpdateItemType; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.physics.box2d.Body; import com.badlogic.gdx.physics.box2d.BodyDef; import com.badlogic.gdx.physics.box2d.CircleShape; import com.badlogic.gdx.physics.box2d.Fixture; import com.badlogic.gdx.physics.box2d.FixtureDef; import com.badlogic.gdx.physics.box2d.BodyDef.BodyType; import ru.alastar.enums.EquipType; import ru.alastar.main.net.ConnectedClient; import ru.alastar.main.net.Server; import ru.alastar.main.net.responses.AddItemResponse; import ru.alastar.main.net.responses.RemovePacket; import ru.alastar.main.net.responses.UpdateItemResponse; import ru.alastar.physics.IPhysic; import ru.alastar.physics.PhysicalData; import ru.alastar.world.ServerTile; import ru.alastar.world.ServerWorld; public class Item extends Transform implements IUpdate, IPhysic { public int id; public String caption; public int amount; public int entityId; public EquipType eqType; public Attributes attributes; public ItemType type; public int worldId; public boolean active = false; public ArrayList<IUpdate> allAround; private Timer updateTimer = null; // Physics BodyDef bodyDef; public Body body; FixtureDef fixtureDef; Fixture fixture; CircleShape circle; PhysicalData pData; public Item(int i, int ei, String c, int a, float f, float g, float h, EquipType et, ItemType type, Attributes a1, int wId) { super((int) h); this.id = i; this.caption = c; this.amount = a; this.entityId = ei; this.eqType = et; this.type = type; this.attributes = a1; this.worldId = wId; this.allAround = new ArrayList<IUpdate>(); bodyDef = new BodyDef(); bodyDef.type = BodyType.DynamicBody; bodyDef.position.set(f, g); bodyDef.linearDamping = 1.6F; Server.SaveItem(this); } public void setActive() { body = Server.getWorld(worldId).getPhysic().createBody(bodyDef); pData = new PhysicalData(this.z, false, this); circle = new CircleShape(); circle.setRadius(1f); fixtureDef = new FixtureDef(); fixtureDef.shape = circle; fixtureDef.density = 0.5f; fixtureDef.friction = 0.4f; fixtureDef.restitution = 0.6f; fixture = body.createFixture(fixtureDef); fixture.setUserData((IPhysic)this); circle.dispose(); active = true; final Item e = this; updateTimer = new Timer(); updateTimer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { if (e.body.isActive()){ Server.UpdatePosition(e); CheckIfInAir(); } else { } } }, 100, 100); } public void Destroy() { if(active){ this.body.destroyFixture(fixture); this.getWorld().getPhysic().destroyBody(body); this.getWorld().RemoveEntity(this); } } public int getAttributeValue(String s) { return attributes.getValue(s); } public boolean setAttributeValue(String s, int v) { return attributes.setValue(s, v); } public void diffValue(String s, int i) { attributes.setValue(s, attributes.getValue(s) - i); } @Override public void UpdateTo(ConnectedClient c) { if (c != null) { // MUST DO IT ALWAYS! UpdateTo() can take an AI controlled Entity // that have no ConnectedClient! AddItemResponse r = new AddItemResponse(); r.id = this.id; r.caption = this.caption; r.type = this.type; r.attrs = this.attributes.values; r.amount = this.amount; r.x = this.getPosition().x; r.y = this.getPosition().y; r.z = this.z; Server.SendTo(c, r); } } @Override public void RemoveTo(ConnectedClient c) { if (c != null) // MUST DO IT ALWAYS! RemoveTo() can take an AI // controlled Entity that have no ConnectedClient! { RemovePacket r = new RemovePacket(); r.id = this.id; r.type = TypeId.getTypeId(Type.Item); Server.SendTo(c, r); } } private void CheckIfInAir() { ServerTile t; for (int z = this.z - 1; z > getWorld().zMin; --z) { t = getWorld().GetTile(new Vector3((int) body.getPosition().x, (int) body.getPosition().y, z)); if (t == null) { this.z = z; } else break; } } @Override public void tryRemoveNear(IUpdate i) { if (allAround.contains(i)) { allAround.remove(i); if (i.getType() == TypeId.getTypeId(Type.Entity)) RemoveTo(Server.getClient((Entity) i)); } } @Override public void tryAddToNear(IUpdate e) { if (!allAround.contains(e)) { allAround.add(e); if (e.getType() == TypeId.getTypeId(Type.Entity)){ UpdateTo(Server.getClient((Entity) e)); } } } @Override public int getType() { return TypeId.getTypeId(Type.Item); } @Override public void UpdateAround() { getWorld().UpdateNear(this); ConnectedClient c; UpdateItemResponse r = new UpdateItemResponse(); r.id = id; r.updType = UpdateItemType.Position; r.x = getPosition().x; r.y = getPosition().y; r.z = z; for (IUpdate ent : allAround) { if (ent.getType() == TypeId.getTypeId(Type.Entity)) { c = Server.getClient((Entity) ent); if (c != null) Server.SendTo(c.connection, r); } } } @Override public ServerWorld getWorld() { return Server.getWorld(worldId); } @Override public Vector2 getPosition() { if (active) return body.getPosition(); else return bodyDef.position; } @Override public ArrayList<IUpdate> getAround() { return allAround; } @Override public PhysicalData getData() { return pData; } @Override public void UpdatePhysicalData(int z, boolean b) { this.pData.setZ(z); this.pData.setIgnore(b); } @Override public int getId() { return id; } }