void Start() { for (int i = 0; i < buttonList.Count; i++) { buttonList[i].Init(); buttonList[i].SetCallback(this.OnHoverButton, this.OnExitButton, this.OnButton, null); } LvlInfo entry = new LvlInfo(); entry.lvlName = "Demo_Linear"; entry.lvlDesp = "A simple level with 3 linear paths"; levelInfoList.Add(entry); entry = new LvlInfo(); entry.lvlName = "Demo_LinearLoop"; entry.lvlDesp = "A level with single path traverse through a buildable grid, allow player to alter the creep route on the run"; levelInfoList.Add(entry); entry = new LvlInfo(); entry.lvlName = "Demo_BranchingPath"; entry.lvlDesp = "A level with branching path, each travel through island(s) of buildable grid.\nThe creep will choose the shortest route to their destination\nThis level uses procedural generation for the incoming creep"; levelInfoList.Add(entry); entry = new LvlInfo(); entry.lvlName = "Demo_Platform"; entry.lvlDesp = "A path on top of a single buildable grid of unconventional layout\nThis level is set to endless mode and uses procedural generation for the incoming creep"; levelInfoList.Add(entry); OnExitButton(null); }
public bool canRollOver(int x, int y, VehInfo type) { LvlInfo level = _arena._server._assets.Level; bool blocked = level.isTileBlocked(x, y, type); if (blocked) { x /= 16; y /= 16; int phy = level.Tiles[y * level.Width + x].Physics; short low = level.PhysicsLow[phy]; short high = level.PhysicsHigh[phy]; //Typical man vehicle: LowZ = 0 HighZ = 55 //Physic (Green): LowZ = 0 HighZ = 16 //Can we pass under or over? if (_state.positionZ > low) { blocked = false; //Not blocked } } return(blocked); }
/// <summary> /// Spawns a ball at a desired location /// </summary> static public void Spawn_Ball(Ball ball, int posX, int posY, int width, int height) { LvlInfo level = ball._arena._server._assets.Level; int x = posX - (level.OffsetX * 16); int y = posY - (level.OffsetY * 16); short w = (short)(x - width); short h = (short)(y - height); short top = (short)(x + width); short bottom = (short)(y + height); ball._state.positionX = (short)(((w - top) / 2) + top); ball._state.positionY = (short)(((h - bottom) / 2) + bottom); ball._state.positionZ = 1; ball._state.velocityX = 0; ball._state.velocityY = 0; ball._state.velocityZ = 0; ball.ballFriction = -1; //Client figures it out for us ball.ballStatus = -1; int now = Environment.TickCount; ball.tickCount = (uint)now; ball._state.lastUpdate = now; ball._state.lastUpdateServer = now; ball._owner = null; ball._lastOwner = null; //Lets update ball._arena.UpdateBall(ball); //Send it Helpers.Object_Ball(ball._arena.Players, ball); }
/// <summary> /// Keeps the combat bot around the engineer /// </summary> public Vector3 steerForFollowLeader(InfantryVehicle vehicle) { if (target == null) { return(Vector3.Zero); } LvlInfo level = _arena._server._assets.Level; List <LvlInfo.Tile> tiles = Helpers.calcBresenhems(_arena, _state.positionX, _state.positionY, target._state.positionX, target._state.positionY); for (int i = 0; i <= tiles.Count - 1; i++) { int phy = tiles[i].Physics; short low = level.PhysicsLow[phy]; short high = level.PhysicsHigh[phy]; _arena.sendArenaMessage(String.Format("Height: {0} Physic: {1}", high, tiles[i].Physics)); } Vector3 pursuitSteer = vehicle.SteerForPursuit(target._baseVehicle.Abstract, 0.2f); return(pursuitSteer); }
/// <summary> /// Load and print /// </summary> /// <param name="args">args[0] must be the level file.</param> static void Main(string[] args) { if (args.Length == 0) { throw new ArgumentException("No .lvl file given"); } LvlInfo level = LvlInfo.Load(args[0]); Print("File Opened", delegate { PrintValue("Name", args[0]); }); Print("General", delegate { PrintValue("Width", level.Width); PrintValue("Height", level.Height); }); Print("Physics", delegate { PrintValue("Low", level.PhysicsLow); PrintValue("High", level.PhysicsHigh); }); Print("Blob References (Filename, Id)", delegate { PrintValue("Object Blobs", level.ObjectBlobs); PrintValue("Floor Blobs", level.FloorBlobs); }); Print("Tile References (Terrain#, UNKNOWN, Physics/Vision)", delegate { PrintValue("Tiles", level.Tiles); }); }
/// <summary> /// Handles an item pickup request from a client /// </summary> static public void Warp(Helpers.ResetFlags flags, Player player, Arena.RelativeObj warp, int invulnTime) { LvlInfo level = player._server._assets.Level; int x = warp.posX - (level.OffsetX * 16); int y = warp.posY - (level.OffsetY * 16); //Resolve our box short height = (short)(warp.warp.GeneralData.Height / 2); short width = (short)(warp.warp.GeneralData.Width / 2); //Check for an available spot //This fixes warping onto physics int attempts = 0; for (; attempts < 10; attempts++) { short px = (short)x; short py = (short)y; if (!player._arena.getTile(px, py).Blocked) { break; } Helpers.randomPositionInArea(player._arena, ref px, ref py, width, height); } //Use our first warp! player.warp(flags, (short)-1, (short)(x - width), (short)(y - height), (short)(x + width), (short)(y + height), (short)invulnTime); //Route his new state to the rest of the arena SC_PlayerUpdate up = new SC_PlayerUpdate(); up.tickUpdate = player._state.lastUpdate; up.player = player; up.vehicle = player.ActiveVehicle; up.itemID = 0; foreach (Player p in player._arena.Players) { if (p != player) { p._client.send(up); } } }
/// <summary> /// Load and print /// </summary> /// <param name="args">args[0] must be the level file.</param> static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("No .lvl file given."); System.Threading.Thread.Sleep(5000); } else if (args[0].Contains(".map")) { Console.WriteLine("Only .lvl files may be used."); System.Threading.Thread.Sleep(5000); } else { LvlInfo level = LvlInfo.Load(args[0]); fileOut = new StreamWriter(new FileStream("Results.txt", FileMode.Create)); Print("File Opened", delegate { PrintValue("Name", args[0]); }); Print("General", delegate { PrintValue("Width", level.Width); PrintValue("Height", level.Height); }); Print("Physics", delegate { PrintValue("Low", level.PhysicsLow); PrintValue("High", level.PhysicsHigh); }); Print("Blob References (Filename, Id)", delegate { PrintValue("Object Blobs", level.ObjectBlobs); PrintValue("Floor Blobs", level.FloorBlobs); }); Print("Tile References (Terrain#, UNKNOWN, Physics/Vision)", delegate { PrintValue("Tiles", level.Tiles); }); fileOut.Close(); fileOut.Dispose(); } }
/////////////////////////////////////////////////// // Member Functions /////////////////////////////////////////////////// /// <summary> /// Generic Constructor /// </summary> public Pathfinder(ZoneServer server, LogClient logger) { _logger = logger; lvlInfo = server._assets.Level; pathingQueue = new BlockingCollection <PathfindReq>(); //Create a boolean representation of our map byte[] map = new byte[lvlInfo.Width * lvlInfo.Height]; for (int i = 0; i < lvlInfo.Height; ++i) { for (int j = 0; j < lvlInfo.Width; ++j) { //Write in the blocked tile map[(i * lvlInfo.Width) + j] = lvlInfo.Tiles[(i * lvlInfo.Width) + j].Blocked ? (byte)1 : (byte)0; } } pathHandleClr0 = createMapContext(map, lvlInfo.Width, lvlInfo.Height); //Block tiles for clearance int clearance = 2; for (int i = 0; i < lvlInfo.Height; ++i) { for (int j = 0; j < lvlInfo.Width; ++j) { if (lvlInfo.Tiles[(i * lvlInfo.Width) + j].Blocked) { //Block tiles around it for clearance int yMax = Math.Min(lvlInfo.Height - 1, (i + clearance + 1)); int xMax = Math.Min(lvlInfo.Width - 1, (j + clearance + 1)); for (int y = Math.Max(0, i - clearance); y < yMax; ++y) { for (int x = Math.Max(0, j - clearance); x < xMax; ++x) { map[(y * lvlInfo.Width) + x] = (byte)1; } } } } } //Initialize our pathfinder pathHandleClr2 = createMapContext(map, lvlInfo.Width, lvlInfo.Height); }
/// <summary> /// Updates the state in accordance with movement instructions /// </summary> public virtual bool updateState(double delta) { //If we're dead if (delta <= 0 || !bEnabled) { return(false); } //Are we frozen? if (_tickMovementFrozenUntil != 0 && _tickMovementFrozenUntil > Environment.TickCount) { _isThrustingForward = false; _isThrustingBackward = false; _isStrafingLeft = false; _isStrafingRight = false; } else { _tickMovementFrozenUntil = 0; } //Get our speed values for our current terrain SpeedValues stats = _type.TerrainSpeeds[_terrainType]; //Apply our rotation if (_isRotatingLeft) { _direction -= ((_rollRotate / 10000.0d) * delta); } else if (_isRotatingRight) { _direction += ((_rollRotate / 10000.0d) * delta); } _direction %= 240; if (_direction < 0) { _direction = 240 + _direction; } //Vectorize our direction, unf. Vector2 directionVector = Vector2.createUnitVector(_direction); Vector2 accelVector = Vector2.Zero; //Apply our thrusting instructions _thrustDirection = 0; if (_isThrustingForward) { accelVector.x += directionVector.x * _rollThrust; accelVector.y += directionVector.y * _rollThrust; _thrustDirection = _direction; } else if (_isThrustingBackward) { accelVector.x += directionVector.x * -_rollThrustBack; accelVector.y += directionVector.y * -_rollThrustBack; _thrustDirection = calculateNewDirection(_direction, 120); } if (_isStrafingLeft) { double tmpX = directionVector.x; accelVector.x += directionVector.y * _rollThrustStrafe; accelVector.y += -tmpX * _rollThrustStrafe; } else if (_isStrafingRight) { double tmpX = directionVector.x; accelVector.x += -directionVector.y * _rollThrustStrafe; accelVector.y += tmpX * _rollThrustStrafe; } //Apply our acceleration _velocity.x += accelVector.x * (delta / 1000.0d); _velocity.y += accelVector.y * (delta / 1000.0d); //Apply friction double frictionMod = 1000 - ((((((double)_rollFriction) * 800) / 256) / 10) * (delta / 10.0d)); _velocity.x = ((_velocity.x * frictionMod) / 1000.0d); _velocity.y = ((_velocity.y * frictionMod) / 1000.0d); //TODO: Add the effects of projectile explosions on our velocity //TODO: Check for physics react accordingly //Clamp our resulting velocity if (_velocity.Length >= _rollTopSpeed / 1) { _velocity.Normalize(_rollTopSpeed / 1); } //Calculate our new position double xPerTick = _velocity.x / 10000.0d; double yPerTick = _velocity.y / 10000.0d; yPerTick *= 0.70f; //Y coordinates are bigger than x by 0.7? Vector2 newPosition = new Vector2(_position.x + (xPerTick * delta), _position.y + (yPerTick * delta)); //Clamp our position newPosition.x = Math.Min(newPosition.x, (AssetManager.Manager.Level.Width - 1) * 16); newPosition.x = Math.Max(newPosition.x, 0); newPosition.y = Math.Min(newPosition.y, (AssetManager.Manager.Level.Height - 1) * 16); newPosition.y = Math.Max(newPosition.y, 0); //Check for collisions int tileX = (int)Math.Floor(_position.x / 16); int tileY = (int)Math.Floor(_position.y / 16); int newTileX = (int)Math.Floor(newPosition.x / 16); int newTileY = (int)Math.Floor(newPosition.y / 16); LvlInfo.Tile tile = _arena._tiles[(newTileY * _arena._levelWidth) + newTileX]; LvlInfo level = _arena._server._assets.Level; //Collision detection. Will expand on this later if (tile.Blocked && canRollOver((int)newPosition.x, (int)newPosition.y, _type)) { bCollision = true; _lastCollision = new Vector3(((float)_position.x) / 100.0, ((float)newPosition.y) / 100.0, 0); if (Math.Abs(tileX - newTileX) > 0) { _velocity.x *= -1; } if (Math.Abs(tileY - newTileY) > 0) { _velocity.y *= -1; } _state.yaw = (byte)_direction; _state.direction = getDirection(); //Apply any bounce physics _velocity *= _type.BouncePercent / 1000.0d; //Clamp our resulting velocity if (_velocity.Length >= _rollTopSpeed / 1) { _velocity.Normalize(_rollTopSpeed / 1); } //Calculate our new position xPerTick = _velocity.x / 10000.0d; yPerTick = _velocity.y / 10000.0d; yPerTick *= 0.70f; //Y coordinates are bigger than x by 0.7? newPosition = new Vector2(_position.x + (xPerTick * delta), _position.y + (yPerTick * delta)); //Clamp our position newPosition.x = Math.Min(newPosition.x, (AssetManager.Manager.Level.Width - 1) * 16); newPosition.x = Math.Max(newPosition.x, 0); newPosition.y = Math.Min(newPosition.y, (AssetManager.Manager.Level.Height - 1) * 16); newPosition.y = Math.Max(newPosition.y, 0); _position.x = newPosition.x; _position.y = newPosition.y; _state.positionX = (short)(uint)_position.x; _state.positionY = (short)(uint)_position.y; _state.velocityX = (short)(uint)_velocity.x; _state.velocityY = (short)(uint)_velocity.y; _state.lastUpdate = Environment.TickCount; return(false); } else { bCollision = false; } _position.x = newPosition.x; _position.y = newPosition.y; //Update the state, converting our floats into the nearest short values _state.positionX = (short)(uint)_position.x; _state.positionY = (short)(uint)_position.y; _state.velocityX = (short)(uint)_velocity.x; _state.velocityY = (short)(uint)_velocity.y; _state.yaw = (byte)_direction; _state.direction = getDirection(); _state.lastUpdate = Environment.TickCount; //TODO: Apply vector tolerance to decide whether to update return(true); }