41 #include "date.h" |
41 #include "date.h" |
42 #include "cargotype.h" |
42 #include "cargotype.h" |
43 #include "player_face.h" |
43 #include "player_face.h" |
44 #include "group.h" |
44 #include "group.h" |
45 |
45 |
|
46 /** |
|
47 * Multiply two integer values and shift the results to right. |
|
48 * |
|
49 * This function multiplies two integer values. The result is |
|
50 * shifted by the amount of shift to right. |
|
51 * |
|
52 * @param a The first integer |
|
53 * @param b The second integer |
|
54 * @param shift The amount to shift the value to right. |
|
55 * @return The shifted result |
|
56 */ |
|
57 static inline int32 BigMulS(const int32 a, const int32 b, const uint8 shift) |
|
58 { |
|
59 return (int32)((int64)a * (int64)b >> shift); |
|
60 } |
|
61 |
|
62 /** |
|
63 * Multiply two unsigned integers and shift the results to right. |
|
64 * |
|
65 * This function multiplies two unsigned integers. The result is |
|
66 * shifted by the amount of shift to right. |
|
67 * |
|
68 * @param a The first unsigned integer |
|
69 * @param b The second unsigned integer |
|
70 * @param shift The amount to shift the value to right. |
|
71 * @return The shifted result |
|
72 */ |
|
73 static inline uint32 BigMulSU(const uint32 a, const uint32 b, const uint8 shift) |
|
74 { |
|
75 return (uint32)((uint64)a * (uint64)b >> shift); |
|
76 } |
|
77 |
46 /* Score info */ |
78 /* Score info */ |
47 const ScoreInfo _score_info[] = { |
79 const ScoreInfo _score_info[] = { |
48 { SCORE_VEHICLES, 120, 100 }, |
80 { SCORE_VEHICLES, 120, 100 }, |
49 { SCORE_STATIONS, 80, 100 }, |
81 { SCORE_STATIONS, 80, 100 }, |
50 { SCORE_MIN_PROFIT, 10000, 100 }, |
82 { SCORE_MIN_PROFIT, 10000, 100 }, |
61 |
93 |
62 Money CalculateCompanyValue(const Player* p) |
94 Money CalculateCompanyValue(const Player* p) |
63 { |
95 { |
64 PlayerID owner = p->index; |
96 PlayerID owner = p->index; |
65 /* Do a little nasty by using CommandCost, so we can use the "overflow" protection of CommandCost */ |
97 /* Do a little nasty by using CommandCost, so we can use the "overflow" protection of CommandCost */ |
66 CommandCost value; |
98 Money value = 0; |
67 |
99 |
68 { |
100 Station *st; |
69 Station *st; |
101 uint num = 0; |
70 uint num = 0; |
102 |
71 |
103 FOR_ALL_STATIONS(st) { |
72 FOR_ALL_STATIONS(st) { |
104 if (st->owner == owner) num += CountBits(st->facilities); |
73 if (st->owner == owner) num += COUNTBITS(st->facilities); |
105 } |
74 } |
106 |
75 |
107 value += num * _price.station_value * 25; |
76 value.AddCost(num * _price.station_value * 25); |
108 |
77 } |
109 Vehicle *v; |
78 |
110 FOR_ALL_VEHICLES(v) { |
79 { |
111 if (v->owner != owner) continue; |
80 Vehicle *v; |
112 |
81 |
113 if (v->type == VEH_TRAIN || |
82 FOR_ALL_VEHICLES(v) { |
114 v->type == VEH_ROAD || |
83 if (v->owner != owner) continue; |
115 (v->type == VEH_AIRCRAFT && IsNormalAircraft(v)) || |
84 |
116 v->type == VEH_SHIP) { |
85 if (v->type == VEH_TRAIN || |
117 value += v->value * 3 >> 1; |
86 v->type == VEH_ROAD || |
|
87 (v->type == VEH_AIRCRAFT && IsNormalAircraft(v)) || |
|
88 v->type == VEH_SHIP) { |
|
89 value.AddCost(v->value * 3 >> 1); |
|
90 } |
|
91 } |
118 } |
92 } |
119 } |
93 |
120 |
94 /* Add real money value */ |
121 /* Add real money value */ |
95 value.AddCost(-p->current_loan); |
122 value -= p->current_loan; |
96 value.AddCost(p->player_money); |
123 value += p->player_money; |
97 |
124 |
98 return max(value.GetCost(), 1LL); |
125 return max(value, (Money)1); |
99 } |
126 } |
100 |
127 |
101 /** if update is set to true, the economy is updated with this score |
128 /** if update is set to true, the economy is updated with this score |
102 * (also the house is updated, should only be true in the on-tick event) |
129 * (also the house is updated, should only be true in the on-tick event) |
103 * @param update the economy with calculated score |
130 * @param update the economy with calculated score |
215 score = 0; |
242 score = 0; |
216 for (ScoreID i = SCORE_BEGIN; i < SCORE_END; i++) { |
243 for (ScoreID i = SCORE_BEGIN; i < SCORE_END; i++) { |
217 /* Skip the total */ |
244 /* Skip the total */ |
218 if (i == SCORE_TOTAL) continue; |
245 if (i == SCORE_TOTAL) continue; |
219 /* Check the score */ |
246 /* Check the score */ |
220 s = clamp(_score_part[owner][i], 0, _score_info[i].needed) * _score_info[i].score / _score_info[i].needed; |
247 s = Clamp(_score_part[owner][i], 0, _score_info[i].needed) * _score_info[i].score / _score_info[i].needed; |
221 score += s; |
248 score += s; |
222 total_score += _score_info[i].score; |
249 total_score += _score_info[i].score; |
223 } |
250 } |
224 |
251 |
225 _score_part[owner][SCORE_TOTAL] = score; |
252 _score_part[owner][SCORE_TOTAL] = score; |
299 |
326 |
300 /* Take care of rating in towns */ |
327 /* Take care of rating in towns */ |
301 FOR_ALL_TOWNS(t) { |
328 FOR_ALL_TOWNS(t) { |
302 /* If a player takes over, give the ratings to that player. */ |
329 /* If a player takes over, give the ratings to that player. */ |
303 if (new_player != PLAYER_SPECTATOR) { |
330 if (new_player != PLAYER_SPECTATOR) { |
304 if (HASBIT(t->have_ratings, old_player)) { |
331 if (HasBit(t->have_ratings, old_player)) { |
305 if (HASBIT(t->have_ratings, new_player)) { |
332 if (HasBit(t->have_ratings, new_player)) { |
306 // use max of the two ratings. |
333 // use max of the two ratings. |
307 t->ratings[new_player] = max(t->ratings[new_player], t->ratings[old_player]); |
334 t->ratings[new_player] = max(t->ratings[new_player], t->ratings[old_player]); |
308 } else { |
335 } else { |
309 SETBIT(t->have_ratings, new_player); |
336 SetBit(t->have_ratings, new_player); |
310 t->ratings[new_player] = t->ratings[old_player]; |
337 t->ratings[new_player] = t->ratings[old_player]; |
311 } |
338 } |
312 } |
339 } |
313 } |
340 } |
314 |
341 |
315 /* Reset the ratings for the old player */ |
342 /* Reset the ratings for the old player */ |
316 t->ratings[old_player] = 500; |
343 t->ratings[old_player] = 500; |
317 CLRBIT(t->have_ratings, old_player); |
344 ClrBit(t->have_ratings, old_player); |
318 } |
345 } |
319 |
346 |
320 { |
347 { |
321 int num_train = 0; |
348 int num_train = 0; |
322 int num_road = 0; |
349 int num_road = 0; |
516 |
543 |
517 DrawStringMultiCenter(49, 148, STR_7058_PRESIDENT, 94); |
544 DrawStringMultiCenter(49, 148, STR_7058_PRESIDENT, 94); |
518 |
545 |
519 switch (ni->string_id & 0xF0) { |
546 switch (ni->string_id & 0xF0) { |
520 case NB_BTROUBLE: |
547 case NB_BTROUBLE: |
521 DrawStringCentered(w->width >> 1, 1, STR_7056_TRANSPORT_COMPANY_IN_TROUBLE, 0); |
548 DrawStringCentered(w->width >> 1, 1, STR_7056_TRANSPORT_COMPANY_IN_TROUBLE, TC_FROMSTRING); |
522 |
549 |
523 SetDParam(0, p->index); |
550 SetDParam(0, p->index); |
524 |
551 |
525 DrawStringMultiCenter( |
552 DrawStringMultiCenter( |
526 ((w->width - 101) >> 1) + 98, |
553 ((w->width - 101) >> 1) + 98, |
528 STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED, |
555 STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED, |
529 w->width - 101); |
556 w->width - 101); |
530 break; |
557 break; |
531 |
558 |
532 case NB_BMERGER: |
559 case NB_BMERGER: |
533 DrawStringCentered(w->width >> 1, 1, STR_7059_TRANSPORT_COMPANY_MERGER, 0); |
560 DrawStringCentered(w->width >> 1, 1, STR_7059_TRANSPORT_COMPANY_MERGER, TC_FROMSTRING); |
534 SetDParam(0, ni->params[0]); |
561 SetDParam(0, ni->params[0]); |
535 SetDParam(1, p->index); |
562 SetDParam(1, p->index); |
536 SetDParam(2, ni->params[1]); |
563 SetDParam(2, ni->params[1]); |
537 DrawStringMultiCenter( |
564 DrawStringMultiCenter( |
538 ((w->width - 101) >> 1) + 98, |
565 ((w->width - 101) >> 1) + 98, |
540 ni->params[1] == 0 ? STR_707F_HAS_BEEN_TAKEN_OVER_BY : STR_705A_HAS_BEEN_SOLD_TO_FOR, |
567 ni->params[1] == 0 ? STR_707F_HAS_BEEN_TAKEN_OVER_BY : STR_705A_HAS_BEEN_SOLD_TO_FOR, |
541 w->width - 101); |
568 w->width - 101); |
542 break; |
569 break; |
543 |
570 |
544 case NB_BBANKRUPT: |
571 case NB_BBANKRUPT: |
545 DrawStringCentered(w->width >> 1, 1, STR_705C_BANKRUPT, 0); |
572 DrawStringCentered(w->width >> 1, 1, STR_705C_BANKRUPT, TC_FROMSTRING); |
546 SetDParam(0, ni->params[0]); |
573 SetDParam(0, ni->params[0]); |
547 DrawStringMultiCenter( |
574 DrawStringMultiCenter( |
548 ((w->width - 101) >> 1) + 98, |
575 ((w->width - 101) >> 1) + 98, |
549 90, |
576 90, |
550 STR_705D_HAS_BEEN_CLOSED_DOWN_BY, |
577 STR_705D_HAS_BEEN_CLOSED_DOWN_BY, |
551 w->width - 101); |
578 w->width - 101); |
552 break; |
579 break; |
553 |
580 |
554 case NB_BNEWCOMPANY: |
581 case NB_BNEWCOMPANY: |
555 DrawStringCentered(w->width >> 1, 1, STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED, 0); |
582 DrawStringCentered(w->width >> 1, 1, STR_705E_NEW_TRANSPORT_COMPANY_LAUNCHED, TC_FROMSTRING); |
556 SetDParam(0, p->index); |
583 SetDParam(0, p->index); |
557 SetDParam(1, ni->params[0]); |
584 SetDParam(1, ni->params[0]); |
558 DrawStringMultiCenter( |
585 DrawStringMultiCenter( |
559 ((w->width - 101) >> 1) + 98, |
586 ((w->width - 101) >> 1) + 98, |
560 90, |
587 90, |
609 _current_player = st->owner; |
636 _current_player = st->owner; |
610 SET_EXPENSES_TYPE(EXPENSES_PROPERTY); |
637 SET_EXPENSES_TYPE(EXPENSES_PROPERTY); |
611 SubtractMoneyFromPlayer(_price.station_value >> 1); |
638 SubtractMoneyFromPlayer(_price.station_value >> 1); |
612 } |
639 } |
613 |
640 |
614 if (!HASBIT(1<<0|1<<3|1<<6|1<<9, _cur_month)) |
641 if (!HasBit(1<<0|1<<3|1<<6|1<<9, _cur_month)) |
615 return; |
642 return; |
616 |
643 |
617 FOR_ALL_PLAYERS(p) { |
644 FOR_ALL_PLAYERS(p) { |
618 if (p->is_active) { |
645 if (p->is_active) { |
619 memmove(&p->old_economy[1], &p->old_economy[0], sizeof(p->old_economy) - sizeof(p->old_economy[0])); |
646 memmove(&p->old_economy[1], &p->old_economy[0], sizeof(p->old_economy) - sizeof(p->old_economy[0])); |
708 if (!p->is_active) continue; |
735 if (!p->is_active) continue; |
709 |
736 |
710 _current_player = p->index; |
737 _current_player = p->index; |
711 SET_EXPENSES_TYPE(EXPENSES_LOAN_INT); |
738 SET_EXPENSES_TYPE(EXPENSES_LOAN_INT); |
712 |
739 |
713 SubtractMoneyFromPlayer(CommandCost((Money)BIGMULUS(p->current_loan, interest, 16))); |
740 SubtractMoneyFromPlayer(CommandCost((Money)BigMulSU(p->current_loan, interest, 16))); |
714 |
741 |
715 SET_EXPENSES_TYPE(EXPENSES_OTHER); |
742 SET_EXPENSES_TYPE(EXPENSES_OTHER); |
716 SubtractMoneyFromPlayer(_price.station_value >> 2); |
743 SubtractMoneyFromPlayer(_price.station_value >> 2); |
717 } |
744 } |
718 } |
745 } |
979 |
1006 |
980 fr->from = i = GetRandomIndustry(); |
1007 fr->from = i = GetRandomIndustry(); |
981 if (i == NULL) return; |
1008 if (i == NULL) return; |
982 |
1009 |
983 /* Randomize cargo type */ |
1010 /* Randomize cargo type */ |
984 if (HASBIT(Random(), 0) && i->produced_cargo[1] != CT_INVALID) { |
1011 if (HasBit(Random(), 0) && i->produced_cargo[1] != CT_INVALID) { |
985 cargo = i->produced_cargo[1]; |
1012 cargo = i->produced_cargo[1]; |
986 trans = i->last_month_pct_transported[1]; |
1013 trans = i->last_month_pct_transported[1]; |
987 total = i->last_month_production[1]; |
1014 total = i->last_month_production[1]; |
988 } else { |
1015 } else { |
989 cargo = i->produced_cargo[0]; |
1016 cargo = i->produced_cargo[0]; |
1149 Money GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type) |
1176 Money GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type) |
1150 { |
1177 { |
1151 const CargoSpec *cs = GetCargo(cargo_type); |
1178 const CargoSpec *cs = GetCargo(cargo_type); |
1152 |
1179 |
1153 /* Use callback to calculate cargo profit, if available */ |
1180 /* Use callback to calculate cargo profit, if available */ |
1154 if (HASBIT(cs->callback_mask, CBM_CARGO_PROFIT_CALC)) { |
1181 if (HasBit(cs->callback_mask, CBM_CARGO_PROFIT_CALC)) { |
1155 uint32 var18 = min(dist, 0xFFFF) | (min(num_pieces, 0xFF) << 16) | (transit_days << 24); |
1182 uint32 var18 = min(dist, 0xFFFF) | (min(num_pieces, 0xFF) << 16) | (transit_days << 24); |
1156 uint16 callback = GetCargoCallback(CBID_CARGO_PROFIT_CALC, 0, var18, cs); |
1183 uint16 callback = GetCargoCallback(CBID_CARGO_PROFIT_CALC, 0, var18, cs); |
1157 if (callback != CALLBACK_FAILED) { |
1184 if (callback != CALLBACK_FAILED) { |
1158 int result = GB(callback, 0, 14); |
1185 int result = GB(callback, 0, 14); |
1159 |
1186 |
1160 /* Simulate a 15 bit signed value */ |
1187 /* Simulate a 15 bit signed value */ |
1161 if (HASBIT(callback, 14)) result = 0x4000 - result; |
1188 if (HasBit(callback, 14)) result = 0x4000 - result; |
1162 |
1189 |
1163 /* "The result should be a signed multiplier that gets multiplied |
1190 /* "The result should be a signed multiplier that gets multiplied |
1164 * by the amount of cargo moved and the price factor, then gets |
1191 * by the amount of cargo moved and the price factor, then gets |
1165 * divided by 8192." */ |
1192 * divided by 8192." */ |
1166 return result * num_pieces * _cargo_payment_rates[cargo_type] / 8192; |
1193 return result * num_pieces * _cargo_payment_rates[cargo_type] / 8192; |
1197 time_factor = MAX_TIME_FACTOR - 2 * days_over_days1 + days2; |
1224 time_factor = MAX_TIME_FACTOR - 2 * days_over_days1 + days2; |
1198 } |
1225 } |
1199 |
1226 |
1200 if (time_factor < MIN_TIME_FACTOR) time_factor = MIN_TIME_FACTOR; |
1227 if (time_factor < MIN_TIME_FACTOR) time_factor = MIN_TIME_FACTOR; |
1201 |
1228 |
1202 return BIGMULSS(dist * time_factor * num_pieces, _cargo_payment_rates[cargo_type], 21); |
1229 return BigMulS(dist * time_factor * num_pieces, _cargo_payment_rates[cargo_type], 21); |
1203 } |
1230 } |
1204 |
1231 |
1205 static void DeliverGoodsToIndustry(TileIndex xy, CargoID cargo_type, int num_pieces) |
1232 static void DeliverGoodsToIndustry(TileIndex xy, CargoID cargo_type, int num_pieces) |
1206 { |
1233 { |
1207 Industry *best = NULL; |
1234 Industry *best = NULL; |
1224 } |
1251 } |
1225 |
1252 |
1226 /* Check if matching cargo has been found */ |
1253 /* Check if matching cargo has been found */ |
1227 if (i == lengthof(ind->accepts_cargo)) continue; |
1254 if (i == lengthof(ind->accepts_cargo)) continue; |
1228 |
1255 |
1229 if (HASBIT(indspec->callback_flags, CBM_IND_REFUSE_CARGO)) { |
1256 if (HasBit(indspec->callback_flags, CBM_IND_REFUSE_CARGO)) { |
1230 uint16 res = GetIndustryCallback(CBID_INDUSTRY_REFUSE_CARGO, 0, GetReverseCargoTranslation(cargo_type, indspec->grf_prop.grffile), ind, ind->type, ind->xy); |
1257 uint16 res = GetIndustryCallback(CBID_INDUSTRY_REFUSE_CARGO, 0, GetReverseCargoTranslation(cargo_type, indspec->grf_prop.grffile), ind, ind->type, ind->xy); |
1231 if (res == 0) continue; |
1258 if (res == 0) continue; |
1232 } |
1259 } |
1233 |
1260 |
1234 uint dist = DistanceManhattan(ind->xy, xy); |
1261 uint dist = DistanceManhattan(ind->xy, xy); |
1246 uint16 callback = indspec->callback_flags; |
1273 uint16 callback = indspec->callback_flags; |
1247 |
1274 |
1248 best->was_cargo_delivered = true; |
1275 best->was_cargo_delivered = true; |
1249 best->last_cargo_accepted_at = _date; |
1276 best->last_cargo_accepted_at = _date; |
1250 |
1277 |
1251 if (HASBIT(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HASBIT(callback, CBM_IND_PRODUCTION_256_TICKS)) { |
1278 if (HasBit(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(callback, CBM_IND_PRODUCTION_256_TICKS)) { |
1252 best->incoming_cargo_waiting[accepted_cargo_index] = min(num_pieces + best->incoming_cargo_waiting[accepted_cargo_index], 0xFFFF); |
1279 best->incoming_cargo_waiting[accepted_cargo_index] = min(num_pieces + best->incoming_cargo_waiting[accepted_cargo_index], 0xFFFF); |
1253 if (HASBIT(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) { |
1280 if (HasBit(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) { |
1254 IndustryProductionCallback(best, 0); |
1281 IndustryProductionCallback(best, 0); |
1255 } else { |
1282 } else { |
1256 InvalidateWindow(WC_INDUSTRY_VIEW, best->index); |
1283 InvalidateWindow(WC_INDUSTRY_VIEW, best->index); |
1257 } |
1284 } |
1258 } else { |
1285 } else { |
1259 best->produced_cargo_waiting[0] = min(best->produced_cargo_waiting[0] + (num_pieces * indspec->input_cargo_multiplier[accepted_cargo_index][0] / 256), 0xFFFF); |
1286 best->produced_cargo_waiting[0] = min(best->produced_cargo_waiting[0] + (num_pieces * indspec->input_cargo_multiplier[accepted_cargo_index][0] / 256), 0xFFFF); |
1260 best->produced_cargo_waiting[1] = min(best->produced_cargo_waiting[1] + (num_pieces * indspec->input_cargo_multiplier[accepted_cargo_index][1] / 256), 0xFFFF); |
1287 best->produced_cargo_waiting[1] = min(best->produced_cargo_waiting[1] + (num_pieces * indspec->input_cargo_multiplier[accepted_cargo_index][1] / 256), 0xFFFF); |
1261 } |
1288 } |
1262 |
1289 |
|
1290 TriggerIndustry(best, INDUSTRY_TRIGGER_RECEIVED_CARGO); |
1263 StartStopIndustryTileAnimation(best, IAT_INDUSTRY_RECEIVED_CARGO); |
1291 StartStopIndustryTileAnimation(best, IAT_INDUSTRY_RECEIVED_CARGO); |
1264 } |
1292 } |
1265 } |
1293 } |
1266 |
1294 |
1267 static bool CheckSubsidised(Station *from, Station *to, CargoID cargo_type) |
1295 static bool CheckSubsidised(Station *from, Station *to, CargoID cargo_type) |
1340 |
1368 |
1341 /* Update player statistics */ |
1369 /* Update player statistics */ |
1342 { |
1370 { |
1343 Player *p = GetPlayer(_current_player); |
1371 Player *p = GetPlayer(_current_player); |
1344 p->cur_economy.delivered_cargo += num_pieces; |
1372 p->cur_economy.delivered_cargo += num_pieces; |
1345 SETBIT(p->cargo_types, cargo_type); |
1373 SetBit(p->cargo_types, cargo_type); |
1346 } |
1374 } |
1347 |
1375 |
1348 /* Get station pointers. */ |
1376 /* Get station pointers. */ |
1349 s_from = GetStation(source); |
1377 s_from = GetStation(source); |
1350 s_to = GetStation(dest); |
1378 s_to = GetStation(dest); |
1394 /* The owner of the train wants to be paid */ |
1422 /* The owner of the train wants to be paid */ |
1395 PlayerID old_player = _current_player; |
1423 PlayerID old_player = _current_player; |
1396 _current_player = front_v->owner; |
1424 _current_player = front_v->owner; |
1397 |
1425 |
1398 /* At this moment loading cannot be finished */ |
1426 /* At this moment loading cannot be finished */ |
1399 CLRBIT(front_v->vehicle_flags, VF_LOADING_FINISHED); |
1427 ClrBit(front_v->vehicle_flags, VF_LOADING_FINISHED); |
1400 |
1428 |
1401 /* Start unloading in at the first possible moment */ |
1429 /* Start unloading in at the first possible moment */ |
1402 front_v->load_unload_time_rem = 1; |
1430 front_v->load_unload_time_rem = 1; |
1403 |
1431 |
1404 for (Vehicle *v = front_v; v != NULL; v = v->Next()) { |
1432 for (Vehicle *v = front_v; v != NULL; v = v->Next()) { |
1405 /* No cargo to unload */ |
1433 /* No cargo to unload */ |
1406 if (v->cargo_cap == 0 || v->cargo.Empty()) continue; |
1434 if (v->cargo_cap == 0 || v->cargo.Empty()) continue; |
1407 |
1435 |
1408 /* All cargo has already been paid for, no need to pay again */ |
1436 /* All cargo has already been paid for, no need to pay again */ |
1409 if (!v->cargo.UnpaidCargo()) { |
1437 if (!v->cargo.UnpaidCargo()) { |
1410 SETBIT(v->vehicle_flags, VF_CARGO_UNLOADING); |
1438 SetBit(v->vehicle_flags, VF_CARGO_UNLOADING); |
1411 continue; |
1439 continue; |
1412 } |
1440 } |
1413 |
1441 |
1414 GoodsEntry *ge = &st->goods[v->cargo_type]; |
1442 GoodsEntry *ge = &st->goods[v->cargo_type]; |
1415 const CargoList::List *cargos = v->cargo.Packets(); |
1443 const CargoList::List *cargos = v->cargo.Packets(); |
1416 |
1444 |
1417 for (CargoList::List::const_iterator it = cargos->begin(); it != cargos->end(); it++) { |
1445 for (CargoList::List::const_iterator it = cargos->begin(); it != cargos->end(); it++) { |
1418 CargoPacket *cp = *it; |
1446 CargoPacket *cp = *it; |
1419 if (!cp->paid_for && |
1447 if (!cp->paid_for && |
1420 cp->source != last_visited && |
1448 cp->source != last_visited && |
1421 HASBIT(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE) && |
1449 HasBit(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE) && |
1422 (front_v->current_order.flags & OF_TRANSFER) == 0) { |
1450 (front_v->current_order.flags & OF_TRANSFER) == 0) { |
1423 /* Deliver goods to the station */ |
1451 /* Deliver goods to the station */ |
1424 st->time_since_unload = 0; |
1452 st->time_since_unload = 0; |
1425 |
1453 |
1426 /* handle end of route payment */ |
1454 /* handle end of route payment */ |
1429 route_profit += profit; // display amount paid for final route delivery, A-D of a chain A-B-C-D |
1457 route_profit += profit; // display amount paid for final route delivery, A-D of a chain A-B-C-D |
1430 vehicle_profit += profit - cp->feeder_share; // whole vehicle is not payed for transfers picked up earlier |
1458 vehicle_profit += profit - cp->feeder_share; // whole vehicle is not payed for transfers picked up earlier |
1431 |
1459 |
1432 result |= 1; |
1460 result |= 1; |
1433 |
1461 |
1434 SETBIT(v->vehicle_flags, VF_CARGO_UNLOADING); |
1462 SetBit(v->vehicle_flags, VF_CARGO_UNLOADING); |
1435 } else if (front_v->current_order.flags & (OF_UNLOAD | OF_TRANSFER)) { |
1463 } else if (front_v->current_order.flags & (OF_UNLOAD | OF_TRANSFER)) { |
1436 if (!cp->paid_for && (front_v->current_order.flags & OF_TRANSFER) != 0) { |
1464 if (!cp->paid_for && (front_v->current_order.flags & OF_TRANSFER) != 0) { |
1437 Money profit = GetTransportedGoodsIncome( |
1465 Money profit = GetTransportedGoodsIncome( |
1438 cp->count, |
1466 cp->count, |
1439 /* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */ |
1467 /* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */ |
1484 { |
1512 { |
1485 assert(v->current_order.type == OT_LOADING); |
1513 assert(v->current_order.type == OT_LOADING); |
1486 |
1514 |
1487 /* We have not waited enough time till the next round of loading/unloading */ |
1515 /* We have not waited enough time till the next round of loading/unloading */ |
1488 if (--v->load_unload_time_rem != 0) { |
1516 if (--v->load_unload_time_rem != 0) { |
1489 if (_patches.improved_load && HASBIT(v->current_order.flags, OFB_FULL_LOAD)) { |
1517 if (_patches.improved_load && HasBit(v->current_order.flags, OFB_FULL_LOAD)) { |
1490 /* 'Reserve' this cargo for this vehicle, because we were first. */ |
1518 /* 'Reserve' this cargo for this vehicle, because we were first. */ |
1491 for (; v != NULL; v = v->Next()) { |
1519 for (; v != NULL; v = v->Next()) { |
1492 if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo.Count(); |
1520 if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo.Count(); |
1493 } |
1521 } |
1494 } |
1522 } |
1520 |
1548 |
1521 for (; v != NULL; v = v->Next()) { |
1549 for (; v != NULL; v = v->Next()) { |
1522 if (v->cargo_cap == 0) continue; |
1550 if (v->cargo_cap == 0) continue; |
1523 |
1551 |
1524 byte load_amount = EngInfo(v->engine_type)->load_amount; |
1552 byte load_amount = EngInfo(v->engine_type)->load_amount; |
1525 if (_patches.gradual_loading && HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_LOAD_AMOUNT)) { |
1553 if (_patches.gradual_loading && HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_LOAD_AMOUNT)) { |
1526 uint16 cb_load_amount = GetVehicleCallback(CBID_VEHICLE_LOAD_AMOUNT, 0, 0, v->engine_type, v); |
1554 uint16 cb_load_amount = GetVehicleCallback(CBID_VEHICLE_LOAD_AMOUNT, 0, 0, v->engine_type, v); |
1527 if (cb_load_amount != CALLBACK_FAILED && cb_load_amount != 0) load_amount = cb_load_amount & 0xFF; |
1555 if (cb_load_amount != CALLBACK_FAILED && cb_load_amount != 0) load_amount = cb_load_amount & 0xFF; |
1528 } |
1556 } |
1529 |
1557 |
1530 GoodsEntry *ge = &st->goods[v->cargo_type]; |
1558 GoodsEntry *ge = &st->goods[v->cargo_type]; |
1531 |
1559 |
1532 if (HASBIT(v->vehicle_flags, VF_CARGO_UNLOADING)) { |
1560 if (HasBit(v->vehicle_flags, VF_CARGO_UNLOADING)) { |
1533 uint cargo_count = v->cargo.Count(); |
1561 uint cargo_count = v->cargo.Count(); |
1534 uint amount_unloaded = _patches.gradual_loading ? min(cargo_count, load_amount) : cargo_count; |
1562 uint amount_unloaded = _patches.gradual_loading ? min(cargo_count, load_amount) : cargo_count; |
1535 bool remaining; // Are there cargo entities in this vehicle that can still be unloaded here? |
1563 bool remaining; // Are there cargo entities in this vehicle that can still be unloaded here? |
1536 |
1564 |
1537 if (HASBIT(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE) && !(u->current_order.flags & OF_TRANSFER)) { |
1565 if (HasBit(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE) && !(u->current_order.flags & OF_TRANSFER)) { |
1538 /* The cargo has reached it's final destination, the packets may now be destroyed */ |
1566 /* The cargo has reached it's final destination, the packets may now be destroyed */ |
1539 remaining = v->cargo.MoveTo(NULL, amount_unloaded, CargoList::MTA_FINAL_DELIVERY, last_visited); |
1567 remaining = v->cargo.MoveTo(NULL, amount_unloaded, CargoList::MTA_FINAL_DELIVERY, last_visited); |
1540 |
1568 |
1541 result |= 1; |
1569 result |= 1; |
1542 } else if (u->current_order.flags & (OF_UNLOAD | OF_TRANSFER)) { |
1570 } else if (u->current_order.flags & (OF_UNLOAD | OF_TRANSFER)) { |
1543 remaining = v->cargo.MoveTo(&ge->cargo, amount_unloaded); |
1571 remaining = v->cargo.MoveTo(&ge->cargo, amount_unloaded); |
1544 SETBIT(ge->acceptance_pickup, GoodsEntry::PICKUP); |
1572 SetBit(ge->acceptance_pickup, GoodsEntry::PICKUP); |
1545 |
1573 |
1546 result |= 2; |
1574 result |= 2; |
1547 } else { |
1575 } else { |
1548 /* The order changed while unloading (unset unload/transfer) or the |
1576 /* The order changed while unloading (unset unload/transfer) or the |
1549 * station does not accept goods anymore. */ |
1577 * station does not accept goods anymore. */ |
1550 CLRBIT(v->vehicle_flags, VF_CARGO_UNLOADING); |
1578 ClrBit(v->vehicle_flags, VF_CARGO_UNLOADING); |
1551 continue; |
1579 continue; |
1552 } |
1580 } |
1553 |
1581 |
1554 /* Deliver goods to the station */ |
1582 /* Deliver goods to the station */ |
1555 st->time_since_unload = 0; |
1583 st->time_since_unload = 0; |
1590 uint count = ge->cargo.Count(); |
1618 uint count = ge->cargo.Count(); |
1591 |
1619 |
1592 /* Skip loading this vehicle if another train/vehicle is already handling |
1620 /* Skip loading this vehicle if another train/vehicle is already handling |
1593 * the same cargo type at this station */ |
1621 * the same cargo type at this station */ |
1594 if (_patches.improved_load && cargo_left[v->cargo_type] <= 0) { |
1622 if (_patches.improved_load && cargo_left[v->cargo_type] <= 0) { |
1595 SETBIT(cargo_not_full, v->cargo_type); |
1623 SetBit(cargo_not_full, v->cargo_type); |
1596 continue; |
1624 continue; |
1597 } |
1625 } |
1598 |
1626 |
1599 if (cap > count) cap = count; |
1627 if (cap > count) cap = count; |
1600 if (_patches.gradual_loading) cap = min(cap, load_amount); |
1628 if (_patches.gradual_loading) cap = min(cap, load_amount); |
1625 |
1653 |
1626 result |= 2; |
1654 result |= 2; |
1627 } |
1655 } |
1628 |
1656 |
1629 if (v->cargo.Count() == v->cargo_cap) { |
1657 if (v->cargo.Count() == v->cargo_cap) { |
1630 SETBIT(cargo_full, v->cargo_type); |
1658 SetBit(cargo_full, v->cargo_type); |
1631 } else { |
1659 } else { |
1632 SETBIT(cargo_not_full, v->cargo_type); |
1660 SetBit(cargo_not_full, v->cargo_type); |
1633 } |
1661 } |
1634 } |
1662 } |
1635 |
1663 |
1636 /* We update these variables here, so gradual loading still fills |
1664 /* We update these variables here, so gradual loading still fills |
1637 * all wagons at the same time instead of using the same 'improved' |
1665 * all wagons at the same time instead of using the same 'improved' |
1638 * loading algorithm for the wagons (only fill wagon when there is |
1666 * loading algorithm for the wagons (only fill wagon when there is |
1639 * enough to fill the previous wagons) */ |
1667 * enough to fill the previous wagons) */ |
1640 if (_patches.improved_load && HASBIT(u->current_order.flags, OFB_FULL_LOAD)) { |
1668 if (_patches.improved_load && HasBit(u->current_order.flags, OFB_FULL_LOAD)) { |
1641 /* Update left cargo */ |
1669 /* Update left cargo */ |
1642 for (v = u; v != NULL; v = v->Next()) { |
1670 for (v = u; v != NULL; v = v->Next()) { |
1643 if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo.Count(); |
1671 if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo.Count(); |
1644 } |
1672 } |
1645 } |
1673 } |
1654 |
1682 |
1655 unloading_time = gradual_loading_wait_time[v->type]; |
1683 unloading_time = gradual_loading_wait_time[v->type]; |
1656 } |
1684 } |
1657 } else { |
1685 } else { |
1658 bool finished_loading = true; |
1686 bool finished_loading = true; |
1659 if (HASBIT(v->current_order.flags, OFB_FULL_LOAD)) { |
1687 if (HasBit(v->current_order.flags, OFB_FULL_LOAD)) { |
1660 if (_patches.full_load_any) { |
1688 if (_patches.full_load_any) { |
1661 /* if the aircraft carries passengers and is NOT full, then |
1689 /* if the aircraft carries passengers and is NOT full, then |
1662 * continue loading, no matter how much mail is in */ |
1690 * continue loading, no matter how much mail is in */ |
1663 if ((v->type == VEH_AIRCRAFT && IsCargoInClass(v->cargo_type, CC_PASSENGERS) && v->cargo_cap != v->cargo.Count()) || |
1691 if ((v->type == VEH_AIRCRAFT && IsCargoInClass(v->cargo_type, CC_PASSENGERS) && v->cargo_cap != v->cargo.Count()) || |
1664 (cargo_not_full && (cargo_full & ~cargo_not_full) == 0)) { // There are stull non-full cargos |
1692 (cargo_not_full && (cargo_full & ~cargo_not_full) == 0)) { // There are stull non-full cargos |