From f62fd4a20ee70292739ceb42b5875973c02bb7fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valdis=20Zob=C4=93la?= Date: Mon, 22 Nov 2021 02:35:57 +0200 Subject: [PATCH 1/2] production queue --- game.h | 2 +- monthorders.cpp | 299 ++++++++++++++++++++++++++++++------------------ orders.cpp | 4 + orders.h | 16 ++- parseorders.cpp | 65 ++++++++--- unit.cpp | 2 +- 6 files changed, 257 insertions(+), 131 deletions(-) diff --git a/game.h b/game.h index 43cc1656f..bf62773ca 100644 --- a/game.h +++ b/game.h @@ -564,7 +564,7 @@ class Game int ValidProd(Unit *, ARegion *, Production *); int FindAttemptedProd(ARegion *, Production *); void RunAProduction(ARegion *, Production *); - void RunUnitProduce(ARegion *, Unit *); + int RunUnitProduce(ARegion * r, Unit * u, const ProduceTask &task, const int productionPoints, const int maxProductionPoints, const bool quiet); void Run1BuildOrder(ARegion *, Object *, Unit *); void RunBuildShipOrder(ARegion *, Object *, Unit *); void AddNewBuildings(ARegion *); diff --git a/monthorders.cpp b/monthorders.cpp index 8a58a0d17..a2dc6f6ec 100644 --- a/monthorders.cpp +++ b/monthorders.cpp @@ -1051,101 +1051,123 @@ void Game::RunMonthOrders() } } -void Game::RunUnitProduce(ARegion * r,Unit * u) +int Game::RunUnitProduce(ARegion * r, Unit * u, const ProduceTask &task, const int productionCapacity, const int maxProductionCapacity, const bool quiet) { - Production *p; - ProduceOrder *o = (ProduceOrder *) u->monthorders; - - forlist(&r->products) { - p = (Production *) elem; - // PRODUCE orders for producing goods from the land - // are shared among factions, and therefore handled - // specially by the RunAProduction() function - if (o->skill == p->skill && o->item == p->itemtype) - return; + const Production *p; + const ProduceOrder *o = (ProduceOrder *) u->monthorders; + + if (task.item == -1) { + u->Error("PRODUCE: Can't produce that, item was not specified."); + return 0; } - if (o->item == I_SILVER) { - if (!o->quiet) + const ItemType& item = ItemDefs[task.item]; + + if (task.item == I_SILVER) { + // should not happen + if (!o->quiet) { u->Error("Can't do that in this region."); - delete u->monthorders; - u->monthorders = 0; - return; + } + return 0; } - if (o->item == -1 || ItemDefs[o->item].flags & ItemType::DISABLED) { - u->Error("PRODUCE: Can't produce that."); - delete u->monthorders; - u->monthorders = 0; - return; + if (item.flags & ItemType::DISABLED) { + u->Error("PRODUCE: Can't produce that, item is disabled in this game."); + return 0; } - int input = ItemDefs[o->item].pInput[0].item; + int input = item.pInput[0].item; if (input == -1) { - u->Error("PRODUCE: Can't produce that."); - delete u->monthorders; - u->monthorders = 0; - return; + u->Error("PRODUCE: Can't produce that, item does not have input resources."); + return 0; } - int level = u->GetSkill(o->skill); - if (level < ItemDefs[o->item].pLevel) { - u->Error("PRODUCE: Can't produce that."); - delete u->monthorders; - u->monthorders = 0; - return; + int level = u->GetSkill(task.skill); + if (level < item.pLevel) { + u->Error(AString("PRODUCE: Can't produce that, item requires at least skill of level ") + item.pLevel + ", but unit knows it only on level " + level); + return 0; } - // LLS - int number = u->GetMen() * level + u->GetProductionBonus(o->item); - if (!ActivityCheck(r, u->faction, FactionActivity::TRADE)) { u->Error("PRODUCE: Faction can't produce in that many regions."); - delete u->monthorders; - u->monthorders = 0; - return; + return 0; } + if (productionCapacity == 0) { + u->Event(AString("No more production capacity left for this turn, ") + item.abr + " was not produced."); + + TurnOrder *tOrder = new TurnOrder; + AString order; + tOrder->repeating = 0; + order = "PRODUCE "; + if (task.amount > 0) { + order += task.amount; + order += " "; + } + order += item.abr; + tOrder->turnOrders.Add(new AString(order)); + u->turnorders.Insert(tOrder); + + return 0; + } + + // LLS + int number = u->GetMen() * level + u->GetProductionBonus(task.item); + // find the max we can possibly produce based on man-months of labor - int maxproduced; - if (ItemDefs[o->item].flags & ItemType::SKILLOUT) - maxproduced = u->GetMen(); - else if (ItemDefs[o->item].flags & ItemType::SKILLOUT_HALF) - maxproduced = u->GetMen(); - else - maxproduced = number/ItemDefs[o->item].pMonths; + int maxProduction; + if (item.flags & ItemType::SKILLOUT) { + maxProduction = u->GetMen(); + } + else if (item.flags & ItemType::SKILLOUT_HALF) { + maxProduction = u->GetMen(); + } + else { + maxProduction = number / item.pMonths; + } + + int usedPP = 0; + int availableProduction = (maxProduction * productionCapacity) / maxProductionCapacity; - if (o->target > 0 && maxproduced > o->target) - maxproduced = o->target; + int production = availableProduction; + if (task.amount > 0) { + production = std::min(task.amount, availableProduction); + } - if (ItemDefs[o->item].flags & ItemType::ORINPUTS) { + if (item.flags & ItemType::ORINPUTS) { // Figure out the max we can produce based on the inputs int count = 0; unsigned int c; - for (c = 0; c < sizeof(ItemDefs->pInput)/sizeof(Materials); c++) { - int i = ItemDefs[o->item].pInput[c].item; - if (i != -1) - count += u->GetSharedNum(i) / ItemDefs[o->item].pInput[c].amt; + for (c = 0; c < sizeof(ItemDefs->pInput) / sizeof(Materials); c++) { + int i = item.pInput[c].item; + if (i != -1) { + count += u->GetSharedNum(i) / item.pInput[c].amt; + } } - if (maxproduced > count) - maxproduced = count; - count = maxproduced; - - /* regional economic improvement */ - r->improvement += count; - // Deduct the items spent - for (c = 0; c < sizeof(ItemDefs->pInput)/sizeof(Materials); c++) { - int i = ItemDefs[o->item].pInput[c].item; - int a = ItemDefs[o->item].pInput[c].amt; - if (i != -1) { - int amt = u->GetSharedNum(i); - if (count > amt / a) { - count -= amt / a; - u->ConsumeShared(i, (amt/a)*a); - } else { - u->ConsumeShared(i, count * a); - count = 0; + count = std::min(count, production); + if (count > 0) { + usedPP = (maxProductionCapacity * count) / maxProduction; + if ((maxProductionCapacity * count) % maxProduction) { + usedPP++; + } + + /* regional economic improvement */ + r->improvement += count; + + // Deduct the items spent + for (c = 0; c < sizeof(ItemDefs->pInput) / sizeof(Materials); c++) { + int i = item.pInput[c].item; + int a = item.pInput[c].amt; + if (i != -1) { + int amt = u->GetSharedNum(i); + if (count > amt / a) { + count -= amt / a; + u->ConsumeShared(i, (amt / a) * a); + } else { + u->ConsumeShared(i, count * a); + count = 0; + } } } } @@ -1153,55 +1175,66 @@ void Game::RunUnitProduce(ARegion * r,Unit * u) else { // Figure out the max we can produce based on the inputs unsigned int c; - for (c = 0; c < sizeof(ItemDefs->pInput)/sizeof(Materials); c++) { - int i = ItemDefs[o->item].pInput[c].item; + for (c = 0; c < sizeof(ItemDefs->pInput) / sizeof(Materials); c++) { + int i = item.pInput[c].item; if (i != -1) { int amt = u->GetSharedNum(i); - if (amt/ItemDefs[o->item].pInput[c].amt < maxproduced) { - maxproduced = amt/ItemDefs[o->item].pInput[c].amt; + if (amt / item.pInput[c].amt < production) { + production = amt / item.pInput[c].amt; } } } - - /* regional economic improvement */ - r->improvement += maxproduced; - - // Deduct the items spent - for (c = 0; c < sizeof(ItemDefs->pInput)/sizeof(Materials); c++) { - int i = ItemDefs[o->item].pInput[c].item; - int a = ItemDefs[o->item].pInput[c].amt; - if (i != -1) { - u->ConsumeShared(i, maxproduced*a); + + if (production > 0) { + usedPP = (maxProductionCapacity * production) / maxProduction; + if ((maxProductionCapacity * production) % maxProduction) { + usedPP++; + } + + /* regional economic improvement */ + r->improvement += production; + + // Deduct the items spent + for (c = 0; c < sizeof(ItemDefs->pInput)/sizeof(Materials); c++) { + int i = item.pInput[c].item; + int a = item.pInput[c].amt; + if (i != -1) { + u->ConsumeShared(i, production * a); + } } } } // Now give the items produced - int output = maxproduced * ItemDefs[o->item].pOut; - if (ItemDefs[o->item].flags & ItemType::SKILLOUT) + int output = production * item.pOut; + if (item.flags & ItemType::SKILLOUT) { output *= level; - if (ItemDefs[o->item].flags & ItemType::SKILLOUT_HALF) { + } + else if (item.flags & ItemType::SKILLOUT_HALF) { output *= (level + 1) / 2; } - - u->items.SetNum(o->item,u->items.GetNum(o->item) + output); - u->Event(AString("Produces ") + ItemString(o->item,output) + " in " + - r->ShortPrint(®ions) + "."); - u->Practice(o->skill); - o->target -= output; - if (o->target > 0) { + + u->items.SetNum(task.item, u->items.GetNum(task.item) + output); + u->Event(AString("Produces ") + ItemString(task.item, output) + " in " + r->ShortPrint(®ions) + "."); + + if (productionCapacity == maxProductionCapacity) { + u->Practice(task.skill); + } + + int remainingAmount = task.amount - output; + if (remainingAmount > 0) { TurnOrder *tOrder = new TurnOrder; AString order; tOrder->repeating = 0; order = "PRODUCE "; - order += o->target; + order += remainingAmount; order += " "; - order += ItemDefs[o->item].abr; + order += item.abr; tOrder->turnOrders.Add(new AString(order)); u->turnorders.Insert(tOrder); } - delete u->monthorders; - u->monthorders = 0; + + return usedPP; } void Game::RunProduceOrders(ARegion * r) @@ -1212,12 +1245,58 @@ void Game::RunProduceOrders(ARegion * r) Unit * u = (Unit *) elem; if (u->monthorders) { if (u->monthorders->type == O_PRODUCE) { - RunUnitProduce(r,u); - } else { + ProduceOrder* order = (ProduceOrder *) u->monthorders; + if (order->item != -1) { + // performing WORK or ENTERTAIN + continue; + } + + for (auto &task : order->queue) { + forlist(&r->products) { + Production* p = (Production *) elem; + // PRODUCE orders for producing goods from the land + // are shared among factions, and therefore handled + // specially by the RunAProduction() function + + if (task.skill == p->skill && task.item == p->itemtype) { + order->item = task.item; + order->skill = task.skill; + order->amount = task.amount; + + break; + } + } + + if (order->item != -1) { + break; + } + } + + if (order->item != -1) { + if (order->queue.size() > 1) { + u->Error("Can't mix resource production with other production activities."); + } + + order->queue.clear(); + continue; + } + + const int maxProductionPoints = 100; + int productionPoints = maxProductionPoints; + while (!order->queue.empty()) { + auto task = order->queue.front(); + order->queue.pop_front(); + + int pointsUsed = RunUnitProduce(r, u, task, productionPoints, maxProductionPoints, order->quiet); + productionPoints = std::max(0, productionPoints - pointsUsed); + } + } + else { if (u->monthorders->type == O_BUILD) { if (u->build >= 0) { Run1BuildOrder(r,obj,u); - } else { + } + else { RunBuildShipOrder(r,obj,u); } } @@ -1225,8 +1304,10 @@ void Game::RunProduceOrders(ARegion * r) } } } - forlist_reuse(&r->products) - RunAProduction(r,(Production *) elem); + + forlist_reuse(&r->products) { + RunAProduction(r, (Production *) elem); + } } int Game::ValidProd(Unit * u,ARegion * r, Production * p) @@ -1264,8 +1345,8 @@ int Game::ValidProd(Unit * u,ARegion * r, Production * p) int bonus = u->GetProductionBonus(p->itemtype); /* Factor for fractional productivity: 10 */ po->productivity = (int) ((float) (u->GetMen() * level * p->productivity / 10)) + bonus; - if (po->target > 0 && po->productivity > po->target) - po->productivity = po->target; + if (po->amount > 0 && po->productivity > po->amount) + po->productivity = po->amount; return po->productivity; } return 0; @@ -1295,7 +1376,7 @@ void Game::RunAProduction(ARegion * r, Production * p) if (p->amount == 0) return; /* First, see how many units are trying to work */ - int attempted = FindAttemptedProd(r,p); + int attempted = FindAttemptedProd(r, p); int amt = p->amount; if (attempted < amt) attempted = amt; forlist((&r->objects)) { @@ -1332,13 +1413,13 @@ void Game::RunAProduction(ARegion * r, Production * p) + ubucks); u->faction->DiscoverItem(po->item, 0, 1); p->activity += ubucks; - po->target -= ubucks; - if (po->target > 0) { + po->amount -= ubucks; + if (po->amount > 0) { TurnOrder *tOrder = new TurnOrder; AString order; tOrder->repeating = 0; order = "PRODUCE "; - order += po->target; + order += po->amount; order += " "; order += ItemDefs[po->item].abr; tOrder->turnOrders.Add(new AString(order)); diff --git a/orders.cpp b/orders.cpp index 8823ebc84..0d3085268 100644 --- a/orders.cpp +++ b/orders.cpp @@ -198,6 +198,10 @@ ProduceOrder::~ProduceOrder() { } +void ProduceOrder::Push(const ProduceTask &task) { + this->queue.push_back(task); +} + BuyOrder::BuyOrder() { type = O_BUY; diff --git a/orders.h b/orders.h index 0557be67b..d3dfed93a 100644 --- a/orders.h +++ b/orders.h @@ -25,6 +25,8 @@ #ifndef ORDERS_CLASS #define ORDERS_CLASS +#include + class Order; class AttackOrder; class MoveOrder; @@ -50,6 +52,8 @@ class BankOrder; class IdleOrder; class TransportOrder; +struct ProduceTask; + #include "unit.h" #include "gamedefs.h" #include "astring.h" @@ -209,6 +213,12 @@ class TeachOrder : public Order { AList targets; }; +struct ProduceTask { + int item; + int skill; /* -1 for none */ + int amount; +}; + class ProduceOrder : public Order { public: ProduceOrder(); @@ -217,7 +227,11 @@ class ProduceOrder : public Order { int item; int skill; /* -1 for none */ int productivity; - int target; + int amount; + + void Push(const ProduceTask &task); + + std::list queue; }; class BuyOrder : public Order { diff --git a/parseorders.cpp b/parseorders.cpp index 1365f71b8..f2cb39715 100644 --- a/parseorders.cpp +++ b/parseorders.cpp @@ -949,10 +949,12 @@ void Game::ProcessEntertainOrder(Unit *unit, OrdersCheck *pCheck) ParseError(pCheck, unit, 0, err); if (unit->monthorders) delete unit->monthorders; } + ProduceOrder *o = new ProduceOrder; o->item = I_SILVER; o->skill = S_ENTERTAINMENT; - o->target = 0; + o->amount = 0; + unit->monthorders = o; } @@ -1773,41 +1775,65 @@ void Game::ProcessBuyOrder(Unit *u, AString *o, OrdersCheck *pCheck) void Game::ProcessProduceOrder(Unit *u, AString *o, OrdersCheck *pCheck) { - int target = 0; + int amount = 0; AString *token = o->gettoken(); if (token && token->value() > 0) { - target = token->value(); + amount = token->value(); token = o->gettoken(); } if (!token) { ParseError(pCheck, u, 0, "PRODUCE: No item given."); return; } + int it = ParseEnabledItem(token); delete token; - ProduceOrder *p = new ProduceOrder; - p->item = it; + int skill = -1; if (it != -1) { AString skname = ItemDefs[it].pSkill; - p->skill = LookupSkill(&skname); - } else { - p->skill = -1; + skill = LookupSkill(&skname); } - p->target = target; - if (u->monthorders || - (Globals->TAX_PILLAGE_MONTH_LONG && - ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { - if (u->monthorders) delete u->monthorders; - AString err = "PRODUCE: Overwriting previous "; - if (u->inTurnBlock) err += "DELAYED "; - err += "month-long order."; - ParseError(pCheck, u, 0, err); + + ProduceOrder *p = NULL; + if (u->monthorders && u->monthorders->type == O_PRODUCE) { + // if it is already produce order, we will just add new item to the queue + p = ((ProduceOrder *) u->monthorders)->item == -1 + ? (ProduceOrder *) u->monthorders + : NULL; } + + if (!p) { + // no month order or it is not correct PRODUCE + bool taxLikeActivity = u->taxing == TAX_TAX || u->taxing == TAX_PILLAGE; + if (u->monthorders || (Globals->TAX_PILLAGE_MONTH_LONG && taxLikeActivity)) { + AString err = "PRODUCE: Overwriting previous "; + if (u->inTurnBlock) err += "DELAYED "; + err += "month-long order."; + ParseError(pCheck, u, 0, err); + } + + if (u->monthorders) { + delete u->monthorders; + u->monthorders = NULL; + } + } + + if (!u->monthorders) { + p = new ProduceOrder; + p->item = -1; + u->monthorders = p; + } + + p->Push({ + item: it, + skill: skill, + amount: amount + }); + if (Globals->TAX_PILLAGE_MONTH_LONG) u->taxing = TAX_NONE; - u->monthorders = p; } void Game::ProcessWorkOrder(Unit *u, int quiet, OrdersCheck *pCheck) @@ -1815,7 +1841,8 @@ void Game::ProcessWorkOrder(Unit *u, int quiet, OrdersCheck *pCheck) ProduceOrder *order = new ProduceOrder; order->skill = -1; order->item = I_SILVER; - order->target = 0; + order->amount = 0; + if (quiet) order->quiet = 1; if (u->monthorders || diff --git a/unit.cpp b/unit.cpp index 0b96eca30..fb3826609 100644 --- a/unit.cpp +++ b/unit.cpp @@ -788,7 +788,7 @@ void Unit::DefaultOrders(Object *obj) ProduceOrder *order = new ProduceOrder; order->skill = -1; order->item = I_SILVER; - order->target = 0; + order->amount = 0; order->quiet = 1; monthorders = order; } From 74c3fab26ed017c959d72077a20aa335fe9f5c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valdis=20Zob=C4=93la?= Date: Wed, 2 Mar 2022 01:07:08 +0200 Subject: [PATCH 2/2] changes --- game.h | 3 + monthorders.cpp | 177 +++++++++++++++++++++++++++++++++++++++++++++++- orders.h | 6 ++ 3 files changed, 185 insertions(+), 1 deletion(-) diff --git a/game.h b/game.h index bf62773ca..517f7d01c 100644 --- a/game.h +++ b/game.h @@ -600,6 +600,9 @@ class Game // For faction statistics void CountItems (int **); int CountItem (Faction *, int); + + bool ValidateProductionTask(const ARegion * r, Unit * u, const ProduceTask &task, const bool quiet); + ProductionEstimate EstimateProduction(const ARegion * r, Unit * u, const ProduceTask &task) const; }; #endif diff --git a/monthorders.cpp b/monthorders.cpp index a2dc6f6ec..c48aeb2b1 100644 --- a/monthorders.cpp +++ b/monthorders.cpp @@ -1051,7 +1051,182 @@ void Game::RunMonthOrders() } } -int Game::RunUnitProduce(ARegion * r, Unit * u, const ProduceTask &task, const int productionCapacity, const int maxProductionCapacity, const bool quiet) +bool Game::ValidateProductionTask(const ARegion * r, Unit * u, const ProduceTask &task, const bool quiet) { + if (task.item == -1) { + u->Error("PRODUCE: Can't produce that, item was not specified."); + return false; + } + + const ItemType& item = ItemDefs[task.item]; + + if (task.item == I_SILVER) { + // should not happen + if (!quiet) { + u->Error("Can't do that in this region."); + } + + return false; + } + + if (item.flags & ItemType::DISABLED) { + u->Error("PRODUCE: Can't produce that, item is disabled in this game."); + return false; + } + + int input = item.pInput[0].item; + if (input == -1) { + u->Error("PRODUCE: Can't produce that, item does not have input resources."); + return false; + } + + int level = u->GetSkill(task.skill); + if (level < item.pLevel) { + u->Error(AString("PRODUCE: Can't produce that, item requires at least skill of level ") + item.pLevel + ", but unit knows it only on level " + level); + return false; + } + + if (!ActivityCheck(r, u->faction, FactionActivity::TRADE)) { + u->Error("PRODUCE: Faction can't produce in that many regions."); + return false; + } + + return true; +} + +ProductionEstimate Game::EstimateProduction(const ARegion * r, Unit * u, const ProduceTask &task) const { + const ItemType& item = ItemDefs[task.item]; + const int level = u->GetSkill(task.skill); + const int input = item.pInput[0].item; + + // LLS + int number = u->GetMen() * level + u->GetProductionBonus(task.item); + + // find the max we can possibly produce based on man-months of labor + int maxProduction; + if (item.flags & ItemType::SKILLOUT) { + maxProduction = u->GetMen(); + } + else if (item.flags & ItemType::SKILLOUT_HALF) { + maxProduction = u->GetMen(); + } + else { + maxProduction = number / item.pMonths; + } + + int usedPP = 0; + int availableProduction = (maxProduction * productionCapacity) / maxProductionCapacity; + + int production = availableProduction; + if (task.amount > 0) { + production = std::min(task.amount, availableProduction); + } + + if (item.flags & ItemType::ORINPUTS) { + const int inputCount = sizeof(ItemDefs->pInput) / sizeof(Materials); + + // Figure out the max we can produce based on the inputs + int count = 0; + unsigned int c; + for (c = 0; c < inputCount; c++) { + int i = item.pInput[c].item; + if (i != -1) { + count += u->GetSharedNum(i) / item.pInput[c].amt; + } + } + + count = std::min(count, production); + if (count > 0) { + usedPP = (maxProductionCapacity * count) / maxProduction; + if ((maxProductionCapacity * count) % maxProduction) { + usedPP++; + } + + /* regional economic improvement */ + r->improvement += count; + + // Deduct the items spent + for (c = 0; c < inputCount; c++) { + int i = item.pInput[c].item; + int a = item.pInput[c].amt; + if (i != -1) { + int amt = u->GetSharedNum(i); + if (count > amt / a) { + count -= amt / a; + u->ConsumeShared(i, (amt / a) * a); + } else { + u->ConsumeShared(i, count * a); + count = 0; + } + } + } + } + } + else { + // Figure out the max we can produce based on the inputs + unsigned int c; + for (c = 0; c < sizeof(ItemDefs->pInput) / sizeof(Materials); c++) { + int i = item.pInput[c].item; + if (i != -1) { + int amt = u->GetSharedNum(i); + if (amt / item.pInput[c].amt < production) { + production = amt / item.pInput[c].amt; + } + } + } + + if (production > 0) { + usedPP = (maxProductionCapacity * production) / maxProduction; + if ((maxProductionCapacity * production) % maxProduction) { + usedPP++; + } + + /* regional economic improvement */ + r->improvement += production; + + // Deduct the items spent + for (c = 0; c < sizeof(ItemDefs->pInput)/sizeof(Materials); c++) { + int i = item.pInput[c].item; + int a = item.pInput[c].amt; + if (i != -1) { + u->ConsumeShared(i, production * a); + } + } + } + } + + // Now give the items produced + int output = production * item.pOut; + if (item.flags & ItemType::SKILLOUT) { + output *= level; + } + else if (item.flags & ItemType::SKILLOUT_HALF) { + output *= (level + 1) / 2; + } + + u->items.SetNum(task.item, u->items.GetNum(task.item) + output); + u->Event(AString("Produces ") + ItemString(task.item, output) + " in " + r->ShortPrint(®ions) + "."); + + if (productionCapacity == maxProductionCapacity) { + u->Practice(task.skill); + } + + int remainingAmount = task.amount - output; + if (remainingAmount > 0) { + TurnOrder *tOrder = new TurnOrder; + AString order; + tOrder->repeating = 0; + order = "PRODUCE "; + order += remainingAmount; + order += " "; + order += item.abr; + tOrder->turnOrders.Add(new AString(order)); + u->turnorders.Insert(tOrder); + } + + return usedPP; +} + +int Game::RunUnitProduce(ARegion * r, Unit * u, const ProduceTask &task, const double capacity, const bool quiet) { const Production *p; const ProduceOrder *o = (ProduceOrder *) u->monthorders; diff --git a/orders.h b/orders.h index d3dfed93a..727c86c5f 100644 --- a/orders.h +++ b/orders.h @@ -219,6 +219,12 @@ struct ProduceTask { int amount; }; +struct ProductionEstimate { + int effortUsed; + int effortAvailabel; + int amount; +}; + class ProduceOrder : public Order { public: ProduceOrder();