/// <summary> /// Creates a new ball and adds it to our tracking list /// </summary> public Ball newBall(short ballID) { //Maxed out? if (_balls.Count == Arena.maxBalls) { return(null); } //Do we exist? if (_balls.getObjByID((ushort)ballID) != null) { return(null); } //Create our ball object Ball ball = new Ball(ballID, this); if (ball != null) { //Add it to the arena tracker _balls.Add(ball); return(ball); } return(null); }
/// <summary> /// Determines whether there is a vehicle antiwarping the player in the specified area /// </summary> public Computer checkVehAntiWarp(Player player) { ObjTracker <Computer> computers = new ObjTracker <Computer>(); foreach (Vehicle vehicle in _vehicles) { //Cast it properly Computer computer = vehicle as Computer; if (computer == null) { continue; } else { computers.Add(computer); } } //Get the list of computers in the area List <Computer> candidates = candidates = computers.getObjsInRange(player._state.positionX, player._state.positionY, 5000); foreach (Computer candidate in candidates) { //Any anti-warp utils? if (!candidate._activeEquip.Any(util => util.antiWarpDistance != -1)) { continue; } //Ignore your own team if (candidate._team == player._team) { continue; } //Is computer still operable? if (candidate._state.health < candidate._type.HitpointsRequiredToOperate) { continue; } //Is it within the distance? int dist = (int)(player._state.position().Distance(candidate._state.position()) * 100); if (candidate._activeEquip.Any(util => util.antiWarpDistance >= dist)) { return(candidate); } } return(null); }
/// <summary> /// Creates and adds a new bot vehicle to the arena /// </summary> public Bot newBot(Type botType, VehInfo type, Team team, Player owner, Helpers.ObjectState state, params object[] args) { //Is this bot type compatible? if (!typeof(Bot).IsAssignableFrom(botType)) { Log.write(TLog.Error, "Unable to infer bot type from type '{0}'.", botType); return(null); } //Sanity checks VehInfo.Car carType = type as VehInfo.Car; if (carType == null) { Log.write(TLog.Error, "Bots can only be created using Car vehicles."); return(null); } //Too many vehicles? if (_vehicles.Count == maxVehicles) { Log.write(TLog.Warning, "Vehicle list full."); return(null); } //We want to continue wrapping around the vehicleid limits //looking for empty spots. ushort vk; for (vk = _lastVehicleKey; vk <= UInt16.MaxValue; ++vk) { //If we've reached the maximum, wrap around if (vk == UInt16.MaxValue) { vk = 5001; continue; } //Does such a vehicle exist? if (_vehicles.getObjByID(vk) != null) { continue; } //We have a space! break; } _lastVehicleKey = (ushort)(vk + 1); //Create our vehicle class Bot newBot; Helpers.ObjectState newState = new Helpers.ObjectState(); if (state != null) { newState.positionX = state.positionX; newState.positionY = state.positionY; newState.positionZ = state.positionZ; newState.yaw = state.yaw; if (args != null && args.Length > 0) { //Put together a new argument list object[] arguments = new object[3 + args.Length]; arguments[0] = carType; arguments[1] = newState; arguments[2] = this; Array.Copy(args, 0, arguments, 3, args.Length); newBot = (Bot)Activator.CreateInstance(botType, arguments); } else { newBot = (Bot)Activator.CreateInstance(botType, carType, newState, this); } } else { if (args != null && args.Length > 0) { //Put together a new argument list object[] arguments = new object[2 + args.Length]; arguments[0] = carType; arguments[1] = this; Array.Copy(args, 0, arguments, 2, args.Length); newBot = (Bot)Activator.CreateInstance(botType, arguments); } else { newBot = (Bot)Activator.CreateInstance(botType, carType, this); } } if (newBot == null) { Log.write(TLog.Error, "Error while instancing bot type '{0}'", botType); return(null); } newBot._arena = this; newBot._id = vk; newBot._team = team; newBot._creator = owner; newBot._tickCreation = Environment.TickCount; newBot.assignDefaultState(); //This uses the new ID automatically _vehicles.Add(newBot); _bots.Add(newBot); _botsInArena++; //Notify everyone of the new vehicle Helpers.Object_Vehicles(Players, newBot); return(newBot); }
/// <summary> /// Creates and adds a new vehicle to the arena /// </summary> public Vehicle newVehicle(VehInfo type, Team team, Player creator, Helpers.ObjectState state, Action <Vehicle> setupCB, Type classType) { //Too many vehicles? if (_vehicles.Count == maxVehicles) { Log.write(TLog.Warning, "Vehicle list full."); return(null); } //We want to continue wrapping around the vehicleid limits //looking for empty spots. ushort vk; for (vk = _lastVehicleKey; vk <= UInt16.MaxValue; ++vk) { //If we've reached the maximum, wrap around if (vk == UInt16.MaxValue) { vk = 5001; continue; } //Does such a vehicle exist? if (_vehicles.getObjByID(vk) != null) { continue; } //We have a space! break; } //TODO: There might be some kind of strange bug regarding re-used vehicle // ids, even if you attempt to dispose of them. _lastVehicleKey = (ushort)(vk + 1); //Create our vehicle class Vehicle veh; if (classType == null) { if (type.Type == VehInfo.Types.Computer) { veh = new Computer(type as VehInfo.Computer, this); } else { veh = new Vehicle(type, this); } } else { veh = Activator.CreateInstance(classType, type, this) as Vehicle; } veh._id = vk; veh._team = team; veh._creator = creator; veh._oldTeam = creator != null ? creator._team : null; veh._tickUnoccupied = veh._tickCreation = Environment.TickCount; if (state != null) { veh._state.positionX = state.positionX; veh._state.positionY = state.positionY; veh._state.positionZ = state.positionZ; veh._state.yaw = state.yaw; if (veh._type.Type == VehInfo.Types.Computer) { veh._state.fireAngle = state.yaw; //Temporary fix for computer updates rotating north by default, perm fix would be sc_vehices.cs packet fix } if (veh._type.Type == VehInfo.Types.Dependent) { VehInfo.Dependent dep = veh._type as VehInfo.Dependent; veh._state.pitch = (byte)(dep.ChildElevationLowAngle > 0 ? dep.ChildElevationLowAngle : 0); } } veh.assignDefaultState(); //Custom setup? if (setupCB != null) { setupCB(veh); } //This uses the new ID automatically _vehicles.Add(veh); //Notify everyone of the new vehicle Helpers.Object_Vehicles(Players, veh); //Handle dependent vehicles? int slot = 0; foreach (int vid in veh._type.ChildVehicles) { //Nothing? slot++; if (vid <= 0) { continue; } //Find the vehicle type VehInfo childType = _server._assets.getVehicleByID(vid); if (childType == null) { Log.write(TLog.Error, "Invalid child vehicle id '{0}' for {1}.", vid, type); continue; } //Create it! Vehicle child = newVehicle(childType, team, creator, state, delegate(Vehicle c) { c._parent = veh; c._parentSlot = slot - 1; } ); veh._childs.Add(child); //Notify everyone of the new vehicle Helpers.Object_Vehicles(Players, child); } //If it's not a spectator or dependent vehicle, let the arena pass it to the script if (type.Type != VehInfo.Types.Dependent && type.Type != VehInfo.Types.Spectator) { handleVehicleCreation(veh, team, creator); } return(veh); }