package se.rhel.network.model; import com.badlogic.gdx.math.Vector3; import se.rhel.event.*; import se.rhel.model.BaseWorldModel; import se.rhel.model.component.*; import se.rhel.model.entity.ControlledPlayer; import se.rhel.model.entity.IPlayer; import se.rhel.model.physics.MyContactListener; import se.rhel.model.physics.RayVector; import se.rhel.model.weapon.Explosion; import se.rhel.model.weapon.Grenade; import se.rhel.model.weapon.IExplodable; import se.rhel.network.event.ServerModelEvent; import se.rhel.network.event.ServerModelEvents; import se.rhel.util.Utils; import se.rhel.view.input.PlayerInput; import java.util.ArrayList; import java.util.Iterator; import java.util.Map; /** * Group: Multiplayer */ public class ServerWorldModel extends BaseWorldModel { // Linkin ID's and Players //private HashMap<Integer, IPlayer> mPlayers; private final float LOW_FREQ = 0.1f; private float CURR_FREQ_TIMER = 0f; private boolean SEND_LOW_FREQ = false; public ServerWorldModel(Events events) { super(events); for(int i = 0; i < 0; i++) { float x = (float) (Math.random() * 81)-40; float z = (float) (Math.random() * 81)-40; ControlledPlayer cp = new ControlledPlayer(getBulletWorld(), new Vector3(x, 10, z)); cp.addComponent(new BasicAI(cp)); int id = Utils.getInstance().generateUniqueId(); cp.addComponent(new NetworkComponent(id)); setPlayer(id, cp); } } @Override public void update(float delta) { super.update(delta); // Low frequency update CURR_FREQ_TIMER += delta; if(CURR_FREQ_TIMER >= LOW_FREQ) { SEND_LOW_FREQ = true; CURR_FREQ_TIMER = 0f; } else { SEND_LOW_FREQ = false; } for(IPlayer p : getAllPlayers()) { p.update(delta); if(p.isAlive()) { if(((GameObject)p).hasComponent(IAIComponent.class)) { if(PlayerInput.DO_LOW_FREQ_UPDATES) { if(SEND_LOW_FREQ) { // mEvents.notify(new ServerModelEvent(EventType.PLAYER_MOVE, p)); mEvents.notify(new ServerModelEvents.GameObjectEvent(EventType.PLAYER_MOVE, (GameObject)p)); } } else { // mEvents.notify(new ServerModelEvent(EventType.PLAYER_MOVE, p)); mEvents.notify(new ServerModelEvents.GameObjectEvent(EventType.PLAYER_MOVE, (GameObject)p)); } } IActionable ac = (IActionable) ((GameObject)p).getComponent(ActionComponent.class); if(ac.hasShoot()) { RayVector ray = new RayVector(p.getShootPosition(), p.getDirection(), 75f); // mEvents.notify(new ServerModelEvent(EventType.SHOOT, ray, p)); mEvents.notify(new ServerModelEvents.ShootEvent(ray, p)); } } } //Update grenades for (Grenade grenade : getGrenades()) { grenade.update(delta); if(!grenade.isAlive()) { // A grenade is found as dead, send it to client as such // mEvents.notify(new ServerModelEvent(EventType.GRENADE, grenade, false)); mEvents.notify(new ServerModelEvents.GrenadeEvent(grenade, false)); handleExplosion(grenade); destroyGameObject(grenade); removeGrenade(grenade); } else { // The grenade is still alive and should be synched with client // If we want a lower freq update if(PlayerInput.DO_LOW_FREQ_UPDATES) { if(SEND_LOW_FREQ) { // mEvents.notify(new ServerModelEvent(EventType.GRENADE, grenade, true)); mEvents.notify(new ServerModelEvents.GrenadeEvent(grenade, true)); } } else { mEvents.notify(new ServerModelEvents.GrenadeEvent(grenade, true)); // mEvents.notify(new ServerModelEvent(EventType.GRENADE, grenade, true)); } } } Iterator it = getRespawnMap().entrySet().iterator(); while(it.hasNext()) { Map.Entry<IPlayer, Float> pairs = (Map.Entry)it.next(); IPlayer player = pairs.getKey(); float respawntimer = pairs.getValue(); respawntimer += delta; getRespawnMap().put(player, respawntimer); if(respawntimer > 5f) { respawn(player); int id = ((NetworkComponent)((GameObject)player).getComponent(NetworkComponent.class)).getID(); mEvents.notify(new ServerModelEvents.RespawnEvent(id, player.getPosition())); it.remove(); } } } public void checkShootCollision(RayVector ray, GameObject shooter) { MyContactListener.CollisionObject co = super.getShootCollision(ray); if(co != null) { if(co.type == MyContactListener.CollisionObject.CollisionType.ENTITY) { if(!co.entity.equals(shooter)) { damageEntity(co.entity, 25); // mEvents.notify(new ServerModelEvent(EventType.DAMAGE, co.entity)); mEvents.notify(new ServerModelEvents.GameObjectEvent(EventType.DAMAGE, co.entity)); } } else if(co.type == MyContactListener.CollisionObject.CollisionType.WORLD) { // mEvents.notify(new ServerModelEvent(EventType.SERVER_WORLD_COLLISION, co.hitPoint, co.hitNormal)); mEvents.notify(new ServerModelEvents.ServerWorldCollision(co.hitPoint, co.hitNormal)); } ray.setTo(co.hitPoint); } } public void handleExplosion(IExplodable exp) { ArrayList<GameObject> affected = getAffectedByExplosion(exp); for(GameObject obj : affected) { IDamageable entity = (IDamageable) obj.getComponent(DamageComponent.class); entity.damageEntity(exp.getExplosionDamage()); // mEvents.notify(new ServerModelEvent(EventType.DAMAGE, obj)); mEvents.notify(new ServerModelEvents.GameObjectEvent(EventType.DAMAGE, obj)); } } public void checkEntityStatus(GameObject entity) { IDamageable dae = (IDamageable) entity.getComponent(DamageComponent.class); if(dae.isAlive() && dae.getHealth() <= 0) { dae.setAlive(false); addRespawn((IPlayer)entity); Explosion exp = new Explosion(entity.getPosition(), 5, 50); handleExplosion(exp); // mEvents.notify(new ServerModelEvent(EventType.SERVER_DEAD_ENTITY, entity)); mEvents.notify(new ServerModelEvents.GameObjectEvent(EventType.SERVER_DEAD_ENTITY, entity)); } } public void transformEntity(int clientId, Vector3 position, Vector3 rotation) { GameObject obj = (ControlledPlayer)getPlayer(clientId); obj.rotateAndTranslate(rotation, position); } }