Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Imperial Stockpile #1607

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
414 changes: 213 additions & 201 deletions Empire/Empire.cpp

Large diffs are not rendered by default.

27 changes: 22 additions & 5 deletions Empire/Empire.h
Expand Up @@ -151,15 +151,18 @@ struct FO_COMMON_API ProductionQueue {

Element(ProductionItem item_, int empire_id_,
int ordered_, int remaining_, int blocksize_,
int location_, bool paused_ = false);
int location_, bool paused_ = false,
bool allowed_imperial_stockpile_use_ = false);

Element(BuildType build_type, std::string name, int empire_id_,
int ordered_, int remaining_, int blocksize_,
int location_, bool paused_ = false);
int location_, bool paused_ = false,
bool allowed_imperial_stockpile_use_ = false);

Element(BuildType build_type, int design_id, int empire_id_,
int ordered_, int remaining_, int blocksize_,
int location_, bool paused_ = false);
int location_, bool paused_ = false,
bool allowed_imperial_stockpile_use_ = false);

ProductionItem item;
int empire_id = ALL_EMPIRES;
Expand All @@ -175,6 +178,7 @@ struct FO_COMMON_API ProductionQueue {
int turns_left_to_completion = -1;
int rally_point_id = INVALID_OBJECT_ID;
bool paused = false;
bool allowed_imperial_stockpile_use = false;

std::string Dump() const;

Expand All @@ -201,14 +205,24 @@ struct FO_COMMON_API ProductionQueue {
int EmpireID() const { return m_empire_id; }

/** Returns map from sets of object ids that can share resources to amount
* of PP available in those groups of objects */
* of PP available in those groups of objects ; does not include stockpile */
std::map<std::set<int>, float> AvailablePP(const std::shared_ptr<ResourcePool>& industry_pool) const;

/** Returns map from sets of object ids that can share resources to amount
* of PP allocated to production queue elements that have build locations
* in systems in the group. */
const std::map<std::set<int>, float>& AllocatedPP() const;


/** Returns map from sets of object ids that can share resources to amount
* of stockpile PP allocated to production queue elements that have build locations
* in systems in the group. */
const std::map<std::set<int>, float>& AllocatedStockpilePP() const;

/** Returns the value expected for the Imperial Stockpile for the next turn, based on the current
* ProductionQueue allocations. */
float ExpectedNewStockpileAmount() const {return m_expected_new_stockpile_amount; }

/** Returns sets of object ids that have more available than allocated PP */
std::set<std::set<int>> ObjectsWithWastedPP(const std::shared_ptr<ResourcePool>& industry_pool) const;

Expand Down Expand Up @@ -249,6 +263,8 @@ struct FO_COMMON_API ProductionQueue {
QueueType m_queue;
int m_projects_in_progress;
std::map<std::set<int>, float> m_object_group_allocated_pp;
std::map<std::set<int>, float> m_object_group_allocated_stockpile_pp;
float m_expected_new_stockpile_amount;
int m_empire_id;

friend class boost::serialization::access;
Expand Down Expand Up @@ -382,7 +398,7 @@ class FO_COMMON_API Empire {
SitRepItr SitRepBegin() const; ///< starting iterator for sitrep entries for this empire
SitRepItr SitRepEnd() const; ///< end iterator for sitreps

float ProductionPoints() const; ///< Returns the number of production points available to the empire (this is available industry)
float ProductionPoints() const; ///< Returns the empire's current production point output (this is available industry not including stockpile)

/** Returns ResourcePool for \a resource_type or 0 if no such ResourcePool
exists. */
Expand Down Expand Up @@ -444,6 +460,7 @@ class FO_COMMON_API Empire {
void RemoveProductionFromQueue(int index); ///< Removes the produce at position \a index in the production queue, if such an index exists.
void PauseProduction(int index);
void ResumeProduction(int index);
void AllowUseImperialPP(int index, bool allow=true); ///< Allows or disallows the use of the imperial stockpile for production

void AddTech(const std::string& name); ///< Inserts the given Tech into the Empire's list of available technologies.
void UnlockItem(const ItemSpec& item); ///< Adds a given producible item (Building, Ship Hull, Ship part) to the list of available items.
Expand Down
4 changes: 3 additions & 1 deletion Empire/ResourcePool.cpp
Expand Up @@ -28,13 +28,15 @@ int ResourcePool::StockpileObjectID() const
float ResourcePool::Stockpile() const
{ return m_stockpile; }

float ResourcePool::Output() const {
float ResourcePool::TotalOutput() const {
float retval = 0.0f;
for (const std::map<std::set<int>, float>::value_type& entry : m_connected_object_groups_resource_output)
{ retval += entry.second; }
return retval;
}

std::map<std::set<int>, float> ResourcePool::Output() const { return m_connected_object_groups_resource_output; }

float ResourcePool::GroupOutput(int object_id) const {
// find group containing specified object
for (const std::map<std::set<int>, float>::value_type& entry : m_connected_object_groups_resource_output)
Expand Down
11 changes: 8 additions & 3 deletions Empire/ResourcePool.h
Expand Up @@ -29,14 +29,19 @@ class FO_COMMON_API ResourcePool {
int StockpileObjectID() const; ///< returns ID of object that contains this ResourcePool's stockpile

float Stockpile() const; ///< returns current stockpiled amount of resource
float Output() const; ///< returns amount of resource being generated by all ResourceCenters

float TotalOutput() const; ///< returns amount of resource being generated by all ResourceCenters
std::map<std::set<int>, float> Output() const; ///< returns the sets of groups of objects that can share resources, and the amount of this pool's resource that each group is generating this turn
float GroupOutput(int object_id) const; ///< returns amount of resource being generated by resource sharing group that contains the object with id \a object_id

float TargetOutput() const;
float GroupTargetOutput(int object_id) const;

float TotalAvailable() const; ///< returns amount of resource immediately available = production + stockpile from all ResourceCenters, ignoring limitations of connections between centers
std::map<std::set<int>, float> Available() const; ///< returns the sets of groups of objects that can share resources, and the amount of this pool's resource that each group has available
float TotalAvailable() const; ///< returns amount of resource immediately available = output + stockpile from all ResourceCenters, ignoring limitations of connections between centers
/** returns the sets of groups of objects that can share resources, and the amount of this pool's resource that each group has available
* (includes stockpile for the group containing the stockpile object, regardless of whether other game meachanics may impose penalty on
* use of such stockpile) */
std::map<std::set<int>, float> Available() const;
float GroupAvailable(int object_id) const; ///< returns amount of resource available in resource sharing group that contains the object with id \a object_id

std::string Dump() const;
Expand Down
14 changes: 10 additions & 4 deletions UI/MapWnd.cpp
Expand Up @@ -55,6 +55,8 @@
#include <boost/graph/graph_concepts.hpp>
#include <boost/unordered_map.hpp>
#include <boost/optional/optional.hpp>
#include <boost/range/numeric.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/locale.hpp>

#include <GG/DrawUtil.h>
Expand Down Expand Up @@ -3420,7 +3422,7 @@ namespace {

const ProductionQueue& queue = empire->GetProductionQueue();
const std::map<std::set<int>, float>& allocated_pp(queue.AllocatedPP());
const std::map<std::set<int>, float> available_pp(empire->GetResourcePool(RE_INDUSTRY)->Available());
const std::map<std::set<int>, float> available_pp(empire->GetResourcePool(RE_INDUSTRY)->Output());

// For each industry set,
// add all planet's systems to res_pool_systems[industry set]
Expand Down Expand Up @@ -6332,7 +6334,7 @@ void MapWnd::RefreshResearchResourceIndicator() {
m_research->SetBrowseModeTime(GetOptionsDB().Get<int>("UI.tooltip-delay"));

double total_RP_spent = empire->GetResearchQueue().TotalRPsSpent();
double total_RP_output = empire->GetResourcePool(RE_RESEARCH)->Output();
double total_RP_output = empire->GetResourcePool(RE_RESEARCH)->TotalOutput();
double total_RP_wasted = total_RP_output - total_RP_spent;
double total_RP_target_output = empire->GetResourcePool(RE_RESEARCH)->TargetOutput();

Expand Down Expand Up @@ -6380,13 +6382,17 @@ void MapWnd::RefreshIndustryResourceIndicator() {
m_industry->SetBrowseModeTime(GetOptionsDB().Get<int>("UI.tooltip-delay"));

double total_PP_spent = empire->GetProductionQueue().TotalPPsSpent();
double total_PP_output = empire->GetResourcePool(RE_INDUSTRY)->Output();
double total_PP_output = empire->GetResourcePool(RE_INDUSTRY)->TotalOutput();
double total_PP_wasted = total_PP_output - total_PP_spent;
double total_PP_target_output = empire->GetResourcePool(RE_INDUSTRY)->TargetOutput();
float stockpile = empire->GetResourcePool(RE_INDUSTRY)->Stockpile();
float stockpile_used = boost::accumulate(empire->GetProductionQueue().AllocatedStockpilePP() | boost::adaptors::map_values, 0.0f);
float expected_stockpile = empire->GetProductionQueue().ExpectedNewStockpileAmount();

m_industry->SetBrowseInfoWnd(GG::Wnd::Create<ResourceBrowseWnd>(
UserString("MAP_PRODUCTION_TITLE"), UserString("PRODUCTION_INFO_PP"),
total_PP_spent, total_PP_output, total_PP_target_output));
total_PP_spent, total_PP_output, total_PP_target_output,
true, stockpile, stockpile_used, expected_stockpile));

if (total_PP_wasted > 0.05) {
DebugLogger() << "MapWnd::RefreshIndustryResourceIndicator: Showing Industry Wasted Icon with Industry spent: "
Expand Down
28 changes: 28 additions & 0 deletions UI/ProductionWnd.cpp
Expand Up @@ -309,6 +309,9 @@ namespace {
% DoubleToString(total_cost, 3, false)
% DoubleToString(allocation, 3, false)
% DoubleToString(max_allocation, 3, false)) + "\n";

if (elem.allowed_imperial_stockpile_use)
main_text += UserString("PRODUCTION_QUEUE_ITEM_STOCKPILE_ENABLED") + "\n";

int ETA = elem.turns_left_to_completion;
if (ETA != -1)
Expand Down Expand Up @@ -661,6 +664,7 @@ namespace {
boost::signals2::signal<void (GG::ListBox::iterator, bool)> QueueItemPausedSignal;
boost::signals2::signal<void (GG::ListBox::iterator)> QueueItemDupedSignal;
boost::signals2::signal<void (GG::ListBox::iterator)> QueueItemSplitSignal;
boost::signals2::signal<void (GG::ListBox::iterator, bool)> QueueItemUseImperialPPSignal;

protected:
void ItemRightClickedImpl(GG::ListBox::iterator it, const GG::Pt& pt, const GG::Flags<GG::ModKey>& modkeys) override {
Expand All @@ -673,6 +677,8 @@ namespace {
};
auto resume_action = [&it, this]() { this->QueueItemPausedSignal(it, false); };
auto pause_action = [&it, this]() { this->QueueItemPausedSignal(it, true); };
auto disallow_stockpile_action = [&it, this]() { this->QueueItemUseImperialPPSignal(it, false); };
auto allow_stockpile_action = [&it, this]() { this->QueueItemUseImperialPPSignal(it, true); };

auto dupe_action = [&it, this]() { this->QueueItemDupedSignal(it); };
auto split_action = [&it, this]() { this->QueueItemSplitSignal(it); };
Expand Down Expand Up @@ -716,6 +722,11 @@ namespace {
popup->AddMenuItem(GG::MenuItem(UserString("PAUSE"), false, false, pause_action));
}

if (queue_row && queue_row->elem.allowed_imperial_stockpile_use) {
popup->AddMenuItem(GG::MenuItem(UserString("DISALLOW_IMPERIAL_PP_STOCKPILE_USE"), false, false, disallow_stockpile_action));
} else {
popup->AddMenuItem(GG::MenuItem(UserString("ALLOW_IMPERIAL_PP_STOCKPILE_USE"), false, false, allow_stockpile_action));
}
// pedia lookup
std::string item_name = "";
if (build_type == BT_BUILDING) {
Expand Down Expand Up @@ -845,6 +856,8 @@ void ProductionWnd::CompleteConstruction() {
boost::bind(&ProductionWnd::ShowPedia, this));
m_queue_wnd->GetQueueListBox()->QueueItemPausedSignal.connect(
boost::bind(&ProductionWnd::QueueItemPaused, this, _1, _2));
m_queue_wnd->GetQueueListBox()->QueueItemUseImperialPPSignal.connect(
boost::bind(&ProductionWnd::QueueItemUseImperialPP, this, _1, _2));

AttachChild(m_production_info_panel);
AttachChild(m_queue_wnd);
Expand Down Expand Up @@ -1243,6 +1256,21 @@ void ProductionWnd::QueueItemSplit(GG::ListBox::iterator it) {
empire->UpdateProductionQueue();
}

void ProductionWnd::QueueItemUseImperialPP(GG::ListBox::iterator it, bool allow) {
if (!m_order_issuing_enabled)
return;
int client_empire_id = HumanClientApp::GetApp()->EmpireID();
Empire* empire = GetEmpire(client_empire_id);
if (!empire)
return;

HumanClientApp::GetApp()->Orders().IssueOrder(
OrderPtr(new ProductionQueueOrder(client_empire_id, std::distance(m_queue_wnd->GetQueueListBox()->begin(), it),
allow, -1.0f, -1.0f)));

empire->UpdateProductionQueue();
}

void ProductionWnd::EnableOrderIssuing(bool enable/* = true*/) {
m_order_issuing_enabled = enable;
m_queue_wnd->GetQueueListBox()->EnableOrderIssuing(m_order_issuing_enabled);
Expand Down
1 change: 1 addition & 0 deletions UI/ProductionWnd.h
Expand Up @@ -129,6 +129,7 @@ class ProductionWnd : public GG::Wnd {
void QueueItemPaused(GG::ListBox::iterator it, bool pause);
void QueueItemDuped(GG::ListBox::iterator it);
void QueueItemSplit(GG::ListBox::iterator it);
void QueueItemUseImperialPP(GG::ListBox::iterator it, bool allow);

ProductionInfoPanel* m_production_info_panel;
ProductionQueueWnd* m_queue_wnd;
Expand Down
60 changes: 59 additions & 1 deletion UI/ResourceBrowseWnd.cpp
Expand Up @@ -13,7 +13,9 @@ namespace {


ResourceBrowseWnd::ResourceBrowseWnd(const std::string& title_text, const std::string& unit_label,
float used, float output, float target_output) :
float used, float output, float target_output, bool show_stockpile /*=false*/,
float stockpile /*=0.0f*/, float stockpile_use /*=0.0f*/,
float stockpile_change /*=0.0f*/):
GG::BrowseInfoWnd(GG::X0, GG::Y0, BrowseTextWidth(), GG::Y1),
m_title_text(GG::Wnd::Create<CUILabel>(title_text, GG::FORMAT_CENTER)),
m_used_points_label(GG::Wnd::Create<CUILabel>(UserString("RESOURCE_TT_USED"), GG::FORMAT_RIGHT)),
Expand All @@ -25,6 +27,16 @@ ResourceBrowseWnd::ResourceBrowseWnd(const std::string& title_text, const std::s
m_target_points_label(GG::Wnd::Create<CUILabel>(UserString("RESOURCE_TT_TARGET_OUTPUT"), GG::FORMAT_RIGHT)),
m_target_points(GG::Wnd::Create<CUILabel>(DoubleToString(target_output, 3, false), GG::FORMAT_LEFT)),
m_target_points_P_label(GG::Wnd::Create<CUILabel>(unit_label, GG::FORMAT_LEFT)),
m_show_stockpile(show_stockpile),
m_stockpile_points_label(GG::Wnd::Create<CUILabel>(UserString("STOCKPILE_LABEL"), GG::FORMAT_RIGHT)),
m_stockpile_points(GG::Wnd::Create<CUILabel>(DoubleToString(stockpile, 3, false), GG::FORMAT_LEFT)),
m_stockpile_points_P_label(GG::Wnd::Create<CUILabel>(unit_label, GG::FORMAT_LEFT)),
m_stockpile_used_points_label(GG::Wnd::Create<CUILabel>(UserString("STOCKPILE_USE_LABEL"), GG::FORMAT_RIGHT)),
m_stockpile_used_points(GG::Wnd::Create<CUILabel>(DoubleToString(stockpile_use, 3, false), GG::FORMAT_LEFT)),
m_stockpile_used_points_P_label(GG::Wnd::Create<CUILabel>(unit_label, GG::FORMAT_LEFT)),
m_stockpile_change_points_label(GG::Wnd::Create<CUILabel>(UserString("STOCKPILE_CHANGE_LABEL"), GG::FORMAT_RIGHT)),
m_stockpile_change_points(GG::Wnd::Create<CUILabel>(DoubleToString(stockpile_change, 3, false), GG::FORMAT_LEFT)),
m_stockpile_change_points_P_label(GG::Wnd::Create<CUILabel>(unit_label, GG::FORMAT_LEFT)),
m_offset(GG::X0, ICON_BROWSE_ICON_HEIGHT/2)
{}

Expand Down Expand Up @@ -94,6 +106,52 @@ void ResourceBrowseWnd::CompleteConstruction() {
m_target_points_P_label->Resize(P_LABEL_SIZE);
top_left.y += m_target_points_label->Height();

AttachChild(m_stockpile_points_label);
AttachChild(m_stockpile_points);
AttachChild(m_stockpile_points_P_label);
AttachChild(m_stockpile_used_points_label);
AttachChild(m_stockpile_used_points);
AttachChild(m_stockpile_used_points_P_label);
AttachChild(m_stockpile_change_points_label);
AttachChild(m_stockpile_change_points);
AttachChild(m_stockpile_change_points_P_label);

if (m_show_stockpile) {
m_stockpile_points_label->MoveTo(GG::Pt(top_left.x + LEFT_TEXT_X, top_left.y));
m_stockpile_points_label->Resize(LABEL_TEXT_SIZE);
m_stockpile_points->MoveTo(GG::Pt(top_left.x + RIGHT_TEXT_X, top_left.y));
m_stockpile_points->Resize(VALUE_TEXT_SIZE);
m_stockpile_points_P_label->MoveTo(GG::Pt(top_left.x + P_LABEL_X, top_left.y));
m_stockpile_points_P_label->Resize(P_LABEL_SIZE);
top_left.y += m_stockpile_points_label->Height();

m_stockpile_used_points_label->MoveTo(GG::Pt(top_left.x + LEFT_TEXT_X, top_left.y));
m_stockpile_used_points_label->Resize(LABEL_TEXT_SIZE);
m_stockpile_used_points->MoveTo(GG::Pt(top_left.x + RIGHT_TEXT_X, top_left.y));
m_stockpile_used_points->Resize(VALUE_TEXT_SIZE);
m_stockpile_used_points_P_label->MoveTo(GG::Pt(top_left.x + P_LABEL_X, top_left.y));
m_stockpile_used_points_P_label->Resize(P_LABEL_SIZE);
top_left.y += m_stockpile_used_points_label->Height();

m_stockpile_change_points_label->MoveTo(GG::Pt(top_left.x + LEFT_TEXT_X, top_left.y));
m_stockpile_change_points_label->Resize(LABEL_TEXT_SIZE);
m_stockpile_change_points->MoveTo(GG::Pt(top_left.x + RIGHT_TEXT_X, top_left.y));
m_stockpile_change_points->Resize(VALUE_TEXT_SIZE);
m_stockpile_change_points_P_label->MoveTo(GG::Pt(top_left.x + P_LABEL_X, top_left.y));
m_stockpile_change_points_P_label->Resize(P_LABEL_SIZE);
top_left.y += m_stockpile_change_points_label->Height();
} else {
m_stockpile_points_label->Hide();
m_stockpile_points->Hide();
m_stockpile_points_P_label->Hide();
m_stockpile_used_points_label->Hide();
m_stockpile_used_points->Hide();
m_stockpile_used_points_P_label->Hide();
m_stockpile_change_points_label->Hide();
m_stockpile_change_points->Hide();
m_stockpile_change_points_P_label->Hide();
}

// background / border rendering prep
Resize(GG::Pt(BrowseTextWidth(), top_left.y + EDGE_PAD - m_offset.y));

Expand Down