/// <summary> /// Loads the quarter owner stuff. /// </summary> /// <param name="contentManager">Content manager of the game</param> internal static void LoadContent(ContentManager contentManager) { instance = new EmptyTownQuarterOwner(new TownQuarterOwnerContent { RoadSignTexture = contentManager.Load <Texture2D>("Textures/roadSignGreen"), FlagModel = contentManager.Load <Model>("Objects/Decorations/flagEmpty2"), AllyHumanModel = contentManager.Load <Model>("Objects/Humans/human0") }); }
/// <summary> /// Creates and generates the whole town. /// </summary> /// <param name="game">The game</param> /// <param name="loadingFrom">Loading form where the generating progress will be shown</param> public Town(ActionGame game, Loading loadingFrom) : base(game) { EmptyTownQuarterOwner.LoadContent(game.Content); quarters = new TownQuarter[game.Settings.TownQuarterCount]; //Town graph creation loadingFrom.SetLabel("Generating town graph..."); loadingFrom.SetValue(0); int[] degrees = new int[game.Settings.TownQuarterCount]; bool[,] edges = new bool[game.Settings.TownQuarterCount, game.Settings.TownQuarterCount]; // Graph is unoriented (symetric). edges[i, j] can be true only if i<j! for (int i = 0; i < game.Settings.TownQuarterCount - 1; i++) // First is made path through all. Graph has to have only one component. { int j = i + 1; degrees[i]++; degrees[j]++; edges[i, j] = true; } for (int i = 0; i < game.Settings.TownQuarterCount; i++) { loadingFrom.SetValue(100 * i / game.Settings.TownQuarterCount); for (int j = i + 1; j < game.Settings.TownQuarterCount; j++) //graph isn't oriented and reflexion is denied { if (!edges[i, j] && degrees[i] < MaxQuarterDegree && degrees[j] < MaxQuarterDegree) { if (game.Random.NextDouble() < 0.65) { degrees[i]++; degrees[j]++; edges[i, j] = true; } } } } //Quarter creating by degrees loadingFrom.SetLabel("Generating quarters and streets..."); loadingFrom.SetValue(0); for (int i = 0; i < game.Settings.TownQuarterCount; i++) { loadingFrom.SetValue(100 * i / game.Settings.TownQuarterCount); float perimeterLength = MinSideLengthPerInterface * Math.Max(degrees[i], 4); // Even interface isn't needed the side must be there perimeterLength *= (float)game.Random.NextDouble() + 1f; //Minimal length can be doubled float width = (perimeterLength / 2f) * (float)(game.Random.NextDouble() * 0.3 + 0.35); //aspect ratio float height = (perimeterLength / 2f) - width; if (width < MinQuarterSideLength) { width = MinQuarterSideLength; } if (height < MinQuarterSideLength) { height = MinQuarterSideLength; } do { try { TownQuarter quarter = new TownQuarter(game, new Vector2(width, height), degrees[i]); quarters[i] = quarter; } catch (NoSpaceForInterfaceException) { float widthIncement = MinSideLengthPerInterface * (float)game.Random.NextDouble(); width += widthIncement; height += MinSideLengthPerInterface - widthIncement; } }while (quarters[i] == null); } //Joining interfaces loadingFrom.SetLabel("Building town..."); loadingFrom.SetValue(0); for (int i = 0; i < game.Settings.TownQuarterCount; i++) { loadingFrom.SetValue(100 * i / game.Settings.TownQuarterCount); for (int j = i + 1; j < game.Settings.TownQuarterCount; j++) { if (edges[i, j]) { TownQuarterInterface ifaceI = (from iface in quarters[i].Interfaces where iface.OppositeInterface == null orderby game.Random.Next() select iface).First(); TownQuarterInterface ifaceJ = (from iface in quarters[j].Interfaces where iface.OppositeInterface == null orderby game.Random.Next() select iface).First(); ifaceI.OppositeInterface = ifaceJ; ifaceJ.OppositeInterface = ifaceI; ifaceI.LeftPathGraphVertex.AddNeighborBothDirection(ifaceJ.RightPathGraphVertex, TownQuarter.SquareWidth); ifaceI.RightPathGraphVertex.AddNeighborBothDirection(ifaceJ.LeftPathGraphVertex, TownQuarter.SquareWidth); } } } foreach (var quarter in quarters) { quarter.BuildInterfaceRoadSigns(); } //Town map base creating { Bitmap mapRaster = new Bitmap(MapImageWidth, MapImageHeight); using (Graphics graphics = Graphics.FromImage(mapRaster)) { graphics.FillRectangle(Brushes.White, 0, 0, mapRaster.Width, mapRaster.Height); float angleJump = MathHelper.TwoPi / Game.Settings.TownQuarterCount; float radius = Math.Min(MapImageWidth, MapImageHeight) / 2f - 20f; PointF center = new PointF(MapImageWidth / 2f, MapImageHeight / 2f); for (int i = 0; i < Game.Settings.TownQuarterCount; i++) { for (int j = i + 1; j < Game.Settings.TownQuarterCount; j++) { if (edges[i, j]) { graphics.DrawLine(Pens.Green, center.X + (float)Math.Cos(i * angleJump) * radius, center.Y + (float)Math.Sin(i * angleJump) * radius, center.X + (float)Math.Cos(j * angleJump) * radius, center.Y + (float)Math.Sin(j * angleJump) * radius ); } } } for (int i = 0; i < Game.Settings.TownQuarterCount; i++) { graphics.FillEllipse(Brushes.Black, center.X + (float)Math.Cos(i * angleJump) * radius - 3.5f, center.Y + (float)Math.Sin(i * angleJump) * radius - 3.5f, 7, 7); graphics.DrawString(quarters[i].Name, new Font("Verdana", 12), Brushes.Black, center.X + (float)Math.Cos(i * angleJump) * radius, center.Y + (float)Math.Sin(i * angleJump) * radius - 16); } } mapImage = mapRaster; } GC.Collect(); //Selecting starting quarter currentQuarter = quarters[0]; }