53 |
75 |
54 /** |
76 /** |
55 * Retrieve the type for this industry. Although it is accessed by a tile, |
77 * Retrieve the type for this industry. Although it is accessed by a tile, |
56 * it will return the general type of industry, and not the sprite index |
78 * it will return the general type of industry, and not the sprite index |
57 * as would do GetIndustryGfx. |
79 * as would do GetIndustryGfx. |
58 * The same information can be accessed by looking at Industry->type |
|
59 * @param tile that is queried |
80 * @param tile that is queried |
60 * @pre IsTileType(tile, MP_INDUSTRY) |
81 * @pre IsTileType(tile, MP_INDUSTRY) |
61 * @return general type for this industry, as defined in industry.h |
82 * @return general type for this industry, as defined in industry.h |
62 **/ |
83 **/ |
63 IndustryType GetIndustryType(TileIndex tile) |
84 IndustryType GetIndustryType(TileIndex tile) |
64 { |
85 { |
65 IndustryGfx this_type = GetIndustryGfx(tile); |
|
66 IndustryType iloop; |
|
67 |
|
68 assert(IsTileType(tile, MP_INDUSTRY)); |
86 assert(IsTileType(tile, MP_INDUSTRY)); |
69 |
87 |
70 for (iloop = IT_COAL_MINE; iloop < IT_END; iloop += 1) { |
88 const Industry *ind = GetIndustryByTile(tile); |
71 if (IS_BYTE_INSIDE(this_type, industry_gfx_Solver[iloop].MinGfx, |
89 return IsValidIndustry(ind) ? ind->type : (IndustryType)IT_INVALID; |
72 industry_gfx_Solver[iloop].MaxGfx+1)) { |
|
73 return iloop; |
|
74 } |
|
75 } |
|
76 |
|
77 return IT_INVALID; //we have not found equivalent, whatever the reason |
|
78 } |
90 } |
79 |
91 |
80 /** |
92 /** |
81 * Accessor for array _industry_specs. |
93 * Accessor for array _industry_specs. |
82 * This will ensure at once : proper access and |
94 * This will ensure at once : proper access and |
83 * not allowing modifications of it. |
95 * not allowing modifications of it. |
84 * @param thistype of industry (which is the index in _industry_specs) |
96 * @param thistype of industry (which is the index in _industry_specs) |
85 * @pre thistype < IT_END |
97 * @pre thistype < NUM_INDUSTRYTYPES |
86 * @return a pointer to the corresponding industry spec |
98 * @return a pointer to the corresponding industry spec |
87 **/ |
99 **/ |
88 const IndustrySpec *GetIndustrySpec(IndustryType thistype) |
100 const IndustrySpec *GetIndustrySpec(IndustryType thistype) |
89 { |
101 { |
90 assert(thistype < IT_END); |
102 assert(thistype < NUM_INDUSTRYTYPES); |
91 return &_industry_specs[thistype]; |
103 return &_industry_specs[thistype]; |
92 } |
104 } |
93 |
105 |
94 /** |
106 /** |
95 * Accessor for array _industry_tile_specs. |
107 * Accessor for array _industry_tile_specs. |
96 * This will ensure at once : proper access and |
108 * This will ensure at once : proper access and |
97 * not allowing modifications of it. |
109 * not allowing modifications of it. |
98 * @param gfx of industrytile (which is the index in _industry_specs) |
110 * @param gfx of industrytile (which is the index in _industry_specs) |
99 * @pre gfx < NUM_INDUSTRY_GFXES |
111 * @pre gfx < INVALID_INDUSTRYTILE |
100 * @return a pointer to the corresponding industrytile spec |
112 * @return a pointer to the corresponding industrytile spec |
101 **/ |
113 **/ |
102 const IndustryTileSpec *GetIndustryTileSpec(IndustryGfx gfx) |
114 const IndustryTileSpec *GetIndustryTileSpec(IndustryGfx gfx) |
103 { |
115 { |
104 assert(gfx < NUM_INDUSTRY_GFXES); |
116 assert(gfx < INVALID_INDUSTRYTILE); |
105 return &_industry_tile_specs[gfx]; |
117 return &_industry_tile_specs[gfx]; |
106 } |
118 } |
107 |
119 |
108 void DestroyIndustry(Industry *i) |
120 void DestroyIndustry(Industry *i) |
109 { |
121 { |
135 InvalidateWindow(WC_INDUSTRY_DIRECTORY, 0); |
147 InvalidateWindow(WC_INDUSTRY_DIRECTORY, 0); |
136 } |
148 } |
137 |
149 |
138 static void IndustryDrawSugarMine(const TileInfo *ti) |
150 static void IndustryDrawSugarMine(const TileInfo *ti) |
139 { |
151 { |
140 const DrawIndustrySpec1Struct *d; |
152 const DrawIndustryAnimationStruct *d; |
141 uint32 image; |
|
142 |
153 |
143 if (!IsIndustryCompleted(ti->tile)) return; |
154 if (!IsIndustryCompleted(ti->tile)) return; |
144 |
155 |
145 d = &_draw_industry_spec1[GetIndustryAnimationState(ti->tile)]; |
156 d = &_draw_industry_spec1[GetIndustryAnimationState(ti->tile)]; |
146 |
157 |
147 AddChildSpriteScreen(SPR_IT_SUGAR_MINE_SIEVE + d->image_1, PAL_NONE, d->x, 0); |
158 AddChildSpriteScreen(SPR_IT_SUGAR_MINE_SIEVE + d->image_1, PAL_NONE, d->x, 0); |
148 |
159 |
149 image = d->image_2; |
160 if (d->image_2 != 0) { |
150 if (image != 0) AddChildSpriteScreen(SPR_IT_SUGAR_MINE_CLOUDS + image - 1, PAL_NONE, 8, 41); |
161 AddChildSpriteScreen(SPR_IT_SUGAR_MINE_CLOUDS + d->image_2 - 1, PAL_NONE, 8, 41); |
151 |
162 } |
152 image = d->image_3; |
163 |
153 if (image != 0) { |
164 if (d->image_3 != 0) { |
154 AddChildSpriteScreen(SPR_IT_SUGAR_MINE_PILE + image - 1, PAL_NONE, |
165 AddChildSpriteScreen(SPR_IT_SUGAR_MINE_PILE + d->image_3 - 1, PAL_NONE, |
155 _drawtile_proc1_x[image - 1], _drawtile_proc1_y[image - 1]); |
166 _drawtile_proc1[d->image_3 - 1].x, _drawtile_proc1[d->image_3 - 1].y); |
156 } |
167 } |
157 } |
168 } |
158 |
169 |
159 static void IndustryDrawToffeeQuarry(const TileInfo *ti) |
170 static void IndustryDrawToffeeQuarry(const TileInfo *ti) |
160 { |
171 { |
161 int x = 0; |
172 uint8 x = 0; |
162 |
173 |
163 if (IsIndustryCompleted(ti->tile)) { |
174 if (IsIndustryCompleted(ti->tile)) { |
164 x = _industry_anim_offs[GetIndustryAnimationState(ti->tile)]; |
175 x = _industry_anim_offs_toffee[GetIndustryAnimationState(ti->tile)]; |
165 if ( (byte)x == 0xFF) |
176 if (x == 0xFF) |
166 x = 0; |
177 x = 0; |
167 } |
178 } |
168 |
179 |
169 AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_SHOVEL, PAL_NONE, 22 - x, 24 + x); |
180 AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_SHOVEL, PAL_NONE, 22 - x, 24 + x); |
170 AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_TOFFEE, PAL_NONE, 6, 14); |
181 AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_TOFFEE, PAL_NONE, 6, 14); |
171 } |
182 } |
172 |
183 |
173 static void IndustryDrawBubbleGenerator( const TileInfo *ti) |
184 static void IndustryDrawBubbleGenerator( const TileInfo *ti) |
174 { |
185 { |
175 if (IsIndustryCompleted(ti->tile)) { |
186 if (IsIndustryCompleted(ti->tile)) { |
176 AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_BUBBLE, PAL_NONE, 5, _industry_anim_offs_2[GetIndustryAnimationState(ti->tile)]); |
187 AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_BUBBLE, PAL_NONE, 5, _industry_anim_offs_bubbles[GetIndustryAnimationState(ti->tile)]); |
177 } else { |
188 } else { |
178 AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_SPRING, PAL_NONE, 3, 67); |
189 AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_SPRING, PAL_NONE, 3, 67); |
179 } |
190 } |
180 } |
191 } |
181 |
192 |
182 static void IndustryDrawToyFactory(const TileInfo *ti) |
193 static void IndustryDrawToyFactory(const TileInfo *ti) |
183 { |
194 { |
184 const DrawIndustrySpec4Struct *d; |
195 const DrawIndustryAnimationStruct *d; |
185 |
196 |
186 d = &_industry_anim_offs_3[GetIndustryAnimationState(ti->tile)]; |
197 d = &_industry_anim_offs_toys[GetIndustryAnimationState(ti->tile)]; |
187 |
198 |
188 if (d->image_1 != 0xFF) { |
199 if (d->image_1 != 0xFF) { |
189 AddChildSpriteScreen(SPR_IT_TOY_FACTORY_CLAY, PAL_NONE, 50 - d->image_1 * 2, 96 + d->image_1); |
200 AddChildSpriteScreen(SPR_IT_TOY_FACTORY_CLAY, PAL_NONE, d->x, 96 + d->image_1); |
190 } |
201 } |
191 |
202 |
192 if (d->image_2 != 0xFF) { |
203 if (d->image_2 != 0xFF) { |
193 AddChildSpriteScreen(SPR_IT_TOY_FACTORY_ROBOT, PAL_NONE, 16 - d->image_2 * 2, 100 + d->image_2); |
204 AddChildSpriteScreen(SPR_IT_TOY_FACTORY_ROBOT, PAL_NONE, 16 - d->image_2 * 2, 100 + d->image_2); |
194 } |
205 } |
914 |
921 |
915 if (CircularTileSearch(tile, 40, SearchLumberMillTrees, 0)) ///< 40x40 tiles to search |
922 if (CircularTileSearch(tile, 40, SearchLumberMillTrees, 0)) ///< 40x40 tiles to search |
916 i->cargo_waiting[0] = min(0xffff, i->cargo_waiting[0] + 45); ///< Found a tree, add according value to waiting cargo |
923 i->cargo_waiting[0] = min(0xffff, i->cargo_waiting[0] + 45); ///< Found a tree, add according value to waiting cargo |
917 } |
924 } |
918 |
925 |
919 static const byte _industry_sounds[37][2] = { |
|
920 {0}, |
|
921 {0}, |
|
922 {1, SND_28_SAWMILL}, |
|
923 {0}, |
|
924 {0}, |
|
925 {0}, |
|
926 {1, SND_03_FACTORY_WHISTLE}, |
|
927 {1, SND_03_FACTORY_WHISTLE}, |
|
928 {0}, |
|
929 {3, SND_24_SHEEP}, |
|
930 {0}, |
|
931 {0}, |
|
932 {0}, |
|
933 {0}, |
|
934 {1, SND_28_SAWMILL}, |
|
935 {0}, |
|
936 {0}, |
|
937 {0}, |
|
938 {0}, |
|
939 {0}, |
|
940 {0}, |
|
941 {0}, |
|
942 {0}, |
|
943 {1, SND_03_FACTORY_WHISTLE}, |
|
944 {0}, |
|
945 {0}, |
|
946 {0}, |
|
947 {0}, |
|
948 {0}, |
|
949 {0}, |
|
950 {0}, |
|
951 {0}, |
|
952 {1, SND_33_PLASTIC_MINE}, |
|
953 {0}, |
|
954 {0}, |
|
955 {0}, |
|
956 {0}, |
|
957 }; |
|
958 |
|
959 |
|
960 static void ProduceIndustryGoods(Industry *i) |
926 static void ProduceIndustryGoods(Industry *i) |
961 { |
927 { |
962 uint32 r; |
928 uint32 r; |
963 uint num; |
929 uint num; |
|
930 const IndustrySpec *indsp = GetIndustrySpec(i->type); |
964 |
931 |
965 /* play a sound? */ |
932 /* play a sound? */ |
966 if ((i->counter & 0x3F) == 0) { |
933 if ((i->counter & 0x3F) == 0) { |
967 if (CHANCE16R(1,14,r) && (num=_industry_sounds[i->type][0]) != 0) { |
934 if (CHANCE16R(1, 14, r) && (num = indsp->number_of_sounds) != 0) { |
968 SndPlayTileFx( |
935 SndPlayTileFx( |
969 (SoundFx)(_industry_sounds[i->type][1] + (((r >> 16) * num) >> 16)), |
936 (SoundFx)(indsp->random_sounds[((r >> 16) * num) >> 16]), |
970 i->xy); |
937 i->xy); |
971 } |
938 } |
972 } |
939 } |
973 |
940 |
974 i->counter--; |
941 i->counter--; |
975 |
942 |
976 /* produce some cargo */ |
943 /* produce some cargo */ |
977 if ((i->counter & 0xFF) == 0) { |
944 if ((i->counter & 0xFF) == 0) { |
|
945 IndustyBehaviour indbehav = indsp->behaviour; |
978 i->cargo_waiting[0] = min(0xffff, i->cargo_waiting[0] + i->production_rate[0]); |
946 i->cargo_waiting[0] = min(0xffff, i->cargo_waiting[0] + i->production_rate[0]); |
979 i->cargo_waiting[1] = min(0xffff, i->cargo_waiting[1] + i->production_rate[1]); |
947 i->cargo_waiting[1] = min(0xffff, i->cargo_waiting[1] + i->production_rate[1]); |
980 |
948 |
981 if (i->type == IT_FARM || i->type == IT_FARM_2) { |
949 if (indbehav & INDUSTRYBEH_PLANT_FIELDS) { |
982 MaybePlantFarmField(i); |
950 MaybePlantFarmField(i); |
983 } else if (i->type == IT_LUMBER_MILL && (i->counter & 0x1FF) == 0) { |
951 } else if ((indbehav & INDUSTRYBEH_CUT_TREES) && (i->counter & 0x1FF) == 0) { |
984 ChopLumberMillTrees(i); |
952 ChopLumberMillTrees(i); |
985 } |
953 } |
986 } |
954 } |
987 } |
955 } |
988 |
956 |
1184 if (bits & 4 && (t & SLOPE_SW)) return false; |
1156 if (bits & 4 && (t & SLOPE_SW)) return false; |
1185 if (bits & 8 && (t & SLOPE_SE)) return false; |
1157 if (bits & 8 && (t & SLOPE_SE)) return false; |
1186 } |
1158 } |
1187 } |
1159 } |
1188 |
1160 |
1189 if (type == IT_BANK_TEMP) { |
1161 if (ind_behav & INDUSTRYBEH_ONLY_INTOWN) { |
1190 if (!IsTileType(cur_tile, MP_HOUSE)) { |
1162 if (!IsTileType(cur_tile, MP_HOUSE)) { |
1191 _error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS; |
1163 _error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS; |
1192 return false; |
1164 return false; |
1193 } |
1165 } |
1194 } else if (type == IT_BANK_TROPIC_ARCTIC) { |
1166 } else { |
1195 if (!IsTileType(cur_tile, MP_HOUSE)) { |
1167 if (ind_behav & INDUSTRYBEH_ONLY_NEARTOWN) { |
1196 _error_message = STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS; |
1168 if (!IsTileType(cur_tile, MP_HOUSE)) goto do_clear; |
1197 return false; |
1169 } else { |
|
1170 do_clear: |
|
1171 if (CmdFailed(DoCommand(cur_tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) |
|
1172 return false; |
1198 } |
1173 } |
1199 } else if (type == IT_TOY_SHOP) { |
|
1200 if (!IsTileType(cur_tile, MP_HOUSE)) goto do_clear; |
|
1201 } else if (type == IT_WATER_TOWER) { |
|
1202 if (!IsTileType(cur_tile, MP_HOUSE)) { |
|
1203 _error_message = STR_0316_CAN_ONLY_BE_BUILT_IN_TOWNS; |
|
1204 return false; |
|
1205 } |
|
1206 } else { |
|
1207 do_clear: |
|
1208 if (CmdFailed(DoCommand(cur_tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) |
|
1209 return false; |
|
1210 } |
1174 } |
1211 } |
1175 } |
1212 } |
1176 } |
1213 } while ((++it)->ti.x != -0x80); |
1177 } while ((++it)->ti.x != -0x80); |
1214 |
1178 |
1215 return true; |
1179 return true; |
1216 } |
1180 } |
1217 |
1181 |
1218 static bool CheckIfIndustryIsAllowed(TileIndex tile, int type, const Town *t) |
1182 static bool CheckIfIndustryIsAllowed(TileIndex tile, int type, const Town *t) |
1219 { |
1183 { |
1220 if (type == IT_BANK_TEMP && t->population < 1200) { |
1184 if ((GetIndustrySpec(type)->behaviour & INDUSTRYBEH_TOWN1200_MORE) && t->population < 1200) { |
1221 _error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS; |
1185 _error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS; |
1222 return false; |
1186 return false; |
1223 } |
1187 } |
1224 |
1188 |
1225 if (type == IT_TOY_SHOP && DistanceMax(t->xy, tile) > 9) { |
1189 if ((GetIndustrySpec(type)->behaviour & INDUSTRYBEH_ONLY_NEARTOWN) && DistanceMax(t->xy, tile) > 9) { |
1226 _error_message = STR_0239_SITE_UNSUITABLE; |
1190 _error_message = STR_0239_SITE_UNSUITABLE; |
1227 return false; |
1191 return false; |
1228 } |
1192 } |
1229 |
1193 |
1230 return true; |
1194 return true; |
1543 const IndustryTileTable *it = indspec->table[RandomRange(indspec->num_table)]; |
1504 const IndustryTileTable *it = indspec->table[RandomRange(indspec->num_table)]; |
1544 |
1505 |
1545 return CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, it); |
1506 return CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, it); |
1546 } |
1507 } |
1547 |
1508 |
1548 static const byte _numof_industry_table[4][12] = { |
1509 static const byte _numof_industry_table[5][12] = { |
1549 /* difficulty settings for number of industries */ |
1510 /* difficulty settings for number of industries */ |
1550 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //none |
1511 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //none |
|
1512 {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, //very low |
1551 {0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5}, //low |
1513 {0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5}, //low |
1552 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, //normal |
1514 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, //normal |
1553 {0, 2, 3, 4, 6, 7, 8, 9, 10, 10, 10}, //high |
1515 {0, 2, 3, 4, 6, 7, 8, 9, 10, 10, 10}, //high |
1554 }; |
1516 }; |
1555 |
1517 |
|
1518 /** This function is the one who really do the creation work |
|
1519 * of random industries during game creation |
|
1520 * @param type IndustryType of the desired industry |
|
1521 * @param amount of industries that need to be built */ |
1556 static void PlaceInitialIndustry(IndustryType type, int amount) |
1522 static void PlaceInitialIndustry(IndustryType type, int amount) |
1557 { |
1523 { |
1558 int num = _numof_industry_table[_opt.diff.number_industries][amount]; |
1524 int num = _numof_industry_table[_opt.diff.number_industries][amount]; |
1559 |
1525 const IndustrySpec *ind_spc = GetIndustrySpec(type); |
1560 if (type == IT_OIL_REFINERY || type == IT_OIL_RIG) { |
1526 |
1561 /* These are always placed next to the coastline, so we scale by the perimeter instead. */ |
1527 /* These are always placed next to the coastline, so we scale by the perimeter instead. */ |
1562 num = ScaleByMapSize1D(num); |
1528 num = (ind_spc->check_proc == CHECK_REFINERY || ind_spc->check_proc == CHECK_OIL_RIG) ? ScaleByMapSize1D(num) : ScaleByMapSize(num); |
1563 } else { |
|
1564 num = ScaleByMapSize(num); |
|
1565 } |
|
1566 |
1529 |
1567 if (_opt.diff.number_industries != 0) { |
1530 if (_opt.diff.number_industries != 0) { |
1568 PlayerID old_player = _current_player; |
1531 PlayerID old_player = _current_player; |
1569 _current_player = OWNER_NONE; |
1532 _current_player = OWNER_NONE; |
1570 assert(num > 0); |
1533 assert(num > 0); |
1581 |
1544 |
1582 _current_player = old_player; |
1545 _current_player = old_player; |
1583 } |
1546 } |
1584 } |
1547 } |
1585 |
1548 |
|
1549 /** This function will create ramdon industries during game creation. |
|
1550 * It will scale the amount of industries by map size as well as difficulty level */ |
1586 void GenerateIndustries() |
1551 void GenerateIndustries() |
1587 { |
1552 { |
1588 const byte *b; |
|
1589 uint i = 0; |
1553 uint i = 0; |
|
1554 uint8 chance; |
|
1555 IndustryType it; |
|
1556 const IndustrySpec *ind_spc; |
1590 |
1557 |
1591 /* Find the total amount of industries */ |
1558 /* Find the total amount of industries */ |
1592 b = _industry_create_table[_opt.landscape]; |
1559 for (it = IT_COAL_MINE; it < NUM_INDUSTRYTYPES; it++) { |
1593 do { |
1560 |
1594 int num = _numof_industry_table[_opt.diff.number_industries][b[0]]; |
1561 ind_spc = GetIndustrySpec(it); |
1595 |
1562 if (ind_spc->enabled) { |
1596 if (b[1] == IT_OIL_REFINERY || b[1] == IT_OIL_RIG) { |
1563 chance = ind_spc->appear_creation[_opt.landscape]; |
1597 /* These are always placed next to the coastline, so we scale by the perimeter instead. */ |
1564 if (chance > 0) { |
1598 num = ScaleByMapSize1D(num); |
1565 /* once the chance of appearance is determind, it have to be scaled by |
1599 } else { |
1566 * the difficulty level. The "chance" in question is more an index into |
1600 num = ScaleByMapSize(num); |
1567 * the _numof_industry_table,in fact */ |
1601 } |
1568 int num = _numof_industry_table[_opt.diff.number_industries][chance]; |
1602 |
1569 |
1603 i += num; |
1570 /* These are always placed next to the coastline, so we scale by the perimeter instead. */ |
1604 } while ( (b+=2)[0] != 0); |
1571 num = (ind_spc->check_proc == CHECK_REFINERY || ind_spc->check_proc == CHECK_OIL_RIG) ? ScaleByMapSize1D(num) : ScaleByMapSize(num); |
|
1572 i += num; |
|
1573 } |
|
1574 } |
|
1575 } |
|
1576 |
1605 SetGeneratingWorldProgress(GWP_INDUSTRY, i); |
1577 SetGeneratingWorldProgress(GWP_INDUSTRY, i); |
1606 |
1578 |
1607 b = _industry_create_table[_opt.landscape]; |
1579 for (it = IT_COAL_MINE; it < NUM_INDUSTRYTYPES; it++) { |
1608 do { |
1580 /* Once the number of industries has been determined, let's really create them. |
1609 PlaceInitialIndustry(b[1], b[0]); |
1581 * The test for chance allows us to try create industries that are available only |
1610 } while ( (b+=2)[0] != 0); |
1582 * for this landscape. |
|
1583 * @todo : Do we really have to pass chance as un-scaled value, since we've already |
|
1584 * processed that scaling above? No, don't think so. Will find a way. */ |
|
1585 ind_spc = GetIndustrySpec(it); |
|
1586 if (ind_spc->enabled) { |
|
1587 chance = ind_spc->appear_creation[_opt.landscape]; |
|
1588 if (chance > 0) PlaceInitialIndustry(it, chance); |
|
1589 } |
|
1590 }; |
1611 } |
1591 } |
1612 |
1592 |
1613 /* Change industry production or do closure */ |
1593 /* Change industry production or do closure */ |
1614 static void ExtChangeIndustryProduction(Industry *i) |
1594 static void ExtChangeIndustryProduction(Industry *i) |
1615 { |
1595 { |
1669 if (closeit) { |
1649 if (closeit) { |
1670 i->prod_level = 0; |
1650 i->prod_level = 0; |
1671 SetDParam(0, i->index); |
1651 SetDParam(0, i->index); |
1672 AddNewsItem( |
1652 AddNewsItem( |
1673 indspec->closure_text, |
1653 indspec->closure_text, |
1674 NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_TILE, NT_OPENCLOSE, 0), |
1654 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_OPENCLOSE, 0), |
1675 i->xy + TileDiffXY(1, 1), 0 |
1655 i->xy + TileDiffXY(1, 1), 0 |
1676 ); |
1656 ); |
1677 } |
1657 } |
1678 } |
1658 } |
1679 |
1659 |
1680 |
1660 |
1681 static void UpdateIndustryStatistics(Industry *i) |
1661 static void UpdateIndustryStatistics(Industry *i) |
1682 { |
1662 { |
1683 byte pct; |
1663 byte pct; |
1684 |
1664 bool refresh = false; |
1685 if (i->produced_cargo[0] != CT_INVALID) { |
1665 const IndustrySpec *indsp = GetIndustrySpec(i->type); |
1686 pct = 0; |
1666 |
1687 if (i->last_mo_production[0] != 0) { |
1667 for (byte j = 0; j < lengthof(indsp->produced_cargo); j++) { |
1688 i->last_prod_year = _cur_year; |
1668 if (indsp->produced_cargo[j] != CT_INVALID) { |
1689 pct = min(i->last_mo_transported[0] * 256 / i->last_mo_production[0],255); |
1669 pct = 0; |
1690 } |
1670 if (i->last_mo_production[j] != 0) { |
1691 i->pct_transported[0] = pct; |
1671 i->last_prod_year = _cur_year; |
1692 |
1672 pct = min(i->last_mo_transported[j] * 256 / i->last_mo_production[j], 255); |
1693 i->total_production[0] = i->last_mo_production[0]; |
1673 } |
1694 i->last_mo_production[0] = 0; |
1674 i->pct_transported[j] = pct; |
1695 |
1675 |
1696 i->total_transported[0] = i->last_mo_transported[0]; |
1676 i->total_production[j] = i->last_mo_production[j]; |
1697 i->last_mo_transported[0] = 0; |
1677 i->last_mo_production[j] = 0; |
1698 } |
1678 |
1699 |
1679 i->total_transported[j] = i->last_mo_transported[j]; |
1700 if (i->produced_cargo[1] != CT_INVALID) { |
1680 i->last_mo_transported[j] = 0; |
1701 pct = 0; |
1681 refresh = true; |
1702 if (i->last_mo_production[1] != 0) { |
1682 } |
1703 i->last_prod_year = _cur_year; |
1683 } |
1704 pct = min(i->last_mo_transported[1] * 256 / i->last_mo_production[1],255); |
1684 |
1705 } |
1685 if (refresh) |
1706 i->pct_transported[1] = pct; |
|
1707 |
|
1708 i->total_production[1] = i->last_mo_production[1]; |
|
1709 i->last_mo_production[1] = 0; |
|
1710 |
|
1711 i->total_transported[1] = i->last_mo_transported[1]; |
|
1712 i->last_mo_transported[1] = 0; |
|
1713 } |
|
1714 |
|
1715 |
|
1716 if (i->produced_cargo[0] != CT_INVALID || i->produced_cargo[1] != CT_INVALID) |
|
1717 InvalidateWindow(WC_INDUSTRY_VIEW, i->index); |
1686 InvalidateWindow(WC_INDUSTRY_VIEW, i->index); |
1718 |
1687 |
1719 if (i->prod_level == 0) { |
1688 if (i->prod_level == 0) { |
1720 DeleteIndustry(i); |
1689 DeleteIndustry(i); |
1721 } else if (_patches.smooth_economy) { |
1690 } else if (_patches.smooth_economy) { |
1722 ExtChangeIndustryProduction(i); |
1691 ExtChangeIndustryProduction(i); |
1723 } |
1692 } |
1724 } |
1693 } |
1725 |
1694 |
1726 static const byte _new_industry_rand[4][32] = { |
1695 /** Simple helper that will collect data for the generation of industries */ |
1727 {12, 12, 12, 12, 12, 12, 12, 0, 0, 6, 6, 9, 9, 3, 3, 3, 18, 18, 4, 4, 2, 2, 5, 5, 5, 5, 5, 5, 1, 1, 8, 8}, |
1696 struct ProbabilityHelper { |
1728 {16, 16, 16, 0, 0, 0, 9, 9, 9, 9, 13, 13, 3, 3, 3, 3, 15, 15, 15, 4, 4, 11, 11, 11, 11, 11, 14, 14, 1, 1, 7, 7}, |
1697 uint16 prob; ///< probability |
1729 {21, 21, 21, 24, 22, 22, 22, 22, 23, 23, 16, 16, 16, 4, 4, 19, 19, 19, 13, 13, 20, 20, 20, 11, 11, 11, 17, 17, 17, 10, 10, 10}, |
1698 IndustryType ind; ///< industry id correcponding |
1730 {30, 30, 30, 36, 36, 31, 31, 31, 27, 27, 27, 28, 28, 28, 26, 26, 26, 34, 34, 34, 35, 35, 35, 29, 29, 29, 32, 32, 32, 33, 33, 33}, |
|
1731 }; |
1699 }; |
1732 |
1700 |
1733 static void MaybeNewIndustry(uint32 r) |
1701 /** |
1734 { |
1702 * Try to create a random industry, during gameplay |
1735 int type =_new_industry_rand[_opt.landscape][GB(r, 16, 5)]; |
1703 */ |
1736 int j; |
1704 static void MaybeNewIndustry(void) |
1737 Industry *i; |
1705 { |
1738 const IndustrySpec *ind_spc = GetIndustrySpec(type);; |
1706 Industry *ind; //will receive the industry's creation pointer |
1739 |
1707 IndustryType rndtype, j; // Loop controlers |
1740 if (type == IT_OIL_WELL && _cur_year > 1950) return; |
1708 const IndustrySpec *ind_spc; |
1741 if (type == IT_OIL_RIG && _cur_year < 1960) return; |
1709 uint num = 0; |
1742 |
1710 ProbabilityHelper cumulative_probs[NUM_INDUSTRYTYPES]; // probability collector |
1743 j = 2000; |
1711 uint16 probability_max = 0; |
|
1712 |
|
1713 /* Generate a list of all possible industries that can be built. */ |
|
1714 for (j = 0; j < NUM_INDUSTRYTYPES; j++) { |
|
1715 byte chance = GetIndustrySpec(j)->appear_ingame[_opt.landscape]; |
|
1716 |
|
1717 /* if appearing chance for this landscape is above 0, this industry can be chosen */ |
|
1718 if (chance != 0) { |
|
1719 probability_max += chance; |
|
1720 /* adds the result for this industry */ |
|
1721 cumulative_probs[num].ind = j; |
|
1722 cumulative_probs[num++].prob = probability_max; |
|
1723 } |
|
1724 } |
|
1725 |
|
1726 /* Find a random type, with maximum being what has been evaluate above*/ |
|
1727 rndtype = RandomRange(probability_max); |
|
1728 for (j = 0; j < NUM_INDUSTRYTYPES; j++) { |
|
1729 /* and choose the index of the industry that matches as close as possible this random type */ |
|
1730 if (cumulative_probs[j].prob >= rndtype) break; |
|
1731 } |
|
1732 |
|
1733 ind_spc = GetIndustrySpec(cumulative_probs[j].ind); |
|
1734 /* Check if it is allowed */ |
|
1735 if ((ind_spc->behaviour & INDUSTRYBEH_BEFORE_1950) && _cur_year > 1950) return; |
|
1736 if ((ind_spc->behaviour & INDUSTRYBEH_AFTER_1960) && _cur_year < 1960) return; |
|
1737 |
|
1738 /* try to create 2000 times this industry */ |
|
1739 num = 2000; |
1744 for (;;) { |
1740 for (;;) { |
1745 i = CreateNewIndustry(RandomTile(), type); |
1741 ind = CreateNewIndustry(RandomTile(), cumulative_probs[j].ind); |
1746 if (i != NULL) break; |
1742 if (ind != NULL) break; |
1747 if (--j == 0) return; |
1743 if (--num == 0) return; |
1748 } |
1744 } |
1749 |
1745 |
1750 SetDParam(0, ind_spc->name); |
1746 SetDParam(0, ind_spc->name); |
1751 SetDParam(1, i->town->index); |
1747 SetDParam(1, ind->town->index); |
1752 AddNewsItem(ind_spc->new_industry_text, |
1748 AddNewsItem(ind_spc->new_industry_text, |
1753 NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_TILE, NT_OPENCLOSE, 0), i->xy, 0); |
1749 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_OPENCLOSE, 0), ind->xy, 0); |
1754 } |
1750 } |
1755 |
1751 |
1756 static void ChangeIndustryProduction(Industry *i) |
1752 static void ChangeIndustryProduction(Industry *i) |
1757 { |
1753 { |
1758 bool only_decrease = false; |
1754 bool only_decrease = false; |
1877 SLE_CONDVAR(Industry, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5), |
1873 SLE_CONDVAR(Industry, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5), |
1878 SLE_CONDVAR(Industry, xy, SLE_UINT32, 6, SL_MAX_VERSION), |
1874 SLE_CONDVAR(Industry, xy, SLE_UINT32, 6, SL_MAX_VERSION), |
1879 SLE_VAR(Industry, width, SLE_UINT8), |
1875 SLE_VAR(Industry, width, SLE_UINT8), |
1880 SLE_VAR(Industry, height, SLE_UINT8), |
1876 SLE_VAR(Industry, height, SLE_UINT8), |
1881 SLE_REF(Industry, town, REF_TOWN), |
1877 SLE_REF(Industry, town, REF_TOWN), |
1882 SLE_ARR(Industry, produced_cargo, SLE_UINT8, 2), |
1878 SLE_CONDNULL( 2, 2, 60), ///< used to be industry's produced_cargo |
1883 SLE_ARR(Industry, cargo_waiting, SLE_UINT16, 2), |
1879 SLE_ARR(Industry, cargo_waiting, SLE_UINT16, 2), |
1884 SLE_ARR(Industry, production_rate, SLE_UINT8, 2), |
1880 SLE_ARR(Industry, production_rate, SLE_UINT8, 2), |
1885 SLE_ARR(Industry, accepts_cargo, SLE_UINT8, 3), |
1881 SLE_CONDNULL( 3, 2, 60), ///< used to be industry's accepts_cargo |
1886 SLE_VAR(Industry, prod_level, SLE_UINT8), |
1882 SLE_VAR(Industry, prod_level, SLE_UINT8), |
1887 SLE_ARR(Industry, last_mo_production, SLE_UINT16, 2), |
1883 SLE_ARR(Industry, last_mo_production, SLE_UINT16, 2), |
1888 SLE_ARR(Industry, last_mo_transported, SLE_UINT16, 2), |
1884 SLE_ARR(Industry, last_mo_transported, SLE_UINT16, 2), |
1889 SLE_ARR(Industry, pct_transported, SLE_UINT8, 2), |
1885 SLE_ARR(Industry, pct_transported, SLE_UINT8, 2), |
1890 SLE_ARR(Industry, total_production, SLE_UINT16, 2), |
1886 SLE_ARR(Industry, total_production, SLE_UINT16, 2), |