widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #04361
[Merge] lp:~meitis/widelands/bug861761 into lp:widelands
meitis has proposed merging lp:~meitis/widelands/bug861761 into lp:widelands.
Requested reviews:
Widelands Developers (widelands-dev)
Related bugs:
Bug #861761 in widelands: "Improve production prioritisation"
https://bugs.launchpad.net/widelands/+bug/861761
For more details, see:
https://code.launchpad.net/~meitis/widelands/bug861761/+merge/271710
--
Your team Widelands Developers is requested to review the proposed merge of lp:~meitis/widelands/bug861761 into lp:widelands.
=== modified file 'src/economy/economy.cc'
--- src/economy/economy.cc 2014-11-30 18:49:38 +0000
+++ src/economy/economy.cc 2015-09-18 20:25:43 +0000
@@ -499,27 +499,60 @@
}
+// TODO(meitis): most (all?) production programs execute the condition and on success
+// they sleep before producing the ware. This makes it much more likely for two or more
+// productions sites to start a production though only 1 ware would need to be produced
+// the actually to do would be to change all(?) production programs to sleep after
+// producing the ware, instead before
bool Economy::needs_ware(WareIndex const ware_type) const {
uint32_t const t = ware_target_quantity(ware_type).permanent;
- uint32_t quantity = 0;
- for (const Warehouse * wh : m_warehouses) {
- quantity += wh->get_wares().stock(ware_type);
- if (t <= quantity)
- return false;
+
+ // we have a target quantity set
+ if (t > 0) {
+ uint32_t quantity = 0;
+ for (const Warehouse * wh : m_warehouses) {
+ quantity += wh->get_wares().stock(ware_type);
+ if (t <= quantity)
+ return false;
+ }
+ return true;
+
+ // we have target quantity set to 0, we need to check if there is an open request
+ } else {
+ for (const Request * temp_req : m_requests) {
+ const Request & req = *temp_req;
+
+ if (req.get_type() == wwWARE && req.get_index() == ware_type)
+ return true;
+ }
+ return false;
}
- return true;
}
bool Economy::needs_worker(WareIndex const worker_type) const {
uint32_t const t = worker_target_quantity(worker_type).permanent;
- uint32_t quantity = 0;
- for (const Warehouse * wh : m_warehouses) {
- quantity += wh->get_workers().stock(worker_type);
- if (t <= quantity)
- return false;
+
+ // we have a target quantity set
+ if (t > 0) {
+ uint32_t quantity = 0;
+ for (const Warehouse * wh : m_warehouses) {
+ quantity += wh->get_workers().stock(worker_type);
+ if (t <= quantity)
+ return false;
+ }
+ return true;
+
+ // we have target quantity set to 0, we need to check if there is an open request
+ } else {
+ for (const Request * temp_req : m_requests) {
+ const Request & req = *temp_req;
+
+ if (req.get_type() == wwWORKER && req.get_index() == worker_type)
+ return true;
+ }
+ return false;
}
- return true;
}
@@ -806,11 +839,12 @@
*/
void Economy::_create_requested_worker(Game & game, WareIndex index)
{
- unsigned demand = 0;
+ uint32_t demand = 0;
bool soldier_level_check;
const TribeDescr & tribe = owner().tribe();
const WorkerDescr & w_desc = *tribe.get_worker_descr(index);
+ Request * open_request = nullptr;
// Make a dummy soldier, which should never be assigned to any economy
// Minimal invasive fix of bug 1236538: never create a rookie for a request
@@ -825,8 +859,7 @@
soldier_level_check = false;
}
-
- for (const Request * temp_req : m_requests) {
+ for (Request * temp_req : m_requests) {
const Request & req = *temp_req;
if (req.get_type() != wwWORKER || req.get_index() != index)
@@ -844,7 +877,11 @@
continue;
}
- demand += req.get_open_count();
+ uint32_t current_demand = req.get_open_count();
+ demand += current_demand;
+ if (current_demand > 0) {
+ open_request = temp_req;
+ }
}
if (!demand)
@@ -885,28 +922,46 @@
uint32_t can_create = std::numeric_limits<uint32_t>::max();
uint32_t idx = 0;
uint32_t scarcest_idx = 0;
+ bool planAtLeastOne = false;
for (const std::pair<std::string, uint8_t>& bc : cost) {
uint32_t cc = total_available[idx] / bc.second;
if (cc <= can_create) {
scarcest_idx = idx;
can_create = cc;
}
+
+ // if the target quantity of a resource is set to 0
+ // plan at least one worker, so a request for that resource is triggered
+ WareIndex id_w = tribe.ware_index(bc.first);
+ if (0 == ware_target_quantity(id_w).permanent)
+ planAtLeastOne = true;
idx++;
}
- if (total_planned > can_create) {
+ if (total_planned > can_create && (!planAtLeastOne || total_planned > 1)) {
// Eliminate some excessive plans, to make sure we never request more than
// there are supplies for (otherwise, cyclic transportation might happen)
+ // except in case of planAtLeastOne we continue to plan at least one
// Note that supplies might suddenly disappear outside our control because
// of loss of land or silly player actions.
+ Warehouse * wh_with_plan = nullptr;
for (uint32_t n_wh = 0; n_wh < warehouses().size(); ++n_wh) {
Warehouse * wh = m_warehouses[n_wh];
uint32_t planned = wh->get_planned_workers(game, index);
uint32_t reduce = std::min(planned, total_planned - can_create);
+
+ if (planAtLeastOne && planned > 0) {
+ wh_with_plan = wh;
+ }
wh->plan_workers(game, index, planned - reduce);
total_planned -= reduce;
}
+
+ // in case of planAtLeastOne undo a set to zero
+ if (nullptr != wh_with_plan && 0 == total_planned)
+ wh_with_plan->plan_workers(game, index, 1);
+
} else if (total_planned < demand) {
uint32_t plan_goal = std::min(can_create, demand);
@@ -920,6 +975,16 @@
wh->plan_workers(game, index, plan);
total_planned += plan;
}
+
+ // plan at least one if required and if we haven't done already
+ // we are going to ignore stock policies of all warehouses here completely
+ // the worker we are making is not going to be stocked, there is a request for him
+ if (planAtLeastOne && 0 == total_planned) {
+ Warehouse * wh = find_closest_warehouse(open_request->target_flag());
+ if (nullptr == wh)
+ wh = m_warehouses[0];
+ wh->plan_workers(game, index, 1);
+ }
}
}
=== modified file 'src/wui/transport_ui.cc'
--- src/wui/transport_ui.cc 2014-11-30 18:49:38 +0000
+++ src/wui/transport_ui.cc 2015-09-18 20:25:43 +0000
@@ -157,7 +157,7 @@
if (m_display.ware_selected(id)) {
const Economy::TargetQuantity & tq =
m_economy.ware_target_quantity(id);
- if (1 < tq.permanent) {
+ if (0 < tq.permanent) {
Widelands::Player & player = m_economy.owner();
Game & game = dynamic_cast<Game&>(player.egbase());
game.send_player_command
Follow ups