|
1 | 1 | using System.Collections.Generic; |
| 2 | +using System; |
2 | 3 | using Godot; |
3 | 4 | using ConvertCiv3Media; |
4 | 5 | using C7GameData; |
@@ -183,14 +184,146 @@ public BuildingLayer() |
183 | 184 | public override void drawObject(LooseView looseView, Tile tile, Vector2 tileCenter) |
184 | 185 | { |
185 | 186 | if (tile.hasBarbarianCamp) { |
186 | | - var texRect = new Rect2(buildingSpriteSize * new Vector2 (2, 0), buildingSpriteSize); |
| 187 | + var texRect = new Rect2(buildingSpriteSize * new Vector2 (2, 0), buildingSpriteSize); //(2, 0) is the offset in the TerrainBuildings.PCX file (top row, third in) |
187 | 188 | // TODO: Modify this calculation so it doesn't assume buildingSpriteSize is the same as the size of the terrain tiles |
188 | 189 | var screenRect = new Rect2(tileCenter - (float)0.5 * buildingSpriteSize, buildingSpriteSize); |
189 | 190 | looseView.DrawTextureRectRegion(buildingsTex, screenRect, texRect); |
190 | 191 | } |
191 | 192 | } |
192 | 193 | } |
193 | 194 |
|
| 195 | +public class CityLayer : ILooseLayer { |
| 196 | + private ImageTexture cityTexture; |
| 197 | + private Vector2 citySpriteSize; |
| 198 | + |
| 199 | + public CityLayer() |
| 200 | + { |
| 201 | + //TODO: Generalize, support multiple city types, etc. |
| 202 | + this.cityTexture = Util.LoadTextureFromPCX("Art/Cities/rROMAN.PCX", 0, 0, 167, 95); |
| 203 | + this.citySpriteSize = new Vector2(167, 95); |
| 204 | + } |
| 205 | + |
| 206 | + public void drawObject(LooseView looseView, Tile tile, Vector2 tileCenter) |
| 207 | + { |
| 208 | + if (tile.cityAtTile != null) { |
| 209 | + City city = tile.cityAtTile; |
| 210 | + GD.Print("Tile " + tile.xCoordinate + ", " + tile.yCoordinate + " has a city named " + city.name); |
| 211 | + Rect2 screenRect = new Rect2(tileCenter - (float)0.5 * citySpriteSize, citySpriteSize); |
| 212 | + Rect2 textRect = new Rect2(new Vector2(0, 0), citySpriteSize); |
| 213 | + looseView.DrawTextureRectRegion(cityTexture, screenRect, textRect); |
| 214 | + |
| 215 | + DynamicFont smallFont = new DynamicFont(); |
| 216 | + smallFont.FontData = ResourceLoader.Load("res://Fonts/NotoSans-Regular.ttf") as DynamicFontData; |
| 217 | + smallFont.Size = 11; |
| 218 | + |
| 219 | + String cityNameAndGrowth = city.name + " : 10"; |
| 220 | + String productionDescription = "Warrior : 5"; |
| 221 | + |
| 222 | + int cityNameAndGrowthWidth = (int)smallFont.GetStringSize(cityNameAndGrowth).x; |
| 223 | + int productionDescriptionWidth = (int)smallFont.GetStringSize(productionDescription).x; |
| 224 | + int maxTextWidth = Math.Max(cityNameAndGrowthWidth, productionDescriptionWidth); |
| 225 | + GD.Print("Width of city name = " + maxTextWidth); |
| 226 | + |
| 227 | + int cityLabelWidth = maxTextWidth + (city.IsCapital()? 70 : 45); //TODO: Is 65 right? 70? Will depend on whether it's capital, too |
| 228 | + int textAreaWidth = cityLabelWidth - (city.IsCapital() ? 50 : 25); |
| 229 | + GD.Print("City label width: " + cityLabelWidth); |
| 230 | + GD.Print("Text area width: " + textAreaWidth); |
| 231 | + const int CITY_LABEL_HEIGHT = 23; |
| 232 | + const int TEXT_ROW_HEIGHT = 9; |
| 233 | + const int LEFT_RIGHT_BOXES_WIDTH = 24; |
| 234 | + const int LEFT_RIGHT_BOXES_HEIGHT = CITY_LABEL_HEIGHT - 2; |
| 235 | + |
| 236 | + //Label/name/producing area |
| 237 | + Image labelImage = new Image(); |
| 238 | + labelImage.Create(cityLabelWidth, CITY_LABEL_HEIGHT, false, Image.Format.Rgba8); |
| 239 | + labelImage.Fill(Color.Color8(0, 0, 0, 0)); |
| 240 | + byte transparencyLevel = 192; //25% |
| 241 | + Color civColor = Color.Color8(227, 10, 10, transparencyLevel); //Roman Red |
| 242 | + Color civColorDarker = Color.Color8(0, 0, 138, transparencyLevel); //todo: automate the darker() function. maybe less transparency? |
| 243 | + Color topRowGrey = Color.Color8(32, 32, 32, transparencyLevel); |
| 244 | + Color bottomRowGrey = Color.Color8(48, 48, 48, transparencyLevel); |
| 245 | + Color backgroundGrey = Color.Color8(64, 64, 64, transparencyLevel); |
| 246 | + Color borderGrey = Color.Color8(80, 80, 80, transparencyLevel); |
| 247 | + |
| 248 | + Image horizontalBorder = new Image(); |
| 249 | + horizontalBorder.Create(cityLabelWidth - 2, 1, false, Image.Format.Rgba8); |
| 250 | + horizontalBorder.Fill(borderGrey); |
| 251 | + labelImage.BlitRect(horizontalBorder, new Rect2(0, 0, new Vector2(cityLabelWidth - 2, 1)), new Vector2(1, 0)); |
| 252 | + labelImage.BlitRect(horizontalBorder, new Rect2(0, 0, new Vector2(cityLabelWidth - 2, 1)), new Vector2(1, 22)); |
| 253 | + |
| 254 | + Image verticalBorder = new Image(); |
| 255 | + verticalBorder.Create(1, CITY_LABEL_HEIGHT - 2, false, Image.Format.Rgba8); |
| 256 | + verticalBorder.Fill(borderGrey); |
| 257 | + labelImage.BlitRect(verticalBorder, new Rect2(0, 0, new Vector2(1, 23)), new Vector2(0, 1)); |
| 258 | + labelImage.BlitRect(verticalBorder, new Rect2(0, 0, new Vector2(1, 23)), new Vector2(cityLabelWidth - 1, 1)); |
| 259 | + |
| 260 | + Image bottomRow = new Image(); |
| 261 | + bottomRow.Create(textAreaWidth, 1, false, Image.Format.Rgba8); |
| 262 | + bottomRow.Fill(bottomRowGrey); |
| 263 | + labelImage.BlitRect(bottomRow, new Rect2(0, 0, new Vector2(textAreaWidth, 1)), new Vector2(25, 21)); |
| 264 | + |
| 265 | + Image topRow = new Image(); |
| 266 | + topRow.Create(textAreaWidth, 1, false, Image.Format.Rgba8); |
| 267 | + topRow.Fill(topRowGrey); |
| 268 | + labelImage.BlitRect(topRow, new Rect2(0, 0, new Vector2(textAreaWidth, 1)), new Vector2(25, 1)); |
| 269 | + |
| 270 | + Image background = new Image(); |
| 271 | + background.Create(textAreaWidth, TEXT_ROW_HEIGHT, false, Image.Format.Rgba8); |
| 272 | + background.Fill(backgroundGrey); |
| 273 | + labelImage.BlitRect(background, new Rect2(0, 0, new Vector2(textAreaWidth, 9)), new Vector2(25, 2)); |
| 274 | + labelImage.BlitRect(background, new Rect2(0, 0, new Vector2(textAreaWidth, 9)), new Vector2(25, 12)); |
| 275 | + |
| 276 | + Image centerDivider = new Image(); |
| 277 | + centerDivider.Create(textAreaWidth, 1, false, Image.Format.Rgba8); |
| 278 | + centerDivider.Fill(civColor); |
| 279 | + labelImage.BlitRect(centerDivider, new Rect2(0, 0, new Vector2(textAreaWidth, 1)), new Vector2(25, 11)); |
| 280 | + |
| 281 | + Image leftAndRightBoxes = new Image(); |
| 282 | + leftAndRightBoxes.Create(LEFT_RIGHT_BOXES_WIDTH, LEFT_RIGHT_BOXES_HEIGHT, false, Image.Format.Rgba8); |
| 283 | + leftAndRightBoxes.Fill(civColor); |
| 284 | + labelImage.BlitRect(leftAndRightBoxes, new Rect2(0, 0, new Vector2(24, 21)), new Vector2(1, 1)); |
| 285 | + if (city.IsCapital()) { |
| 286 | + labelImage.BlitRect(leftAndRightBoxes, new Rect2(0, 0, new Vector2(24, 21)), new Vector2(cityLabelWidth - 25, 1)); |
| 287 | + |
| 288 | + Pcx cityIcons = Util.LoadPCX("Art/Cities/city icons.pcx"); |
| 289 | + Image nonEmbassyStar = PCXToGodot.getImageFromPCX(cityIcons, 20, 1, 18, 18); |
| 290 | + labelImage.BlendRect(nonEmbassyStar, new Rect2(0, 0, new Vector2(18, 18)), new Vector2(cityLabelWidth - 24, 2)); |
| 291 | + } |
| 292 | + |
| 293 | + //todo: darker shades of civ color around edges |
| 294 | + |
| 295 | + ImageTexture label = new ImageTexture(); |
| 296 | + label.CreateFromImage(labelImage, 0); |
| 297 | + |
| 298 | + Rect2 labelDestination = new Rect2(tileCenter + new Vector2(cityLabelWidth/-2, 24), new Vector2(cityLabelWidth, CITY_LABEL_HEIGHT)); //24 is a swag |
| 299 | + Rect2 allOfTheLabel = new Rect2(new Vector2(0, 0), new Vector2(cityLabelWidth, CITY_LABEL_HEIGHT)); |
| 300 | + looseView.DrawTextureRectRegion(label, labelDestination, allOfTheLabel); |
| 301 | + |
| 302 | + //Destination for font is based on lower-left of baseline of font, not upper left as for blitted rectangles |
| 303 | + int cityNameOffset = cityNameAndGrowthWidth/-2; |
| 304 | + int prodDescriptionOffset = productionDescriptionWidth/-2; |
| 305 | + if (!city.IsCapital()) { |
| 306 | + cityNameOffset+=12; |
| 307 | + prodDescriptionOffset+=12; |
| 308 | + } |
| 309 | + Vector2 cityNameDestination = new Vector2(tileCenter + new Vector2(cityNameOffset, 24) + new Vector2(0, 10)); |
| 310 | + looseView.DrawString(smallFont, cityNameDestination, cityNameAndGrowth, Color.Color8(255, 255, 255, 255)); |
| 311 | + Vector2 productionDestination = new Vector2(tileCenter + new Vector2(prodDescriptionOffset, 24) + new Vector2(0, 20)); |
| 312 | + looseView.DrawString(smallFont, productionDestination, productionDescription, Color.Color8(255, 255, 255, 255)); |
| 313 | + |
| 314 | + //City pop size |
| 315 | + DynamicFont midSizedFont = new DynamicFont(); |
| 316 | + midSizedFont.FontData = ResourceLoader.Load("res://Fonts/NotoSans-Regular.ttf") as DynamicFontData; |
| 317 | + midSizedFont.Size = 18; |
| 318 | + string popSizeString = "24"; |
| 319 | + int popSizeWidth = (int)midSizedFont.GetStringSize(popSizeString).x; |
| 320 | + int popSizeOffset = LEFT_RIGHT_BOXES_WIDTH/2 - popSizeWidth/2; |
| 321 | + Vector2 popSizeDestination = new Vector2(tileCenter + new Vector2(cityLabelWidth/-2, 24) + new Vector2(popSizeOffset, 18)); |
| 322 | + looseView.DrawString(midSizedFont, popSizeDestination, popSizeString, Color.Color8(255, 255, 255, 255)); |
| 323 | + } |
| 324 | + } |
| 325 | +} |
| 326 | + |
194 | 327 | public class LooseView : Node2D { |
195 | 328 | public MapView mapView; |
196 | 329 | public List<LooseLayer> layers = new List<LooseLayer>(); |
@@ -268,6 +401,7 @@ public MapView(Game game, int mapWidth, int mapHeight, bool wrapHorizontally, bo |
268 | 401 | looseView.layers.Add(gridLayer); |
269 | 402 | looseView.layers.Add(new BuildingLayer()); |
270 | 403 | looseView.layers.Add(new UnitLayer()); |
| 404 | + looseView.layers.Add(new CityLayer()); |
271 | 405 |
|
272 | 406 | AddChild(looseView); |
273 | 407 |
|
|
0 commit comments