private void OnShipAdded(Packet<IScenePeer> obj) { //Console.WriteLine("ship.add received"); if (_simulation != null && _isReady) { var shipsToAdd = obj.ReadObject<ShipCreatedDto[]>(); //while (obj.Stream.Position != obj.Stream.Length) for (var i = 0; i < shipsToAdd.Length; i++) { var shipInfos = shipsToAdd[i]; if (shipInfos.id != this.id && !_simulation.Environment.VisibleShips.ContainsKey(shipInfos.id)) { var ship = new Ship { Id = shipInfos.id, Team = shipInfos.team, X = shipInfos.x, Status = shipInfos.status, Y = shipInfos.y, Rot = shipInfos.rot, Weapons = shipInfos.weapons }; //Console.WriteLine("[" + _name + "] Ship {0} added ", shipInfos.id); lock (_simulation.Environment) { _simulation.Environment.AddShip(ship); } } } } }
private void ReviveShip(Ship ship) { var clock = _scene.GetComponent<IEnvironment>().Clock; ship.x = X_MIN + (float)(_rand.NextDouble() * (X_MAX - X_MIN)); ship.y = Y_MIN + (float)(_rand.NextDouble() * (Y_MAX - Y_MIN)); ship.PositionUpdatedOn = clock; _scene.GetComponent<ILogger>().Info("logic.respawn", "Trying to find peer for {0}", ship.player.Id); var peer = _scene.RemotePeers.FirstOrDefault(p => p.Id == ship.player.Id); if (peer != null) { _scene.GetComponent<ILogger>().Info("logic.respawn", "Sending respawn position to {0}", peer.Id); _scene.Send(new MatchPeerFilter(peer), "ship.forcePositionUpdate", (s) => { using (var writer = new BinaryWriter(s, Encoding.UTF8, true)) { writer.Write(ship.id); writer.Write(ship.x); writer.Write(ship.y); writer.Write(ship.rot); writer.Write(ship.PositionUpdatedOn); } }, PacketPriority.MEDIUM_PRIORITY, PacketReliability.RELIABLE); } ship.ChangePv(ship.maxPv - ship.currentPv); }
private Ship CreateShip(Player player) { ushort id = 0; lock (this) { id = _currentId++; } player.ShipId = id; var ship = new Ship(this) { Status = ShipStatus.Waiting, team = id,//Deathmatch id = id, player = player, rot = (float)(_rand.NextDouble() * 2 * Math.PI), x = X_MIN + (float)(_rand.NextDouble() * (X_MAX - X_MIN)), y = Y_MIN + (float)(_rand.NextDouble() * (Y_MAX - Y_MIN)), currentPv = 15, maxPv = 15, weapons = new Weapon[] { new Weapon { id = "canon", damage = 10, precision = 0.6f, coolDown = 1500, range = 200 }/*, new Weapon { id = "missile", damage = 40, precision = 0.6f, coolDown = 3 }*/ } }; return ship; }
/// <summary> /// Invoked every iteration through the frame loop. /// Update World, then sends it to each client. /// </summary> private static void Update() { // Updated world StringBuilder sb = new StringBuilder(); lock (World) { // For all Stars in World foreach (Star star in World.Stars.Values) { // Append each Star sb.Append(JsonConvert.SerializeObject(star) + "\n"); // Destroy all Ships colliding with Star foreach (Ship ship in World.Ships.Values) { Vector2D distance = star.loc - ship.loc; if (distance.Length() < StarSize) { ship.hp = 0; if (GAMEMODE_RandomDeadlyStar) { ship.score--; } ship.alive = false; DeadShips.Add(ship); } } // Destroy all Projectiles colliding with Star foreach (Projectile p in World.Projectiles.Values) { Vector2D distance = star.loc - p.loc; if (distance.Length() < StarSize) { p.alive = false; DeadProjectiles.Add(p.ID); } } } // For all Ships in World foreach (Ship ship in World.Ships.Values) { // Thrust Ship if (ship.up) { ship.thrust = true; ship.velocity += Acceleration(Thrust(ship.dir), Gravity(ship.loc)); ship.loc += ship.velocity; ship.up = false; } // Non-thrusting Ship else { ship.velocity += Gravity(ship.loc); ship.loc += ship.velocity; ship.thrust = false; } // Rotate Left if (ship.left) { ship.dir = RotateLeft(ship.dir); ship.left = false; } // Rotate right if (ship.right) { ship.dir = RotateRight(ship.dir); ship.right = false; } // Fire projectile if (ship.space && ship.alive) { // Begin spacing projectiles ship.projectileTimer++; if (ship.projectileTimer >= ProjectileFiringDelay) { Projectile p = new Projectile(); p.ID = ProjectileID; p.loc = ship.loc; p.dir = ship.dir; p.alive = true; p.owner = ship.ID; p.velocity = (p.dir * ProjectileSpeed) + ship.velocity; World.Projectiles.Add(p.ID, p); ship.projFired++; ship.projectileTimer = 0; ProjectileID++; } ship.space = false; } // If Ship exits World's bounds if (ship.loc.GetX() >= UniverseSize / 2 || ship.loc.GetX() <= -(UniverseSize / 2) || ship.loc.GetY() >= UniverseSize / 2 || ship.loc.GetY() <= -(UniverseSize / 2)) { // Wrap around Ship ship.loc = WrapAround(ship.loc); } // Destroy all Projectiles colliding with Ship and vise-versa foreach (Projectile p in World.Projectiles.Values) { Vector2D distance = ship.loc - p.loc; if (distance.Length() < ShipSize && ship.ID != p.owner && ship.alive) { p.alive = false; ship.hp--; ShipHits.Add(World.Ships[p.owner]); if (ship.hp <= 0) { ship.alive = false; DeadShips.Add(ship); ScoringShips.Add(p.owner); } DeadProjectiles.Add(p.ID); } } sb.Append(JsonConvert.SerializeObject(ship) + "\n"); } // For all Projectiles in World foreach (Projectile p in World.Projectiles.Values) { // Update projectile location with constant velocity p.loc += p.velocity; // If Projectile exits World's bounds if (p.loc.GetX() >= UniverseSize / 2 || p.loc.GetX() <= -(UniverseSize / 2) || p.loc.GetY() >= UniverseSize / 2 || p.loc.GetY() <= -(UniverseSize / 2)) { // Destroy Projectile p.alive = false; DeadProjectiles.Add(p.ID); } sb.Append(JsonConvert.SerializeObject(p) + "\n"); } // All Projectiles-to-destroy are removed from World foreach (int i in DeadProjectiles) { World.Projectiles.Remove(i); } DeadProjectiles.Clear(); // All Ships-to-score have score increased foreach (int i in ScoringShips) { Ship s = World.Ships.Values.ElementAt(i); s.score++; } ScoringShips.Clear(); // All Ships-to-destroy are removed from World and respawned foreach (Ship ship in DeadShips) { if (ship.hp <= 0) { // Incremental value has a further effect on respawn rate ship.respawnTimer += 20; } if (ship.respawnTimer >= RespawnDelay * TimePerFrame) { ship.respawnTimer = 0; ResetShip(ship); ResurrectedShips.Add(ship); } } // Respawn dead Ship foreach (Ship ship in ResurrectedShips) { DeadShips.Remove(ship); } ResurrectedShips.Clear(); // Add hit projectiles to Ship foreach (Ship ship in ShipHits) { World.Ships[ship.ID].projHit++; } ShipHits.Clear(); // Each client is updated with appended World information foreach (SocketState state in Clients) { Networking.Send(state.theSocket, sb.ToString()); } } }