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> /// 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; if (tile.Blocked && level.isTileBlocked((int)newPosition.x, (int)newPosition.y, _type)) { bool collision = false; if (Math.Abs(tileX - newTileX) > 0) { _velocity.x *= -1; collision = true; } if (Math.Abs(tileY - newTileY) > 0) { _velocity.y *= -1; collision = true; } if (collision) { _velocity *= _type.BouncePercent / 1000.0d; } } //Finally, we can adjust our position _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); }