/// <summary> /// Builds the roadsigns for the neighbor quarters. /// </summary> public void BuildInterfaceRoadSigns() { const float vPosition = 8; float height = 2f; const float width = 6f; const float halfWidth = width / 2; Model handleModel = game.Content.Load<Model>("Objects/roadSignHandle"); Vector3 handleModelSize = handleModel.GetSize(game.Drawer.WorldTransformMatrix); foreach (TownQuarterInterface iface in interfaces) { Vector2 handlePos = Vector2.Zero; float handleAzimuth = 0f; Vector3 upperLeft = iface.Position().ToVector3(vPosition); Vector3 upperRight = upperLeft; const float handleEpsilon = 0.02f; //2cm switch (iface.SidePosition) { case TownQuarterInterfacePosition.Top: upperLeft.X -= halfWidth; upperRight.X += halfWidth; upperLeft.Z += (BlockWidth - 2) * SquareWidth; upperRight.Z += (BlockWidth - 2) * SquareWidth; handlePos = upperLeft.XZToVector2(); handlePos.X += halfWidth; handlePos.X -= handleModelSize.X * 0.5f; handlePos.Y -= handleModelSize.Z + handleEpsilon; handleAzimuth = 0f; break; case TownQuarterInterfacePosition.Right: upperLeft.Z -= halfWidth; upperRight.Z += halfWidth; upperLeft.X -= (BlockWidth - 2) * SquareWidth; upperRight.X -= (BlockWidth - 2) * SquareWidth; handlePos = upperLeft.XZToVector2(); handlePos.Y += halfWidth; //handlePos.Y -= handleModelSize.X * 0.5f; handlePos.X += handleModelSize.Z + handleEpsilon - handleModelSize.X * 0.5f - handleModelSize.Z * 0.5f; handleAzimuth = MathHelper.PiOver2; break; case TownQuarterInterfacePosition.Bottom: upperLeft.X += halfWidth; upperRight.X -= halfWidth; upperLeft.Z -= (BlockWidth - 2) * SquareWidth; upperRight.Z -= (BlockWidth - 2) * SquareWidth; handlePos = upperLeft.XZToVector2(); handlePos.X -= halfWidth; handlePos.X -= handleModelSize.X * 0.5f; handlePos.Y += handleEpsilon; handleAzimuth = 0f; break; case TownQuarterInterfacePosition.Left: upperLeft.Z += halfWidth; upperRight.Z -= halfWidth; upperLeft.X += (BlockWidth - 2) * SquareWidth; upperRight.X += (BlockWidth - 2) * SquareWidth; handlePos = upperLeft.XZToVector2(); handlePos.Y -= halfWidth; //handlePos.Y -= handleModelSize.X * 0.5f; handlePos.X -= handleModelSize.Z + handleEpsilon + handleModelSize.X * 0.5f - handleModelSize.Z * 0.5f; handleAzimuth = MathHelper.PiOver2; break; default: break; } Vector3 lowerLeft = upperLeft, lowerRight = upperRight; lowerLeft.Y -= height; lowerRight.Y -= height; Plate signPlate = new Plate(this, upperLeft, upperRight, lowerLeft, lowerRight, iface.OppositeInterface.Quarter.RoadSignTexture, game.Content.Load<Texture2D>("Textures/metal"), true); magicPlates.AddLast(signPlate); iface.OppositeInterface.Quarter.RegisterNewRoadSign(signPlate); SpatialObject handle = new SpatialObject(handleModel, new PositionInTown(this, handlePos), handleAzimuth, game.Drawer.WorldTransformMatrix); solidObjects.AddLast(handle); } }
/// <summary> /// Fills the concrete rectangle with buildings. /// </summary> /// <param name="buildingModels">Available building models</param> /// <param name="target">Target rectangle</param> private void FillByBuildings(Model[] buildingModels, RectangleF target) { Matrix worldTransform = game.Drawer.WorldTransformMatrix; Random rand = game.Random; float horizontalSpace = (float)(rand.NextDouble() * 0.7 + 0.3) * BetweenBuildingSpace; float verticalSpace = (float)(rand.NextDouble() * 0.7 + 0.3) * BetweenBuildingSpace; IEnumerable<Model> modelCandidates = from model in buildingModels where model.GetSize(worldTransform).X + horizontalSpace <= target.Width && model.GetSize(worldTransform).Z + verticalSpace <= target.Height orderby -(rand.NextDouble(0.4,1.0) * model.GetSize(worldTransform).X * model.GetSize(worldTransform).Z) select model; if (modelCandidates.Any()) { Model usedModel = modelCandidates.First(); SpatialObject building = new SpatialObject( usedModel, this, new Vector3(target.X + horizontalSpace / 2f, 0, target.Y + verticalSpace / 2f), 0, worldTransform); solidObjects.AddLast(building); RectangleF nextRect = new RectangleF( target.X + usedModel.GetSize(worldTransform).X + horizontalSpace, target.Y, target.Width - usedModel.GetSize(worldTransform).X - horizontalSpace, usedModel.GetSize(worldTransform).Z + verticalSpace); RectangleF downRect = new RectangleF( target.X, target.Y + usedModel.GetSize(worldTransform).Z + verticalSpace, target.Width, target.Height - usedModel.GetSize(worldTransform).Z - verticalSpace); FillByBuildings(buildingModels, nextRect); FillByBuildings(buildingModels, downRect); } }
/// <summary> /// Fills empty range of town quarter border with buildings. It takes it by dimension X - first fit. /// </summary> /// <param name="buildingModels">Availible models</param> /// <param name="borderPosition">Position of border - specifies side of rectangle</param> /// <param name="range">Empty range for filling</param> /// <param name="offset">Already filled part of range</param> private int FillEmptyBorderRange(Model[] buildingModels, TownQuarterInterfacePosition borderPosition, Range range, float offset, bool lastOne) { float emptySpace = (range.Length - 1) * SquareWidth - offset; foreach(Model model in buildingModels) { if (model.GetSize(game.Drawer.WorldTransformMatrix).X <= emptySpace) { Model usedModel = model; Vector3 usedModelSize = usedModel.GetSize(game.Drawer.WorldTransformMatrix); float angle = 0; Vector3 position = Vector3.Zero; float newOffset = offset + usedModelSize.X; switch (borderPosition) { case TownQuarterInterfacePosition.Top: position = new Vector3(range.Begin * SquareWidth + SquareWidth + offset, 0, BlockWidth * SquareWidth - SquareWidth - usedModelSize.Z); break; case TownQuarterInterfacePosition.Right: position = new Vector3(BlockWidth * SquareWidth - SquareWidth - usedModelSize.X / 2 + usedModelSize.Z / 2 + +(bitmapSize.Width - 2 * (BlockWidth - 1)) * SquareWidth, 0, range.Begin * SquareWidth + SquareWidth + offset + usedModelSize.X / 2 - usedModelSize.Z / 2); angle = MathHelper.PiOver2; break; case TownQuarterInterfacePosition.Bottom: position = new Vector3(range.Begin * SquareWidth + SquareWidth + offset, 0, BlockWidth * SquareWidth - SquareWidth + (bitmapSize.Height - 2 * (BlockWidth - 1)) * SquareWidth); break; case TownQuarterInterfacePosition.Left: position = new Vector3(BlockWidth * SquareWidth - SquareWidth - usedModelSize.X / 2 - usedModelSize.Z / 2, 0, range.Begin * SquareWidth + SquareWidth + offset + usedModelSize.X / 2 - usedModelSize.Z / 2); angle = MathHelper.PiOver2; break; default: break; } SpatialObject borderBuilding = new SpatialObject(usedModel, this, position, angle, game.Drawer.WorldTransformMatrix); solidObjects.AddLast(borderBuilding); int recRes = 0; if (!lastOne) { recRes = FillEmptyBorderRange(buildingModels, borderPosition, range, newOffset, false); } if (recRes == 0 && !lastOne) { Range overflowedRange = range; overflowedRange.End++; recRes = FillEmptyBorderRange(new Model[] {buildingModels.Last()}, borderPosition, overflowedRange, newOffset, true); } return recRes + 1; //break; } } return 0; }
/// <summary> /// Destroys and removes object from this quarter evidence. /// </summary> /// <param name="obj">The destroyed object</param> public void DestroyObject(SpatialObject obj) { if (!updateProcessing) { if (obj is Human) { guards.Remove(obj as Human); walkers.Remove(obj as Human); } else if(obj is Box) { //solidObjects.Remove(obj); boxes.Remove(obj as Box); } game.Drawer.StopDrawingObject(obj); spaceGrid.RemoveObject(obj); } else { awaitingDestroy.Add(obj); } }