src/town_cmd.cpp
changeset 6534 cbfd00fc5d88
parent 6525 a21429c6f16f
child 6547 f5ae0269d236
equal deleted inserted replaced
6533:8be3ef428116 6534:cbfd00fc5d88
    52 }
    52 }
    53 
    53 
    54 /* Initialize the town-pool */
    54 /* Initialize the town-pool */
    55 DEFINE_OLD_POOL(Town, Town, TownPoolNewBlock, NULL)
    55 DEFINE_OLD_POOL(Town, Town, TownPoolNewBlock, NULL)
    56 
    56 
       
    57 /**
       
    58  * Removes a specific town as well as all industries
       
    59  * under its "juridiction"
       
    60  * @param t Town to remove
       
    61  */
    57 void DestroyTown(Town *t)
    62 void DestroyTown(Town *t)
    58 {
    63 {
    59 	Industry *i;
    64 	Industry *i;
    60 	TileIndex tile;
    65 	TileIndex tile;
    61 
    66 
   118 	variant -= y >> 6;
   123 	variant -= y >> 6;
   119 	variant &= 3;
   124 	variant &= 3;
   120 	return variant;
   125 	return variant;
   121 }
   126 }
   122 
   127 
       
   128 /**
       
   129  * House Tile drawing handler.
       
   130  * Part of the tile loop process
       
   131  * @param ti TileInfo of the tile to draw
       
   132  */
   123 static void DrawTile_Town(TileInfo *ti)
   133 static void DrawTile_Town(TileInfo *ti)
   124 {
   134 {
   125 	const DrawBuildingsTileStruct *dcts;
   135 	const DrawBuildingsTileStruct *dcts;
   126 	SpriteID image;
   136 	SpriteID image;
   127 	SpriteID pal;
   137 	SpriteID pal;
   185 static Slope GetSlopeTileh_Town(TileIndex tile, Slope tileh)
   195 static Slope GetSlopeTileh_Town(TileIndex tile, Slope tileh)
   186 {
   196 {
   187 	return SLOPE_FLAT;
   197 	return SLOPE_FLAT;
   188 }
   198 }
   189 
   199 
       
   200 /**
       
   201  * Animate a tile for a town
       
   202  * Only certain houses can be animated
       
   203  * The newhouses animation superseeds regular ones
       
   204  * @param tile TileIndex of the house to animate
       
   205  */
   190 static void AnimateTile_Town(TileIndex tile)
   206 static void AnimateTile_Town(TileIndex tile)
   191 {
   207 {
   192 	int pos, dest;
   208 	int pos, dest;
   193 
   209 
   194 	if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
   210 	if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
   231 	MarkTileDirtyByTile(tile);
   247 	MarkTileDirtyByTile(tile);
   232 }
   248 }
   233 
   249 
   234 static void UpdateTownRadius(Town *t);
   250 static void UpdateTownRadius(Town *t);
   235 
   251 
       
   252 /**
       
   253  * Determines if a town is close to a tile
       
   254  * @param tile TileIndex of the tile to query
       
   255  * @param dist maximum distance to be accepted
       
   256  * @returns true if the tile correspond to the distance criteria
       
   257  */
   236 static bool IsCloseToTown(TileIndex tile, uint dist)
   258 static bool IsCloseToTown(TileIndex tile, uint dist)
   237 {
   259 {
   238 	const Town* t;
   260 	const Town* t;
   239 
   261 
   240 	FOR_ALL_TOWNS(t) {
   262 	FOR_ALL_TOWNS(t) {
   241 		if (DistanceManhattan(tile, t->xy) < dist) return true;
   263 		if (DistanceManhattan(tile, t->xy) < dist) return true;
   242 	}
   264 	}
   243 	return false;
   265 	return false;
   244 }
   266 }
   245 
   267 
       
   268 /**
       
   269  * Marks the town sign as needing a repaint
       
   270  * @param t Town requesting repaint
       
   271  */
   246 static void MarkTownSignDirty(Town *t)
   272 static void MarkTownSignDirty(Town *t)
   247 {
   273 {
   248 	MarkAllViewportsDirty(
   274 	MarkAllViewportsDirty(
   249 		t->sign.left - 6,
   275 		t->sign.left - 6,
   250 		t->sign.top - 3,
   276 		t->sign.top - 3,
   251 		t->sign.left + t->sign.width_1 * 4 + 12,
   277 		t->sign.left + t->sign.width_1 * 4 + 12,
   252 		t->sign.top + 45
   278 		t->sign.top + 45
   253 	);
   279 	);
   254 }
   280 }
   255 
   281 
       
   282 /**
       
   283  * Resize the sign(label) of the town after changes in
       
   284  * population (creation or growth or else)
       
   285  * @param t Town to update
       
   286  */
   256 void UpdateTownVirtCoord(Town *t)
   287 void UpdateTownVirtCoord(Town *t)
   257 {
   288 {
   258 	Point pt;
   289 	Point pt;
   259 
   290 
   260 	MarkTownSignDirty(t);
   291 	MarkTownSignDirty(t);
   264 	UpdateViewportSignPos(&t->sign, pt.x, pt.y - 24,
   295 	UpdateViewportSignPos(&t->sign, pt.x, pt.y - 24,
   265 		_patches.population_in_label ? STR_TOWN_LABEL_POP : STR_TOWN_LABEL);
   296 		_patches.population_in_label ? STR_TOWN_LABEL_POP : STR_TOWN_LABEL);
   266 	MarkTownSignDirty(t);
   297 	MarkTownSignDirty(t);
   267 }
   298 }
   268 
   299 
       
   300 /**
       
   301  * Change the towns population
       
   302  * @param t Town which polulation has changed
       
   303  * @param mod polulation change (can be positive or negative)
       
   304  */
   269 static void ChangePopulation(Town *t, int mod)
   305 static void ChangePopulation(Town *t, int mod)
   270 {
   306 {
   271 	t->population += mod;
   307 	t->population += mod;
   272 	InvalidateWindow(WC_TOWN_VIEW, t->index);
   308 	InvalidateWindow(WC_TOWN_VIEW, t->index);
   273 	UpdateTownVirtCoord(t);
   309 	UpdateTownVirtCoord(t);
   274 
   310 
   275 	if (_town_sort_order & 2) _town_sort_dirty = true;
   311 	if (_town_sort_order & 2) _town_sort_dirty = true;
   276 }
   312 }
   277 
   313 
       
   314 /**
       
   315  * Determines the world population
       
   316  * Basically, count population of all towns, one by one
       
   317  * @return uint32 the calculated population of the world
       
   318  */
   278 uint32 GetWorldPopulation()
   319 uint32 GetWorldPopulation()
   279 {
   320 {
   280 	uint32 pop;
   321 	uint32 pop;
   281 	const Town* t;
   322 	const Town* t;
   282 
   323 
   283 	pop = 0;
   324 	pop = 0;
   284 	FOR_ALL_TOWNS(t) pop += t->population;
   325 	FOR_ALL_TOWNS(t) pop += t->population;
   285 	return pop;
   326 	return pop;
   286 }
   327 }
   287 
   328 
       
   329 /**
       
   330  * Helper function for house completion stages progression
       
   331  * @param tile TileIndex of the house (or parts of it) to "grow"
       
   332  */
   288 static void MakeSingleHouseBigger(TileIndex tile)
   333 static void MakeSingleHouseBigger(TileIndex tile)
   289 {
   334 {
   290 	assert(IsTileType(tile, MP_HOUSE));
   335 	assert(IsTileType(tile, MP_HOUSE));
   291 
   336 
       
   337 	/* means it is completed, get out. */
   292 	if (LiftHasDestination(tile)) return;
   338 	if (LiftHasDestination(tile)) return;
   293 
   339 
       
   340 	/* progress in construction stages */
   294 	IncHouseConstructionTick(tile);
   341 	IncHouseConstructionTick(tile);
   295 	if (GetHouseConstructionTick(tile) != 0) return;
   342 	if (GetHouseConstructionTick(tile) != 0) return;
   296 
   343 
       
   344 	/* Check and/or  */
   297 	if (HASBIT(GetHouseSpecs(GetHouseType(tile))->callback_mask, CBM_CONSTRUCTION_STATE_CHANGE)) {
   345 	if (HASBIT(GetHouseSpecs(GetHouseType(tile))->callback_mask, CBM_CONSTRUCTION_STATE_CHANGE)) {
   298 		uint16 callback_res = GetHouseCallback(CBID_CONSTRUCTION_STATE_CHANGE, 0, GetHouseType(tile), GetTownByTile(tile), tile);
   346 		uint16 callback_res = GetHouseCallback(CBID_CONSTRUCTION_STATE_CHANGE, 0, GetHouseType(tile), GetTownByTile(tile), tile);
   299 		if (callback_res != CALLBACK_FAILED) ChangeHouseAnimationFrame(tile, callback_res);
   347 		if (callback_res != CALLBACK_FAILED) ChangeHouseAnimationFrame(tile, callback_res);
   300 	}
   348 	}
   301 
   349 
   305 		ChangePopulation(GetTownByTile(tile), GetHouseSpecs(GetHouseType(tile))->population);
   353 		ChangePopulation(GetTownByTile(tile), GetHouseSpecs(GetHouseType(tile))->population);
   306 	}
   354 	}
   307 	MarkTileDirtyByTile(tile);
   355 	MarkTileDirtyByTile(tile);
   308 }
   356 }
   309 
   357 
       
   358 /** Make the house advances in its construction stages until completion
       
   359  * @param tile TileIndex of house
       
   360  */
   310 static void MakeTownHouseBigger(TileIndex tile)
   361 static void MakeTownHouseBigger(TileIndex tile)
   311 {
   362 {
   312 	uint flags = GetHouseSpecs(GetHouseType(tile))->building_flags;
   363 	uint flags = GetHouseSpecs(GetHouseType(tile))->building_flags;
   313 	if (flags & BUILDING_HAS_1_TILE)  MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 0));
   364 	if (flags & BUILDING_HAS_1_TILE)  MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 0));
   314 	if (flags & BUILDING_2_TILES_Y)   MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 1));
   365 	if (flags & BUILDING_2_TILES_Y)   MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 1));
   315 	if (flags & BUILDING_2_TILES_X)   MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 0));
   366 	if (flags & BUILDING_2_TILES_X)   MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 0));
   316 	if (flags & BUILDING_HAS_4_TILES) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 1));
   367 	if (flags & BUILDING_HAS_4_TILES) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 1));
   317 }
   368 }
   318 
   369 
       
   370 /**
       
   371  * Periodic tic handler for houses and town
       
   372  * @param tile been asked to do its stuff
       
   373  */
   319 static void TileLoop_Town(TileIndex tile)
   374 static void TileLoop_Town(TileIndex tile)
   320 {
   375 {
   321 	Town *t;
   376 	Town *t;
   322 	uint32 r;
   377 	uint32 r;
   323 	HouseID house_id = GetHouseType(tile);
   378 	HouseID house_id = GetHouseType(tile);
   332 		MakeTownHouseBigger(tile);
   387 		MakeTownHouseBigger(tile);
   333 		return;
   388 		return;
   334 	}
   389 	}
   335 
   390 
   336 	/* If the lift has a destination, it is already an animated tile. */
   391 	/* If the lift has a destination, it is already an animated tile. */
   337 	if ((hs->building_flags & BUILDING_IS_ANIMATED) && house_id < NEW_HOUSE_OFFSET && !LiftHasDestination(tile) && CHANCE16(1, 2)) AddAnimatedTile(tile);
   392 	if ((hs->building_flags & BUILDING_IS_ANIMATED) &&
       
   393 			house_id < NEW_HOUSE_OFFSET &&
       
   394 			!LiftHasDestination(tile) &&
       
   395 			CHANCE16(1, 2))
       
   396 		AddAnimatedTile(tile);
   338 
   397 
   339 	t = GetTownByTile(tile);
   398 	t = GetTownByTile(tile);
   340 
   399 
   341 	r = Random();
   400 	r = Random();
   342 
   401 
   360 		t->new_act_mail += moved;
   419 		t->new_act_mail += moved;
   361 	}
   420 	}
   362 
   421 
   363 	_current_player = OWNER_TOWN;
   422 	_current_player = OWNER_TOWN;
   364 
   423 
   365 	if (hs->building_flags & BUILDING_HAS_1_TILE && HASBIT(t->flags12, TOWN_IS_FUNDED) && CanDeleteHouse(tile) && --t->time_until_rebuild == 0) {
   424 	if (hs->building_flags & BUILDING_HAS_1_TILE &&
       
   425 			HASBIT(t->flags12, TOWN_IS_FUNDED) &&
       
   426 			CanDeleteHouse(tile) &&
       
   427 			--t->time_until_rebuild == 0) {
   366 		t->time_until_rebuild = GB(r, 16, 8) + 192;
   428 		t->time_until_rebuild = GB(r, 16, 8) + 192;
   367 
   429 
   368 		ClearTownHouse(t, tile);
   430 		ClearTownHouse(t, tile);
   369 
   431 
   370 		/* Rebuild with another house? */
   432 		/* Rebuild with another house? */
   372 	}
   434 	}
   373 
   435 
   374 	_current_player = OWNER_NONE;
   436 	_current_player = OWNER_NONE;
   375 }
   437 }
   376 
   438 
       
   439 /**
       
   440  * Unused handler
       
   441  * @param tile unused
       
   442  */
   377 static void ClickTile_Town(TileIndex tile)
   443 static void ClickTile_Town(TileIndex tile)
   378 {
   444 {
   379 	/* not used */
   445 	/* not used */
   380 }
   446 }
   381 
   447