src/economy.cpp
branchNewGRF_ports
changeset 10184 fcf5fb2548eb
parent 6878 7d1ff2f621c7
child 10192 195d7f6dcf71
equal deleted inserted replaced
10179:eec5a7dcbf61 10184:fcf5fb2548eb
     4 
     4 
     5 #include "stdafx.h"
     5 #include "stdafx.h"
     6 #include "openttd.h"
     6 #include "openttd.h"
     7 #include "currency.h"
     7 #include "currency.h"
     8 #include "landscape.h"
     8 #include "landscape.h"
     9 #include "news.h"
       
    10 #include "player_base.h"
     9 #include "player_base.h"
    11 #include "player_func.h"
    10 #include "player_func.h"
    12 #include "station.h"
       
    13 #include "command_func.h"
    11 #include "command_func.h"
    14 #include "saveload.h"
    12 #include "saveload.h"
    15 #include "industry.h"
    13 #include "industry.h"
    16 #include "town.h"
    14 #include "town.h"
       
    15 #include "news_func.h"
    17 #include "network/network.h"
    16 #include "network/network.h"
    18 #include "engine.h"
       
    19 #include "network/network_data.h"
    17 #include "network/network_data.h"
    20 #include "variables.h"
    18 #include "variables.h"
    21 #include "vehicle_gui.h"
    19 #include "vehicle_gui.h"
    22 #include "ai/ai.h"
    20 #include "ai/ai.h"
    23 #include "train.h"
    21 #include "train.h"
   351 				}
   349 				}
   352 			}
   350 			}
   353 		}
   351 		}
   354 
   352 
   355 		/* Reset the ratings for the old player */
   353 		/* Reset the ratings for the old player */
   356 		t->ratings[old_player] = 500;
   354 		t->ratings[old_player] = RATING_INITIAL;
   357 		ClrBit(t->have_ratings, old_player);
   355 		ClrBit(t->have_ratings, old_player);
   358 	}
   356 	}
   359 
   357 
   360 	{
   358 	{
   361 		int num_train = 0;
   359 		int num_train = 0;
   511 
   509 
   512 	owner = p->index;
   510 	owner = p->index;
   513 
   511 
   514 	switch (p->quarters_of_bankrupcy) {
   512 	switch (p->quarters_of_bankrupcy) {
   515 		case 2:
   513 		case 2:
   516 			AddNewsItem( (StringID)(owner | NB_BTROUBLE),
   514 			AddNewsItem((StringID)(owner | NB_BTROUBLE),
   517 				NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
   515 				NM_CALLBACK, NF_NONE, NT_COMPANY_INFO, DNC_BANKRUPCY, 0, 0);
   518 			break;
   516 			break;
   519 		case 3: {
   517 		case 3: {
   520 			/* XXX - In multiplayer, should we ask other players if it wants to take
   518 			/* XXX - In multiplayer, should we ask other players if it wants to take
   521 		          over when it is a human company? -- TrueLight */
   519 		          over when it is a human company? -- TrueLight */
   522 			if (IsHumanPlayer(owner)) {
   520 			if (IsHumanPlayer(owner)) {
   523 				AddNewsItem( (StringID)(owner | NB_BTROUBLE),
   521 				AddNewsItem((StringID)(owner | NB_BTROUBLE),
   524 					NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
   522 					NM_CALLBACK, NF_NONE, NT_COMPANY_INFO, DNC_BANKRUPCY, 0, 0);
   525 				break;
   523 				break;
   526 			}
   524 			}
   527 
   525 
   528 			/* Check if the company has any value.. if not, declare it bankrupt
   526 			/* Check if the company has any value.. if not, declare it bankrupt
   529 			 *  right now */
   527 			 *  right now */
   540 			/* Close everything the owner has open */
   538 			/* Close everything the owner has open */
   541 			DeletePlayerWindows(owner);
   539 			DeletePlayerWindows(owner);
   542 
   540 
   543 			/* Show bankrupt news */
   541 			/* Show bankrupt news */
   544 			SetDParam(0, p->index);
   542 			SetDParam(0, p->index);
   545 			AddNewsItem( (StringID)(owner | NB_BBANKRUPT), NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
   543 			AddNewsItem((StringID)(owner | NB_BBANKRUPT), NM_CALLBACK, NF_NONE, NT_COMPANY_INFO, DNC_BANKRUPCY, 0, 0);
   546 
   544 
   547 			if (IsHumanPlayer(owner)) {
   545 			if (IsHumanPlayer(owner)) {
   548 				/* XXX - If we are in offline mode, leave the player playing. Eg. there
   546 				/* XXX - If we are in offline mode, leave the player playing. Eg. there
   549 				 * is no THE-END, otherwise mark the player as spectator to make sure
   547 				 * is no THE-END, otherwise mark the player as spectator to make sure
   550 				 * he/she is no long in control of this company */
   548 				 * he/she is no long in control of this company */
   566 				AI_PlayerDied(owner);
   564 				AI_PlayerDied(owner);
   567 		}
   565 		}
   568 	}
   566 	}
   569 }
   567 }
   570 
   568 
   571 void DrawNewsBankrupcy(Window *w)
   569 void DrawNewsBankrupcy(Window *w, const NewsItem *ni)
   572 {
   570 {
   573 	DrawNewsBorder(w);
   571 	DrawNewsBorder(w);
   574 
   572 
   575 	const NewsItem *ni = WP(w, news_d).ni;
       
   576 	Player *p = GetPlayer((PlayerID)GB(ni->string_id, 0, 4));
   573 	Player *p = GetPlayer((PlayerID)GB(ni->string_id, 0, 4));
   577 	DrawPlayerFace(p->face, p->player_color, 2, 23);
   574 	DrawPlayerFace(p->face, p->player_color, 2, 23);
   578 	GfxFillRect(3, 23, 3 + 91, 23 + 118, PALETTE_TO_STRUCT_GREY | (1 << USE_COLORTABLE));
   575 	GfxFillRect(3, 23, 3 + 91, 23 + 118, PALETTE_TO_STRUCT_GREY | (1 << USE_COLORTABLE));
   579 
   576 
   580 	SetDParam(0, p->index);
   577 	SetDParam(0, p->index);
   784 {
   781 {
   785 	if (_opt.diff.economy == 0) return;
   782 	if (_opt.diff.economy == 0) return;
   786 
   783 
   787 	if (--_economy.fluct == 0) {
   784 	if (--_economy.fluct == 0) {
   788 		_economy.fluct = -(int)GB(Random(), 0, 2);
   785 		_economy.fluct = -(int)GB(Random(), 0, 2);
   789 		AddNewsItem(STR_7073_WORLD_RECESSION_FINANCIAL, NEWS_FLAGS(NM_NORMAL,0,NT_ECONOMY,0), 0, 0);
   786 		AddNewsItem(STR_7073_WORLD_RECESSION_FINANCIAL, NM_NORMAL, NF_NONE, NT_ECONOMY, DNC_NONE, 0, 0);
   790 	} else if (_economy.fluct == -12) {
   787 	} else if (_economy.fluct == -12) {
   791 		_economy.fluct = GB(Random(), 0, 8) + 312;
   788 		_economy.fluct = GB(Random(), 0, 8) + 312;
   792 		AddNewsItem(STR_7074_RECESSION_OVER_UPTURN_IN, NEWS_FLAGS(NM_NORMAL,0,NT_ECONOMY,0), 0, 0);
   789 		AddNewsItem(STR_7074_RECESSION_OVER_UPTURN_IN, NM_NORMAL, NF_NONE, NT_ECONOMY, DNC_NONE, 0, 0);
   793 	}
   790 	}
   794 }
   791 }
   795 
   792 
   796 static byte _price_category[NUM_PRICES] = {
   793 static byte _price_category[NUM_PRICES] = {
   797 	0, 2, 2, 2, 2, 2, 2, 2,
   794 	0, 2, 2, 2, 2, 2, 2, 2,
  1127 	for (s = _subsidies; s != endof(_subsidies); s++) {
  1124 	for (s = _subsidies; s != endof(_subsidies); s++) {
  1128 		if (s->cargo_type == CT_INVALID) continue;
  1125 		if (s->cargo_type == CT_INVALID) continue;
  1129 
  1126 
  1130 		if (s->age == 12-1) {
  1127 		if (s->age == 12-1) {
  1131 			pair = SetupSubsidyDecodeParam(s, 1);
  1128 			pair = SetupSubsidyDecodeParam(s, 1);
  1132 			AddNewsItem(STR_202E_OFFER_OF_SUBSIDY_EXPIRED, NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_SUBSIDIES, 0), pair.a, pair.b);
  1129 			AddNewsItem(STR_202E_OFFER_OF_SUBSIDY_EXPIRED, NM_NORMAL, NF_TILE, NT_SUBSIDIES, DNC_NONE, pair.a, pair.b);
  1133 			s->cargo_type = CT_INVALID;
  1130 			s->cargo_type = CT_INVALID;
  1134 			modified = true;
  1131 			modified = true;
  1135 		} else if (s->age == 2*12-1) {
  1132 		} else if (s->age == 2*12-1) {
  1136 			st = GetStation(s->to);
  1133 			st = GetStation(s->to);
  1137 			if (st->owner == _local_player) {
  1134 			if (st->owner == _local_player) {
  1138 				pair = SetupSubsidyDecodeParam(s, 1);
  1135 				pair = SetupSubsidyDecodeParam(s, 1);
  1139 				AddNewsItem(STR_202F_SUBSIDY_WITHDRAWN_SERVICE, NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_SUBSIDIES, 0), pair.a, pair.b);
  1136 				AddNewsItem(STR_202F_SUBSIDY_WITHDRAWN_SERVICE, NM_NORMAL, NF_TILE, NT_SUBSIDIES, DNC_NONE, pair.a, pair.b);
  1140 			}
  1137 			}
  1141 			s->cargo_type = CT_INVALID;
  1138 			s->cargo_type = CT_INVALID;
  1142 			modified = true;
  1139 			modified = true;
  1143 		} else {
  1140 		} else {
  1144 			s->age++;
  1141 			s->age++;
  1173 				}
  1170 				}
  1174 	add_subsidy:
  1171 	add_subsidy:
  1175 				if (!CheckSubsidyDuplicate(s)) {
  1172 				if (!CheckSubsidyDuplicate(s)) {
  1176 					s->age = 0;
  1173 					s->age = 0;
  1177 					pair = SetupSubsidyDecodeParam(s, 0);
  1174 					pair = SetupSubsidyDecodeParam(s, 0);
  1178 					AddNewsItem(STR_2030_SERVICE_SUBSIDY_OFFERED, NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_SUBSIDIES, 0), pair.a, pair.b);
  1175 					AddNewsItem(STR_2030_SERVICE_SUBSIDY_OFFERED, NM_NORMAL, NF_TILE, NT_SUBSIDIES, DNC_NONE, pair.a, pair.b);
  1179 					modified = true;
  1176 					modified = true;
  1180 					break;
  1177 					break;
  1181 				}
  1178 				}
  1182 			}
  1179 			}
  1183 		} while (n--);
  1180 		} while (n--);
  1390 			InjectDParam(1);
  1387 			InjectDParam(1);
  1391 
  1388 
  1392 			SetDParam(0, _current_player);
  1389 			SetDParam(0, _current_player);
  1393 			AddNewsItem(
  1390 			AddNewsItem(
  1394 				STR_2031_SERVICE_SUBSIDY_AWARDED + _opt.diff.subsidy_multiplier,
  1391 				STR_2031_SERVICE_SUBSIDY_AWARDED + _opt.diff.subsidy_multiplier,
  1395 				NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_SUBSIDIES, 0),
  1392 				NM_NORMAL, NF_TILE, NT_SUBSIDIES, DNC_NONE,
  1396 				pair.a, pair.b
  1393 				pair.a, pair.b
  1397 			);
  1394 			);
  1398 
  1395 
  1399 			InvalidateWindow(WC_SUBSIDIES_LIST, 0);
  1396 			InvalidateWindow(WC_SUBSIDIES_LIST, 0);
  1400 			return true;
  1397 			return true;
  1490 		for (CargoList::List::const_iterator it = cargos->begin(); it != cargos->end(); it++) {
  1487 		for (CargoList::List::const_iterator it = cargos->begin(); it != cargos->end(); it++) {
  1491 			CargoPacket *cp = *it;
  1488 			CargoPacket *cp = *it;
  1492 			if (!cp->paid_for &&
  1489 			if (!cp->paid_for &&
  1493 					cp->source != last_visited &&
  1490 					cp->source != last_visited &&
  1494 					HasBit(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE) &&
  1491 					HasBit(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE) &&
  1495 					(front_v->current_order.flags & OFB_TRANSFER) == 0) {
  1492 					(front_v->current_order.GetUnloadType() & OUFB_TRANSFER) == 0) {
  1496 				/* Deliver goods to the station */
  1493 				/* Deliver goods to the station */
  1497 				st->time_since_unload = 0;
  1494 				st->time_since_unload = 0;
  1498 
  1495 
  1499 				/* handle end of route payment */
  1496 				/* handle end of route payment */
  1500 				Money profit = DeliverGoods(cp->count, v->cargo_type, cp->source, last_visited, cp->source_xy, cp->days_in_transit);
  1497 				Money profit = DeliverGoods(cp->count, v->cargo_type, cp->source, last_visited, cp->source_xy, cp->days_in_transit);
  1503 				vehicle_profit += profit - cp->feeder_share;                    // whole vehicle is not payed for transfers picked up earlier
  1500 				vehicle_profit += profit - cp->feeder_share;                    // whole vehicle is not payed for transfers picked up earlier
  1504 
  1501 
  1505 				result |= 1;
  1502 				result |= 1;
  1506 
  1503 
  1507 				SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
  1504 				SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
  1508 			} else if (front_v->current_order.flags & (OFB_UNLOAD | OFB_TRANSFER)) {
  1505 			} else if (front_v->current_order.GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) {
  1509 				if (!cp->paid_for && (front_v->current_order.flags & OFB_TRANSFER) != 0) {
  1506 				if (!cp->paid_for && (front_v->current_order.GetUnloadType() & OUFB_TRANSFER) != 0) {
  1510 					Money profit = GetTransportedGoodsIncome(
  1507 					Money profit = GetTransportedGoodsIncome(
  1511 						cp->count,
  1508 						cp->count,
  1512 						/* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */
  1509 						/* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */
  1513 						DistanceManhattan(cp->loaded_at_xy, GetStation(last_visited)->xy),
  1510 						DistanceManhattan(cp->loaded_at_xy, GetStation(last_visited)->xy),
  1514 						cp->days_in_transit,
  1511 						cp->days_in_transit,
  1553  *                   picked up by another vehicle when all
  1550  *                   picked up by another vehicle when all
  1554  *                   previous vehicles have loaded.
  1551  *                   previous vehicles have loaded.
  1555  */
  1552  */
  1556 static void LoadUnloadVehicle(Vehicle *v, int *cargo_left)
  1553 static void LoadUnloadVehicle(Vehicle *v, int *cargo_left)
  1557 {
  1554 {
  1558 	assert(v->current_order.type == OT_LOADING);
  1555 	assert(v->current_order.IsType(OT_LOADING));
  1559 
  1556 
  1560 	/* We have not waited enough time till the next round of loading/unloading */
  1557 	/* We have not waited enough time till the next round of loading/unloading */
  1561 	if (--v->load_unload_time_rem != 0) {
  1558 	if (--v->load_unload_time_rem != 0) {
  1562 		if (_patches.improved_load && HasBit(v->current_order.flags, OF_FULL_LOAD)) {
  1559 		if (_patches.improved_load && (v->current_order.GetLoadType() & OLFB_FULL_LOAD)) {
  1563 			/* 'Reserve' this cargo for this vehicle, because we were first. */
  1560 			/* 'Reserve' this cargo for this vehicle, because we were first. */
  1564 			for (; v != NULL; v = v->Next()) {
  1561 			for (; v != NULL; v = v->Next()) {
  1565 				if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo.Count();
  1562 				if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo.Count();
  1566 			}
  1563 			}
  1567 		}
  1564 		}
  1605 		if (HasBit(v->vehicle_flags, VF_CARGO_UNLOADING)) {
  1602 		if (HasBit(v->vehicle_flags, VF_CARGO_UNLOADING)) {
  1606 			uint cargo_count = v->cargo.Count();
  1603 			uint cargo_count = v->cargo.Count();
  1607 			uint amount_unloaded = _patches.gradual_loading ? min(cargo_count, load_amount) : cargo_count;
  1604 			uint amount_unloaded = _patches.gradual_loading ? min(cargo_count, load_amount) : cargo_count;
  1608 			bool remaining; // Are there cargo entities in this vehicle that can still be unloaded here?
  1605 			bool remaining; // Are there cargo entities in this vehicle that can still be unloaded here?
  1609 
  1606 
  1610 			if (HasBit(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE) && !(u->current_order.flags & OFB_TRANSFER)) {
  1607 			if (HasBit(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE) && !(u->current_order.GetUnloadType() & OUFB_TRANSFER)) {
  1611 				/* The cargo has reached it's final destination, the packets may now be destroyed */
  1608 				/* The cargo has reached it's final destination, the packets may now be destroyed */
  1612 				remaining = v->cargo.MoveTo(NULL, amount_unloaded, CargoList::MTA_FINAL_DELIVERY, last_visited);
  1609 				remaining = v->cargo.MoveTo(NULL, amount_unloaded, CargoList::MTA_FINAL_DELIVERY, last_visited);
  1613 
  1610 
  1614 				result |= 1;
  1611 				result |= 1;
  1615 			} else if (u->current_order.flags & (OFB_UNLOAD | OFB_TRANSFER)) {
  1612 			} else if (u->current_order.GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) {
  1616 				remaining = v->cargo.MoveTo(&ge->cargo, amount_unloaded);
  1613 				remaining = v->cargo.MoveTo(&ge->cargo, amount_unloaded);
  1617 				SetBit(ge->acceptance_pickup, GoodsEntry::PICKUP);
  1614 				SetBit(ge->acceptance_pickup, GoodsEntry::PICKUP);
  1618 
  1615 
  1619 				result |= 2;
  1616 				result |= 2;
  1620 			} else {
  1617 			} else {
  1639 
  1636 
  1640 			continue;
  1637 			continue;
  1641 		}
  1638 		}
  1642 
  1639 
  1643 		/* Do not pick up goods that we unloaded */
  1640 		/* Do not pick up goods that we unloaded */
  1644 		if (u->current_order.flags & OFB_UNLOAD) continue;
  1641 		if (u->current_order.GetUnloadType() & OUFB_UNLOAD) continue;
  1645 
  1642 
  1646 		/* update stats */
  1643 		/* update stats */
  1647 		int t;
  1644 		int t;
  1648 		switch (u->type) {
  1645 		switch (u->type) {
  1649 			case VEH_TRAIN: t = u->u.rail.cached_max_speed; break;
  1646 			case VEH_TRAIN: t = u->u.rail.cached_max_speed; break;
  1711 
  1708 
  1712 	/* We update these variables here, so gradual loading still fills
  1709 	/* We update these variables here, so gradual loading still fills
  1713 	 * all wagons at the same time instead of using the same 'improved'
  1710 	 * all wagons at the same time instead of using the same 'improved'
  1714 	 * loading algorithm for the wagons (only fill wagon when there is
  1711 	 * loading algorithm for the wagons (only fill wagon when there is
  1715 	 * enough to fill the previous wagons) */
  1712 	 * enough to fill the previous wagons) */
  1716 	if (_patches.improved_load && HasBit(u->current_order.flags, OF_FULL_LOAD)) {
  1713 	if (_patches.improved_load && (u->current_order.GetLoadType() & OLFB_FULL_LOAD)) {
  1717 		/* Update left cargo */
  1714 		/* Update left cargo */
  1718 		for (v = u; v != NULL; v = v->Next()) {
  1715 		for (v = u; v != NULL; v = v->Next()) {
  1719 			if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo.Count();
  1716 			if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo.Count();
  1720 		}
  1717 		}
  1721 	}
  1718 	}
  1730 
  1727 
  1731 			unloading_time = gradual_loading_wait_time[v->type];
  1728 			unloading_time = gradual_loading_wait_time[v->type];
  1732 		}
  1729 		}
  1733 	} else {
  1730 	} else {
  1734 		bool finished_loading = true;
  1731 		bool finished_loading = true;
  1735 		if (HasBit(v->current_order.flags, OF_FULL_LOAD)) {
  1732 		if (v->current_order.GetLoadType() & OLFB_FULL_LOAD) {
  1736 			if (_patches.full_load_any) {
  1733 			if (v->current_order.GetLoadType() == OLF_FULL_LOAD_ANY) {
  1737 				/* if the aircraft carries passengers and is NOT full, then
  1734 				/* if the aircraft carries passengers and is NOT full, then
  1738 				 * continue loading, no matter how much mail is in */
  1735 				 * continue loading, no matter how much mail is in */
  1739 				if ((v->type == VEH_AIRCRAFT && IsCargoInClass(v->cargo_type, CC_PASSENGERS) && v->cargo_cap != v->cargo.Count()) ||
  1736 				if ((v->type == VEH_AIRCRAFT && IsCargoInClass(v->cargo_type, CC_PASSENGERS) && v->cargo_cap != v->cargo.Count()) ||
  1740 						(cargo_not_full && (cargo_full & ~cargo_not_full) == 0)) { // There are stull non-full cargos
  1737 						(cargo_not_full && (cargo_full & ~cargo_not_full) == 0)) { // There are stull non-full cargos
  1741 					finished_loading = false;
  1738 					finished_loading = false;
  1827 	int i;
  1824 	int i;
  1828 	Money value;
  1825 	Money value;
  1829 
  1826 
  1830 	SetDParam(0, p->index);
  1827 	SetDParam(0, p->index);
  1831 	SetDParam(1, p->bankrupt_value);
  1828 	SetDParam(1, p->bankrupt_value);
  1832 	AddNewsItem( (StringID)(_current_player | NB_BMERGER), NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
  1829 	AddNewsItem((StringID)(_current_player | NB_BMERGER), NM_CALLBACK, NF_NONE, NT_COMPANY_INFO, DNC_BANKRUPCY, 0, 0);
  1833 
  1830 
  1834 	/* original code does this a little bit differently */
  1831 	/* original code does this a little bit differently */
  1835 	PlayerID pi = p->index;
  1832 	PlayerID pi = p->index;
  1836 	ChangeNetworkOwner(pi, _current_player);
  1833 	ChangeNetworkOwner(pi, _current_player);
  1837 	ChangeOwnershipOfPlayerItems(pi, _current_player);
  1834 	ChangeOwnershipOfPlayerItems(pi, _current_player);