diff options
author | truelight <truelight@openttd.org> | 2004-12-27 18:18:44 +0000 |
---|---|---|
committer | truelight <truelight@openttd.org> | 2004-12-27 18:18:44 +0000 |
commit | 8dcbf2675b784ac3a060c046c10dc393c52f2772 (patch) | |
tree | 1bdcb08fe5cc2a1ad68d905888ce36d7f3a7cc14 /vehicle.c | |
parent | 96b36ec01eda43cd8e4efedaf8e9249e9597403f (diff) | |
download | openttd-8dcbf2675b784ac3a060c046c10dc393c52f2772.tar.xz |
(svn r1283) -Add: AutoRenew is now a client-side patch instead of a game-side patch
Note: this is the first commit that breaks compatibility with 0.3.5!
-Fix: Bufferoverflow with autorenew_money. It is now a 32-bit integer.
Diffstat (limited to 'vehicle.c')
-rw-r--r-- | vehicle.c | 105 |
1 files changed, 76 insertions, 29 deletions
@@ -25,8 +25,8 @@ void VehicleServiceInDepot(Vehicle *v) bool VehicleNeedsService(const Vehicle *v) { - return _patches.servint_ispercent ? - (v->reliability < _engines[v->engine_type].reliability * (100 - v->service_interval) / 100) : + return _patches.servint_ispercent ? + (v->reliability < _engines[v->engine_type].reliability * (100 - v->service_interval) / 100) : (v->date_of_last_service + v->service_interval < _date); } @@ -1358,6 +1358,7 @@ static void ShowVehicleGettingOld(Vehicle *v, StringID msg) { if (v->owner != _local_player) return; + // Do not show getting-old message if autorenew is active if (_patches.autorenew) return; @@ -1389,53 +1390,99 @@ void AgeVehicle(Vehicle *v) } } -void MaybeRenewVehicle(Vehicle *v, int32 build_cost) +extern int32 EstimateTrainCost(const RailVehicleInfo *rvi); +extern int32 EstimateRoadVehCost(byte engine_type); +extern int32 EstimateShipCost(uint16 engine_type); +extern int32 EstimateAircraftCost(uint16 engine_type); + +/* Renews a vehicle + p1 - Index of vehicle + p2 - Type of new engine */ +int32 CmdRenewVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2) { - Engine *e; + byte new_engine_type = p2; + Vehicle *v = DEREF_VEHICLE(p1); + int cost, build_cost; - // A vehicle is autorenewed when it it gets the amount of months - // give by _patches.autorenew_months away for his max age. - // Standard is -6, meaning 6 months before his max age - // It can be any value between -12 and 12. - if (!_patches.autorenew || v->age - v->max_age < (_patches.autorenew_months * 30)) - return; + SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); + switch (v->type) { + case VEH_Train: build_cost = EstimateTrainCost(RailVehInfo(v->engine_type)); break; + case VEH_Road: build_cost = EstimateRoadVehCost(new_engine_type); break; + case VEH_Ship: build_cost = EstimateShipCost(v->engine_type); break; + case VEH_Aircraft: build_cost = EstimateAircraftCost(new_engine_type); break; + default: return CMD_ERROR; + } + + /* In a rare situation, when 2 clients are connected to 1 company and have the same + settings, a vehicle can be replaced twice.. check if this is the situation here */ + if (v->age == 0) + return CMD_ERROR; + + /* Check if there is money for the upgrade.. if not, give a nice news-item + (that is needed, because this CMD is called automaticly) */ if (DEREF_PLAYER(v->owner)->money64 < _patches.autorenew_money + build_cost - v->value) { - if (v->owner == _local_player) { + if (_local_player == v->owner) { int message; SetDParam(0, v->unitnumber); switch (v->type) { - case VEH_Train: message = STR_TRAIN_AUTORENEW_FAILED; break; - case VEH_Road: message = STR_ROADVEHICLE_AUTORENEW_FAILED; break; - case VEH_Ship: message = STR_SHIP_AUTORENEW_FAILED; break; - case VEH_Aircraft: message = STR_AIRCRAFT_AUTORENEW_FAILED; break; + case VEH_Train: message = STR_TRAIN_AUTORENEW_FAILED; break; + case VEH_Road: message = STR_ROADVEHICLE_AUTORENEW_FAILED; break; + case VEH_Ship: message = STR_SHIP_AUTORENEW_FAILED; break; + case VEH_Aircraft: message = STR_AIRCRAFT_AUTORENEW_FAILED; break; // This should never happen default: message = 0; break; } AddNewsItem(message, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0); } - return; + + return CMD_ERROR; } - // Withdraw the money from the right player ;) - _current_player = v->owner; + cost = build_cost - v->value; - e = &_engines[v->engine_type]; - v->reliability = e->reliability; - v->reliability_spd_dec = e->reliability_spd_dec; - v->age = 0; + if (flags & DC_QUERY_COST) + return cost; - v->date_of_last_service = _date; - v->build_year = _cur_year; + if (flags & DC_EXEC) { + Engine *e; - SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); - SubtractMoneyFromPlayer(build_cost - v->value); - v->value = build_cost; + /* We do not really buy a new vehicle, we upgrade the old one */ + if (v->engine_type != new_engine_type) { + /* XXX - We need to do some more stuff here, when we are going to upgrade + to a new engine! */ + } + e = &_engines[new_engine_type]; + v->reliability = e->reliability; + v->reliability_spd_dec = e->reliability_spd_dec; + v->age = 0; - InvalidateWindow(WC_VEHICLE_DETAILS, v->index); + v->date_of_last_service = _date; + v->build_year = _cur_year; + + v->value = build_cost; + + InvalidateWindow(WC_VEHICLE_DETAILS, v->index); + } + + return cost; +} + +void MaybeRenewVehicle(Vehicle *v) +{ + if (v->owner != _local_player) + return; + + // A vehicle is autorenewed when it it gets the amount of months + // give by _patches.autorenew_months away for his max age. + // Standard is -6, meaning 6 months before his max age + // It can be any value between -12 and 12. + if (!_patches.autorenew || v->age - v->max_age < (_patches.autorenew_months * 30)) + return; - _current_player = OWNER_NONE; + /* Now renew the vehicle */ + DoCommandP(v->tile, v->index, v->engine_type, NULL, CMD_RENEW_VEHICLE); } |