118 /* Else draw regular ground */ |
118 /* Else draw regular ground */ |
119 DrawGroundSprite(dcts->sprite_1); |
119 DrawGroundSprite(dcts->sprite_1); |
120 } |
120 } |
121 |
121 |
122 /* Add a house on top of the ground? */ |
122 /* Add a house on top of the ground? */ |
123 if ((image = dcts->sprite_2) != 0) { |
123 image = dcts->sprite_2; |
124 if (_display_opt & DO_TRANS_BUILDINGS) |
124 if (image != 0) { |
125 MAKE_TRANSPARENT(image); |
125 if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image); |
126 |
126 |
127 AddSortableSpriteToDraw(image, |
127 AddSortableSpriteToDraw(image, |
128 ti->x + dcts->subtile_x, |
128 ti->x + dcts->subtile_x, |
129 ti->y + dcts->subtile_y, |
129 ti->y + dcts->subtile_y, |
130 dcts->width + 1, |
130 dcts->width + 1, |
131 dcts->height + 1, |
131 dcts->height + 1, |
132 dcts->dz, |
132 dcts->dz, |
133 z); |
133 z); |
134 |
134 |
135 if (_display_opt & DO_TRANS_BUILDINGS) |
135 if (_display_opt & DO_TRANS_BUILDINGS) return; |
136 return; |
|
137 } |
136 } |
138 |
137 |
139 { |
138 { |
140 int proc; |
139 int proc = dcts->proc - 1; |
141 if ((proc=dcts->proc-1) >= 0 ) |
140 |
142 _town_draw_tile_procs[proc](ti); |
141 if (proc >= 0) _town_draw_tile_procs[proc](ti); |
143 } |
142 } |
144 } |
143 } |
145 |
144 |
146 static uint GetSlopeZ_Town(const TileInfo* ti) |
145 static uint GetSlopeZ_Town(const TileInfo* ti) |
147 { |
146 { |
156 } |
155 } |
157 |
156 |
158 static void AnimateTile_Town(TileIndex tile) |
157 static void AnimateTile_Town(TileIndex tile) |
159 { |
158 { |
160 int old; |
159 int old; |
161 int i; |
|
162 int a,b; |
160 int a,b; |
163 |
161 |
164 if (_tick_counter & 3) |
162 if (_tick_counter & 3) return; |
165 return; |
|
166 |
163 |
167 // If the house is not one with a lift anymore, then stop this animating. |
164 // If the house is not one with a lift anymore, then stop this animating. |
168 // Not exactly sure when this happens, but probably when a house changes. |
165 // Not exactly sure when this happens, but probably when a house changes. |
169 // Before this was just a return...so it'd leak animated tiles.. |
166 // Before this was just a return...so it'd leak animated tiles.. |
170 // That bug seems to have been here since day 1?? |
167 // That bug seems to have been here since day 1?? |
172 DeleteAnimatedTile(tile); |
169 DeleteAnimatedTile(tile); |
173 return; |
170 return; |
174 } |
171 } |
175 |
172 |
176 if (!((old = _m[tile].m1) & 0x80)) { |
173 if (!((old = _m[tile].m1) & 0x80)) { |
|
174 int i; |
|
175 |
177 _m[tile].m1 |= 0x80; |
176 _m[tile].m1 |= 0x80; |
178 |
177 |
179 do { |
178 do { |
180 i = (Random()&7) - 1; |
179 i = (Random() & 7) - 1; |
181 } while (i < 0 || i == 1 || i*6==old); |
180 } while (i < 0 || i == 1 || i * 6 == old); |
182 |
181 |
183 SB(_m[tile].m5, 0, 6, i); |
182 SB(_m[tile].m5, 0, 6, i); |
184 } |
183 } |
185 |
184 |
186 a = GB(_m[tile].m1, 0, 7); |
185 a = GB(_m[tile].m1, 0, 7); |
263 AB(_m[tile].m5, 0, 3, 1); |
259 AB(_m[tile].m5, 0, 3, 1); |
264 if (GB(_m[tile].m5, 0, 3) != 0) return; |
260 if (GB(_m[tile].m5, 0, 3) != 0) return; |
265 |
261 |
266 _m[tile].m3 = _m[tile].m3 + 0x40; |
262 _m[tile].m3 = _m[tile].m3 + 0x40; |
267 |
263 |
268 if ( (_m[tile].m3 & 0xC0) == 0xC0) { |
264 if ((_m[tile].m3 & 0xC0) == 0xC0) { |
269 ChangePopulation(GetTown(_m[tile].m2), _housetype_population[_m[tile].m4]); |
265 ChangePopulation(GetTown(_m[tile].m2), _housetype_population[_m[tile].m4]); |
270 } |
266 } |
271 MarkTileDirtyByTile(tile); |
267 MarkTileDirtyByTile(tile); |
272 } |
268 } |
273 |
269 |
321 t->new_max_mail += amt; |
317 t->new_max_mail += amt; |
322 moved = MoveGoodsToStation(tile, 1, 1, CT_MAIL, amt); |
318 moved = MoveGoodsToStation(tile, 1, 1, CT_MAIL, amt); |
323 t->new_act_mail += moved; |
319 t->new_act_mail += moved; |
324 } |
320 } |
325 |
321 |
326 if (_house_more_flags[house]&8 && (t->flags12&1) && --t->time_until_rebuild == 0) { |
322 if (_house_more_flags[house] & 8 && (t->flags12 & 1) && --t->time_until_rebuild == 0) { |
327 t->time_until_rebuild = GB(r, 16, 6) + 130; |
323 t->time_until_rebuild = GB(r, 16, 6) + 130; |
328 |
324 |
329 _current_player = OWNER_TOWN; |
325 _current_player = OWNER_TOWN; |
330 |
326 |
331 ClearTownHouse(t, tile); |
327 ClearTownHouse(t, tile); |
374 return cost; |
370 return cost; |
375 } |
371 } |
376 |
372 |
377 static void GetAcceptedCargo_Town(TileIndex tile, AcceptedCargo ac) |
373 static void GetAcceptedCargo_Town(TileIndex tile, AcceptedCargo ac) |
378 { |
374 { |
379 int type = _m[tile].m4; |
375 byte type = _m[tile].m4; |
380 |
376 |
381 ac[CT_PASSENGERS] = _housetype_cargo_passengers[type]; |
377 ac[CT_PASSENGERS] = _housetype_cargo_passengers[type]; |
382 ac[CT_MAIL] = _housetype_cargo_mail[type]; |
378 ac[CT_MAIL] = _housetype_cargo_mail[type]; |
383 ac[CT_GOODS] = _housetype_cargo_goods[type]; |
379 ac[CT_GOODS] = _housetype_cargo_goods[type]; |
384 ac[CT_FOOD] = _housetype_cargo_food[type]; |
380 ac[CT_FOOD] = _housetype_cargo_food[type]; |
385 } |
381 } |
386 |
382 |
387 static void GetTileDesc_Town(TileIndex tile, TileDesc *td) |
383 static void GetTileDesc_Town(TileIndex tile, TileDesc *td) |
388 { |
384 { |
389 td->str = _town_tile_names[_m[tile].m4]; |
385 td->str = _town_tile_names[_m[tile].m4]; |
453 if (++_cur_town_ctr >= GetTownPoolSize()) |
448 if (++_cur_town_ctr >= GetTownPoolSize()) |
454 _cur_town_ctr = 0; |
449 _cur_town_ctr = 0; |
455 |
450 |
456 t = GetTown(i); |
451 t = GetTown(i); |
457 |
452 |
458 if (t->xy != 0) |
453 if (t->xy != 0) TownTickHandler(t); |
459 TownTickHandler(t); |
|
460 } |
454 } |
461 } |
455 } |
462 |
456 |
463 static byte GetTownRoadMask(TileIndex tile) |
457 static byte GetTownRoadMask(TileIndex tile) |
464 { |
458 { |
465 byte b = GetRoadBitsByTile(tile); |
459 byte b = GetRoadBitsByTile(tile); |
466 byte r=0; |
460 byte r = 0; |
467 if (b&1) r|=10; |
461 |
468 if (b&2) r|=5; |
462 if (b & 0x01) r |= 10; |
469 if (b&4) r|=9; |
463 if (b & 0x02) r |= 5; |
470 if (b&8) r|=6; |
464 if (b & 0x04) r |= 9; |
471 if (b&16) r|=3; |
465 if (b & 0x08) r |= 6; |
472 if (b&32) r|=12; |
466 if (b & 0x10) r |= 3; |
|
467 if (b & 0x20) r |= 12; |
473 return r; |
468 return r; |
474 } |
469 } |
475 |
470 |
476 static bool IsRoadAllowedHere(TileIndex tile, int dir) |
471 static bool IsRoadAllowedHere(TileIndex tile, int dir) |
477 { |
472 { |
480 |
475 |
481 // If this assertion fails, it might be because the world contains |
476 // If this assertion fails, it might be because the world contains |
482 // land at the edges. This is not ok. |
477 // land at the edges. This is not ok. |
483 TILE_ASSERT(tile); |
478 TILE_ASSERT(tile); |
484 |
479 |
485 for(;;) { |
480 for (;;) { |
486 // Check if there already is a road at this point? |
481 // Check if there already is a road at this point? |
487 if (GetRoadBitsByTile(tile) == 0) { |
482 if (GetRoadBitsByTile(tile) == 0) { |
488 // No, try to build one in the direction. |
483 // No, try to build one in the direction. |
489 // if that fails clear the land, and if that fails exit. |
484 // if that fails clear the land, and if that fails exit. |
490 // This is to make sure that we can build a road here later. |
485 // This is to make sure that we can build a road here later. |
511 // If the tile is not a slope in the right direction, then |
506 // If the tile is not a slope in the right direction, then |
512 // maybe terraform some. |
507 // maybe terraform some. |
513 if ((k = (dir&1)?0xC:0x9) != slope && (k^0xF) != slope) { |
508 if ((k = (dir&1)?0xC:0x9) != slope && (k^0xF) != slope) { |
514 uint32 r = Random(); |
509 uint32 r = Random(); |
515 |
510 |
516 if (CHANCE16I(1,8, r) && !_generating_world) { |
511 if (CHANCE16I(1, 8, r) && !_generating_world) { |
517 int32 res; |
512 int32 res; |
518 |
513 |
519 if (CHANCE16I(1,16,r)) |
514 if (CHANCE16I(1, 16, r)) { |
520 res = DoCommandByTile(tile, slope, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, |
515 res = DoCommandByTile(tile, slope, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, |
521 CMD_TERRAFORM_LAND); |
516 CMD_TERRAFORM_LAND); |
522 else |
517 } else { |
523 res = DoCommandByTile(tile, slope^0xF, 1, DC_EXEC | DC_AUTO | DC_NO_WATER, |
518 res = DoCommandByTile(tile, slope^0xF, 1, DC_EXEC | DC_AUTO | DC_NO_WATER, |
524 CMD_TERRAFORM_LAND); |
519 CMD_TERRAFORM_LAND); |
|
520 } |
525 if (res == CMD_ERROR && CHANCE16I(1,3,r)) |
521 if (res == CMD_ERROR && CHANCE16I(1,3,r)) |
526 // We can consider building on the slope, though. |
522 // We can consider building on the slope, though. |
527 goto no_slope; |
523 goto no_slope; |
528 } |
524 } |
529 return false; |
525 return false; |
530 } |
526 } |
531 |
|
532 /* Can somebody explain for what this is needed? :s */ |
|
533 // tile = TILE_ADD(tile, _roadblock_tileadd[dir]); |
|
534 return true; |
527 return true; |
535 } |
528 } |
536 } |
529 } |
537 |
530 |
538 static bool TerraformTownTile(TileIndex tile, int edges, int dir) |
531 static bool TerraformTownTile(TileIndex tile, int edges, int dir) |
554 |
547 |
555 TILE_ASSERT(tile); |
548 TILE_ASSERT(tile); |
556 |
549 |
557 // Don't terraform if land is plain or if there's a house there. |
550 // Don't terraform if land is plain or if there's a house there. |
558 FindLandscapeHeightByTile(&ti, tile); |
551 FindLandscapeHeightByTile(&ti, tile); |
559 if (ti.tileh == 0 || ti.type == MP_HOUSE) |
552 if (ti.tileh == 0 || ti.type == MP_HOUSE) return; |
560 return; |
|
561 |
553 |
562 // First try up, then down |
554 // First try up, then down |
563 if (!TerraformTownTile(tile, ~ti.tileh & 0xF, 1)) { |
555 if (!TerraformTownTile(tile, ~ti.tileh & 0xF, 1)) { |
564 TerraformTownTile(tile, ti.tileh & 0xF, 0); |
556 TerraformTownTile(tile, ti.tileh & 0xF, 0); |
565 } |
557 } |
600 } |
591 } |
601 |
592 |
602 if (!IsRoadAllowedHere(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a])), a)) { |
593 if (!IsRoadAllowedHere(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a])), a)) { |
603 // A road is not allowed to continue the randomized road, |
594 // A road is not allowed to continue the randomized road, |
604 // return if the road we're trying to build is curved. |
595 // return if the road we're trying to build is curved. |
605 if ( a != (b^2)) |
596 if (a != (b ^ 2)) return; |
606 return; |
|
607 |
597 |
608 // Return if neither side of the new road is a house |
598 // Return if neither side of the new road is a house |
609 if (!IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 1])), MP_HOUSE) && |
599 if (!IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 1])), MP_HOUSE) && |
610 !IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 3])), MP_HOUSE)) |
600 !IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 3])), MP_HOUSE)) |
611 return; |
601 return; |
617 |
607 |
618 } else if (block < 5 && !HASBIT(mask,block^2)) { |
608 } else if (block < 5 && !HASBIT(mask,block^2)) { |
619 // Continue building on a partial road. |
609 // Continue building on a partial road. |
620 // Always OK. |
610 // Always OK. |
621 _grow_town_result = 0; |
611 _grow_town_result = 0; |
622 rcmd = 1 << (block^2); |
612 rcmd = 1 << (block ^ 2); |
623 } else { |
613 } else { |
624 |
614 |
625 // Reached a tunnel? Then continue at the other side of it. |
615 // Reached a tunnel? Then continue at the other side of it. |
626 if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5& ~3) == 4) { |
616 if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5& ~3) == 4) { |
627 FindLengthOfTunnelResult flotr = FindLengthOfTunnel(tile, GB(_m[tile].m5, 0, 2)); |
617 FindLengthOfTunnelResult flotr = FindLengthOfTunnel(tile, GB(_m[tile].m5, 0, 2)); |
628 *tile_ptr = flotr.tile; |
618 *tile_ptr = flotr.tile; |
629 return; |
619 return; |
630 } |
620 } |
631 |
621 |
632 // For any other kind of tunnel/bridge, bail out. |
622 // For any other kind of tunnel/bridge, bail out. |
633 if (IsTileType(tile, MP_TUNNELBRIDGE)) |
623 if (IsTileType(tile, MP_TUNNELBRIDGE)) return; |
634 return; |
|
635 |
624 |
636 // Possibly extend the road in a direction. |
625 // Possibly extend the road in a direction. |
637 // Randomize a direction and if it has a road, bail out. |
626 // Randomize a direction and if it has a road, bail out. |
638 i = GB(Random(), 0, 2); |
627 i = GB(Random(), 0, 2); |
639 if (HASBIT(mask, i)) |
628 if (HASBIT(mask, i)) return; |
640 return; |
|
641 |
629 |
642 // This is the tile we will reach if we extend to this direction. |
630 // This is the tile we will reach if we extend to this direction. |
643 tmptile = TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[i])); |
631 tmptile = TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[i])); |
644 |
632 |
645 // Don't do it if it reaches to water. |
633 // Don't do it if it reaches to water. |
646 if (IS_WATER_TILE(tmptile)) |
634 if (IS_WATER_TILE(tmptile)) return; |
647 return; |
|
648 |
635 |
649 // Build a house at the edge. 60% chance or |
636 // Build a house at the edge. 60% chance or |
650 // always ok if no road allowed. |
637 // always ok if no road allowed. |
651 if (!IsRoadAllowedHere(tmptile, i) || CHANCE16(6,10)) { |
638 if (!IsRoadAllowedHere(tmptile, i) || CHANCE16(6, 10)) { |
652 // But not if there already is a house there. |
639 // But not if there already is a house there. |
653 if (!IsTileType(tmptile, MP_HOUSE)) { |
640 if (!IsTileType(tmptile, MP_HOUSE)) { |
654 // Level the land if possible |
641 // Level the land if possible |
655 LevelTownLand(tmptile); |
642 LevelTownLand(tmptile); |
656 |
643 |
657 // And build a house. |
644 // And build a house. |
658 // Set result to -1 if we managed to build it. |
645 // Set result to -1 if we managed to build it. |
659 if (BuildTownHouse(t1, tmptile)) |
646 if (BuildTownHouse(t1, tmptile)) _grow_town_result = -1; |
660 _grow_town_result = -1; |
|
661 } |
647 } |
662 return; |
648 return; |
663 } |
649 } |
664 |
650 |
665 _grow_town_result = 0; |
651 _grow_town_result = 0; |
667 } |
653 } |
668 |
654 |
669 FindLandscapeHeightByTile(&ti, tile); |
655 FindLandscapeHeightByTile(&ti, tile); |
670 |
656 |
671 // Return if a water tile |
657 // Return if a water tile |
672 if (ti.type == MP_WATER && ti.map5==0) |
658 if (ti.type == MP_WATER && ti.map5 == 0) return; |
673 return; |
|
674 |
659 |
675 // Determine direction of slope, |
660 // Determine direction of slope, |
676 // and build a road if not a special slope. |
661 // and build a road if not a special slope. |
677 if ((i=0,ti.tileh != 3) && |
662 if ((i=0,ti.tileh != 3) && |
678 (i++,ti.tileh != 9) && |
663 (i++,ti.tileh != 9) && |
821 tile = t->xy; |
806 tile = t->xy; |
822 for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { |
807 for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { |
823 FindLandscapeHeightByTile(&ti, tile); |
808 FindLandscapeHeightByTile(&ti, tile); |
824 |
809 |
825 // Only work with plain land that not already has a house with map5=0 |
810 // Only work with plain land that not already has a house with map5=0 |
826 if (ti.tileh == 0 && !(ti.type==MP_HOUSE && ti.map5==0)) { |
811 if (ti.tileh == 0 && (ti.type != MP_HOUSE || ti.map5 != 0)) { |
827 if (DoCommandByTile(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR) != CMD_ERROR) { |
812 if (DoCommandByTile(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR) != CMD_ERROR) { |
828 DoCommandByTile(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD); |
813 DoCommandByTile(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD); |
829 _current_player = old_player; |
814 _current_player = old_player; |
830 return true; |
815 return true; |
831 } |
816 } |
904 |
889 |
905 SetDParam(0, r); |
890 SetDParam(0, r); |
906 GetString(buf1, townnametype); |
891 GetString(buf1, townnametype); |
907 |
892 |
908 // Check size and width |
893 // Check size and width |
909 if (strlen(buf1) >= 31 || GetStringWidth(buf1) > 130) |
894 if (strlen(buf1) >= 31 || GetStringWidth(buf1) > 130) continue; |
910 continue; |
|
911 |
895 |
912 FOR_ALL_TOWNS(t2) { |
896 FOR_ALL_TOWNS(t2) { |
913 if (t2->xy != 0) { |
897 if (t2->xy != 0) { |
914 // We can't just compare the numbers since |
898 // We can't just compare the numbers since |
915 // several numbers may map to a single name. |
899 // several numbers may map to a single name. |
916 SetDParam(0, t2->index); |
900 SetDParam(0, t2->index); |
917 GetString(buf2, STR_TOWN); |
901 GetString(buf2, STR_TOWN); |
918 if (strcmp(buf1, buf2) == 0) { |
902 if (strcmp(buf1, buf2) == 0) { |
919 if (tries-- < 0) |
903 if (tries-- < 0) return false; |
920 return false; |
|
921 goto restart; |
904 goto restart; |
922 } |
905 } |
923 } |
906 } |
924 } |
907 } |
925 *townnameparts = r; |
908 *townnameparts = r; |
1871 void ChangeTownRating(Town *t, int add, int max) |
1852 void ChangeTownRating(Town *t, int add, int max) |
1872 { |
1853 { |
1873 int rating; |
1854 int rating; |
1874 |
1855 |
1875 // if magic_bulldozer cheat is active, town doesn't penaltize for removing stuff |
1856 // if magic_bulldozer cheat is active, town doesn't penaltize for removing stuff |
1876 if (t == NULL || _current_player >= MAX_PLAYERS || (_cheats.magic_bulldozer.value && add < 0) ) |
1857 if (t == NULL || |
|
1858 _current_player >= MAX_PLAYERS || |
|
1859 (_cheats.magic_bulldozer.value && add < 0)) { |
1877 return; |
1860 return; |
|
1861 } |
1878 |
1862 |
1879 SETBIT(t->have_ratings, _current_player); |
1863 SETBIT(t->have_ratings, _current_player); |
1880 |
1864 |
1881 rating = t->ratings[_current_player]; |
1865 rating = t->ratings[_current_player]; |
1882 |
1866 |