src/economy.cpp
changeset 7114 665294e21ae8
parent 7112 fcac9e881b43
child 7116 5753c4752490
equal deleted inserted replaced
7113:4b0fd37ee609 7114:665294e21ae8
  1321 	}
  1321 	}
  1322 
  1322 
  1323 	return profit;
  1323 	return profit;
  1324 }
  1324 }
  1325 
  1325 
  1326 /*
       
  1327  * Returns true if Vehicle v should wait loading because other vehicle is
       
  1328  * already loading the same cargo type
       
  1329  * v = vehicle to load, u = GetFirstInChain(v)
       
  1330  */
       
  1331 static bool LoadWait(const Vehicle* v, const Vehicle* u)
       
  1332 {
       
  1333 	const Vehicle *w;
       
  1334 	bool has_any_cargo = false;
       
  1335 
       
  1336 	if (!(u->current_order.flags & OF_FULL_LOAD)) return false;
       
  1337 
       
  1338 	for (w = u; w != NULL; w = w->next) {
       
  1339 		if (w->cargo_count != 0) {
       
  1340 			if (v->cargo_type == w->cargo_type &&
       
  1341 					u->last_station_visited == w->cargo_source) {
       
  1342 				return false;
       
  1343 			}
       
  1344 			has_any_cargo = true;
       
  1345 		}
       
  1346 	}
       
  1347 
       
  1348 	const Station *st = GetStation(u->last_station_visited);
       
  1349 	std::list<Vehicle *>::const_iterator iter;
       
  1350 	for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end(); ++iter) {
       
  1351 		const Vehicle *x = *iter;
       
  1352 		if (!(x->vehstatus & (VS_STOPPED | VS_CRASHED)) && u != x) {
       
  1353 			bool other_has_any_cargo = false;
       
  1354 			bool has_space_for_same_type = false;
       
  1355 			bool other_has_same_type = false;
       
  1356 
       
  1357 			for (w = x; w != NULL; w = w->next) {
       
  1358 				if (w->cargo_count < w->cargo_cap && v->cargo_type == w->cargo_type) {
       
  1359 					has_space_for_same_type = true;
       
  1360 				}
       
  1361 
       
  1362 				if (w->cargo_count != 0) {
       
  1363 					if (v->cargo_type == w->cargo_type &&
       
  1364 							u->last_station_visited == w->cargo_source) {
       
  1365 						other_has_same_type = true;
       
  1366 					}
       
  1367 					other_has_any_cargo = true;
       
  1368 				}
       
  1369 			}
       
  1370 
       
  1371 			if (has_space_for_same_type) {
       
  1372 				if (other_has_same_type) return true;
       
  1373 				if (other_has_any_cargo && !has_any_cargo) return true;
       
  1374 			}
       
  1375 		}
       
  1376 	}
       
  1377 
       
  1378 	return false;
       
  1379 }
       
  1380 
       
  1381 /**
  1326 /**
  1382  * Performs the vehicle payment _and_ marks the vehicle to be unloaded.
  1327  * Performs the vehicle payment _and_ marks the vehicle to be unloaded.
  1383  * @param front_v the vehicle to be unloaded
  1328  * @param front_v the vehicle to be unloaded
  1384  */
  1329  */
  1385 void VehiclePayment(Vehicle *front_v)
  1330 void VehiclePayment(Vehicle *front_v)
  1479 }
  1424 }
  1480 
  1425 
  1481 /**
  1426 /**
  1482  * Loads/unload the vehicle if possible.
  1427  * Loads/unload the vehicle if possible.
  1483  * @param v the vehicle to be (un)loaded
  1428  * @param v the vehicle to be (un)loaded
       
  1429  * @param cargo_left the amount of each cargo type that is
       
  1430  *                   virtually left on the platform to be
       
  1431  *                   picked up by another vehicle when all
       
  1432  *                   previous vehicles have loaded.
  1484  */
  1433  */
  1485 static void LoadUnloadVehicle(Vehicle *v)
  1434 static void LoadUnloadVehicle(Vehicle *v, int *cargo_left)
  1486 {
  1435 {
  1487 	assert(v->current_order.type == OT_LOADING);
  1436 	assert(v->current_order.type == OT_LOADING);
  1488 
  1437 
  1489 	/* We have not waited enough time till the next round of loading/unloading */
  1438 	/* We have not waited enough time till the next round of loading/unloading */
  1490 	if (--v->load_unload_time_rem != 0) return;
  1439 	if (--v->load_unload_time_rem != 0) {
       
  1440 		if (_patches.improved_load && HASBIT(v->current_order.flags, OFB_FULL_LOAD)) {
       
  1441 			/* 'Reserve' this cargo for this vehicle, because we were first. */
       
  1442 			for (; v != NULL; v = v->next) {
       
  1443 				if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo_count;
       
  1444 			}
       
  1445 		}
       
  1446 		return;
       
  1447 	}
  1491 
  1448 
  1492 	int unloading_time = 0;
  1449 	int unloading_time = 0;
  1493 	Vehicle *u = v;
  1450 	Vehicle *u = v;
  1494 	int result = 0;
  1451 	int result = 0;
  1495 	uint cap;
  1452 	uint cap;
  1596 		/* If there's goods waiting at the station, and the vehicle
  1553 		/* If there's goods waiting at the station, and the vehicle
  1597 		 * has capacity for it, load it on the vehicle. */
  1554 		 * has capacity for it, load it on the vehicle. */
  1598 		if (count != 0 &&
  1555 		if (count != 0 &&
  1599 				(cap = v->cargo_cap - v->cargo_count) != 0) {
  1556 				(cap = v->cargo_cap - v->cargo_count) != 0) {
  1600 
  1557 
  1601 			if (v->cargo_count == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
       
  1602 
       
  1603 			/* Skip loading this vehicle if another train/vehicle is already handling
  1558 			/* Skip loading this vehicle if another train/vehicle is already handling
  1604 			 * the same cargo type at this station */
  1559 			 * the same cargo type at this station */
  1605 			if (_patches.improved_load && (u->current_order.flags & OF_FULL_LOAD) && LoadWait(v,u)) {
  1560 			if (_patches.improved_load && cargo_left[v->cargo_type] < 0) {
  1606 				SETBIT(cargo_not_full, v->cargo_type);
  1561 				SETBIT(cargo_not_full, v->cargo_type);
  1607 				continue;
  1562 				continue;
  1608 			}
  1563 			}
       
  1564 
       
  1565 			if (cap > count) cap = count;
       
  1566 			if (_patches.gradual_loading) cap = min(cap, load_amount);
       
  1567 			if (_patches.improved_load) {
       
  1568 				/* Don't load stuff that is already 'reserved' for other vehicles */
       
  1569 				cap = min(cargo_left[v->cargo_type], cap);
       
  1570 				cargo_left[v->cargo_type] -= cap;
       
  1571 			}
       
  1572 
       
  1573 			if (v->cargo_count == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
  1609 
  1574 
  1610 			/* TODO: Regarding this, when we do gradual loading, we
  1575 			/* TODO: Regarding this, when we do gradual loading, we
  1611 			 * should first unload all vehicles and then start
  1576 			 * should first unload all vehicles and then start
  1612 			 * loading them. Since this will cause
  1577 			 * loading them. Since this will cause
  1613 			 * VEHICLE_TRIGGER_EMPTY to be called at the time when
  1578 			 * VEHICLE_TRIGGER_EMPTY to be called at the time when
  1615 			 * completely_empty assignment can then be safely
  1580 			 * completely_empty assignment can then be safely
  1616 			 * removed; that's how TTDPatch behaves too. --pasky */
  1581 			 * removed; that's how TTDPatch behaves too. --pasky */
  1617 			completely_empty = false;
  1582 			completely_empty = false;
  1618 			anything_loaded = true;
  1583 			anything_loaded = true;
  1619 
  1584 
  1620 			if (cap > count) cap = count;
       
  1621 			if (_patches.gradual_loading) cap = min(cap, load_amount);
       
  1622 
       
  1623 			/* cargoshare is proportioned by the amount due to unload
  1585 			/* cargoshare is proportioned by the amount due to unload
  1624 			 * Otherwise, with gradual loading, 100% of credits would be taken immediately,
  1586 			 * Otherwise, with gradual loading, 100% of credits would be taken immediately,
  1625 			 * even if the cargo volume represents a tiny percent of the whole.
  1587 			 * even if the cargo volume represents a tiny percent of the whole.
  1626 			 * ge->unload_pending holds the amount that has been credited, but has not yet been unloaded.
  1588 			 * ge->unload_pending holds the amount that has been credited, but has not yet been unloaded.
  1627 			 */
  1589 			 */
  1647 
  1609 
  1648 		if (v->cargo_count == v->cargo_cap) {
  1610 		if (v->cargo_count == v->cargo_cap) {
  1649 			SETBIT(cargo_full, v->cargo_type);
  1611 			SETBIT(cargo_full, v->cargo_type);
  1650 		} else {
  1612 		} else {
  1651 			SETBIT(cargo_not_full, v->cargo_type);
  1613 			SETBIT(cargo_not_full, v->cargo_type);
       
  1614 		}
       
  1615 	}
       
  1616 
       
  1617 	/* We update these variables here, so gradual loading still fills
       
  1618 	 * all wagons at the same time instead of using the same 'improved'
       
  1619 	 * loading algorithm for the wagons (only fill wagon when there is
       
  1620 	 * enough to fill the previous wagons) */
       
  1621 	if (_patches.improved_load && HASBIT(u->current_order.flags, OFB_FULL_LOAD)) {
       
  1622 		/* Update left cargo */
       
  1623 		for (v = u; v != NULL; v = v->next) {
       
  1624 			if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo_count;
  1652 		}
  1625 		}
  1653 	}
  1626 	}
  1654 
  1627 
  1655 	v = u;
  1628 	v = u;
  1656 
  1629 
  1714  * they entered.
  1687  * they entered.
  1715  * @param st the station to do the loading/unloading for
  1688  * @param st the station to do the loading/unloading for
  1716  */
  1689  */
  1717 void LoadUnloadStation(Station *st)
  1690 void LoadUnloadStation(Station *st)
  1718 {
  1691 {
       
  1692 	int cargo_left[NUM_CARGO];
       
  1693 
       
  1694 	for (uint i = 0; i < NUM_CARGO; i++) cargo_left[i] = GB(st->goods[i].waiting_acceptance, 0, 12);
       
  1695 
  1719 	std::list<Vehicle *>::iterator iter;
  1696 	std::list<Vehicle *>::iterator iter;
  1720 	for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end(); ++iter) {
  1697 	for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end(); ++iter) {
  1721 		Vehicle *v = *iter;
  1698 		Vehicle *v = *iter;
  1722 		if (!(v->vehstatus & (VS_STOPPED | VS_CRASHED))) LoadUnloadVehicle(v);
  1699 		if (!(v->vehstatus & (VS_STOPPED | VS_CRASHED))) LoadUnloadVehicle(v, cargo_left);
  1723 	}
  1700 	}
  1724 }
  1701 }
  1725 
  1702 
  1726 void PlayersMonthlyLoop()
  1703 void PlayersMonthlyLoop()
  1727 {
  1704 {