widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #00830
[Merge] lp:~gamag/widelands/building_costs_preview into lp:widelands
Gabriel Margiani has proposed merging lp:~gamag/widelands/building_costs_preview into lp:widelands.
Requested reviews:
Widelands Developers (widelands-dev)
Related bugs:
Bug #740401 in widelands: "Preview required building costs before building or upgrading"
https://bugs.launchpad.net/widelands/+bug/740401
For more details, see:
https://code.launchpad.net/~gamag/widelands/building_costs_preview/+merge/111946
Adds the building costs preview as discussed in http://wl.widelands.org/forum/topic/601/
(it resizes the window always)
in the same way a preview of the enhance costs and the the wares you get back by dismantling
the building is added to the building window.
(this wasn't discussed, so lets do it now)
--
https://code.launchpad.net/~gamag/widelands/building_costs_preview/+merge/111946
Your team Widelands Developers is requested to review the proposed merge of lp:~gamag/widelands/building_costs_preview into lp:widelands.
=== modified file 'src/logic/dismantlesite.cc'
--- src/logic/dismantlesite.cc 2011-11-30 21:38:37 +0000
+++ src/logic/dismantlesite.cc 2012-06-25 21:55:27 +0000
@@ -104,16 +104,39 @@
{
Partially_Finished_Building::init(egbase);
- Tribe_Descr const & t = tribe();
- Building_Descr const * bd = m_building;
+ std::map<Ware_Index, uint8_t> wares;
+ count_returned_wares(*m_building, wares);
+
+ std::map<Ware_Index, uint8_t>::const_iterator it = wares.begin();
+ m_wares.resize(wares.size());
+
+ for (size_t i = 0; i < wares.size(); ++i, ++it) {
+ WaresQueue & wq =
+ *(m_wares[i] = new WaresQueue(*this, it->first, it->second));
+
+ wq.set_filled(it->second);
+ m_work_steps += it->second;
+ }
+}
+
+/*
+===============
+Count wich wares you get back if you dismantle the given building
+===============
+*/
+void DismantleSite::count_returned_wares
+ (const Widelands::Building_Descr & building,
+ std::map<Ware_Index, uint8_t> & res)
+{
+ Tribe_Descr const & t = building.tribe();
+ Building_Descr const * bd = &building;
Building_Index bd_idx = t.building_index(bd->name());
- std::map<Ware_Index, uint8_t> all_costs;
bool done = false;
while (not done) {
std::map<Ware_Index, uint8_t> const & buildcost = bd->buildcost();
for (std::map<Ware_Index, uint8_t>::const_iterator i = buildcost.begin(); i != buildcost.end(); ++i)
- all_costs[i->first] += i->second;
+ res[i->first] += i->second;
// Find the (first) predecessor of this building
for (Building_Index i = Building_Index::First(); i < t.get_nrbuildings(); ++i) {
@@ -128,17 +151,8 @@
}
}
- std::map<Ware_Index, uint8_t>::const_iterator it = all_costs.begin();
-
- m_wares.resize(all_costs.size());
-
- for (size_t i = 0; i < all_costs.size(); ++i, ++it) {
- uint8_t nwares = (it->second + RATIO_RETURNED_WARES - 1) / RATIO_RETURNED_WARES;
- WaresQueue & wq =
- *(m_wares[i] = new WaresQueue(*this, it->first, nwares));
-
- wq.set_filled(nwares);
- m_work_steps += nwares;
+ for (std::map<Ware_Index, uint8_t>::iterator it = res.begin(); it != res.end(); ++it) {
+ it->second = (it->second + RATIO_RETURNED_WARES - 1) / RATIO_RETURNED_WARES;
}
}
=== modified file 'src/logic/dismantlesite.h'
--- src/logic/dismantlesite.h 2011-11-30 21:38:37 +0000
+++ src/logic/dismantlesite.h 2012-06-25 21:55:27 +0000
@@ -73,6 +73,8 @@
virtual bool get_building_work(Game &, Worker &, bool success);
+ static void count_returned_wares(const Building_Descr & building, std::map<Ware_Index, uint8_t> & res);
+
protected:
virtual uint32_t build_step_time() const {return DISMANTLESITE_STEP_TIME;}
=== modified file 'src/ui_basic/button.cc'
--- src/ui_basic/button.cc 2012-02-15 21:25:34 +0000
+++ src/ui_basic/button.cc 2012-06-25 21:55:27 +0000
@@ -288,6 +288,11 @@
if (oldhl == m_highlighted)
return;
+ if (m_highlighted)
+ sigmousein();
+ else
+ sigmouseout();
+
update();
}
=== modified file 'src/ui_basic/button.h'
--- src/ui_basic/button.h 2012-02-15 21:25:34 +0000
+++ src/ui_basic/button.h 2012-06-25 21:55:27 +0000
@@ -87,6 +87,8 @@
void set_draw_flat_background(bool set);
boost::signal<void ()> sigclicked;
+ boost::signal<void ()> sigmousein;
+ boost::signal<void ()> sigmouseout;
protected:
virtual void clicked() {} /// Override this to react on the click.
=== modified file 'src/wui/buildingwindow.cc'
--- src/wui/buildingwindow.cc 2012-02-20 15:54:26 +0000
+++ src/wui/buildingwindow.cc 2012-06-25 21:55:27 +0000
@@ -27,6 +27,7 @@
#include "logic/player.h"
#include "logic/productionsite.h"
#include "logic/tribe.h"
+#include "logic/dismantlesite.h"
#include "ui_basic/tabpanel.h"
#include "upcast.h"
#include "waresqueuedisplay.h"
@@ -71,6 +72,17 @@
// actually create buttons on the first call to think(),
// so that overriding create_capsbuttons() works
+ UI::Box * prevbox = new UI::Box(vbox, 0, 0, UI::Box::Vertical);
+
+ m_prevtext = new UI::Textarea(prevbox);
+ m_prevtext->set_desired_size(0, 0);
+ prevbox->add(m_prevtext, UI::Box::AlignLeft);
+
+ m_enhancecostPrev = new WaresMapDisplay(prevbox, 0, 0, 10, m_building.tribe(), NULL);
+ prevbox->add(m_enhancecostPrev, UI::Box::AlignLeft);
+
+ vbox->add(prevbox, UI::Box::AlignLeft);
+
set_center_panel(vbox);
set_think(true);
@@ -194,13 +206,22 @@
new UI::Button
(capsbuttons, "enhance", 0, 0, 34, 34,
g_gr->get_picture(PicMod_UI, "pics/but4.png"),
- building_descr.get_buildicon(), // button id = building id)
- buffer);
+ building_descr.get_buildicon()); // button id = building id)
enhancebtn->sigclicked.connect
(boost::bind
(&Building_Window::act_enhance,
boost::ref(*this),
boost::ref(*i.current)));
+ enhancebtn->sigmousein.connect
+ (boost::bind
+ (&Building_Window::show_costPrev,
+ boost::ref(*this),
+ boost::ref
+ (*reinterpret_cast<WaresMapDisplay::maptype const *>
+ (&building_descr.buildcost())),
+ std::string(buffer)));
+ enhancebtn->sigmouseout.connect
+ (boost::bind(&Building_Window::hide_costPrev, boost::ref(*this)));
capsbuttons->add
(enhancebtn,
UI::Box::AlignCenter);
@@ -222,13 +243,22 @@
}
if (m_capscache & Widelands::Building::PCap_Dismantle) {
+ WaresMapDisplay::maptype wares;
+ Widelands::DismantleSite::count_returned_wares(m_building.descr(), wares);
UI::Button * dismantlebtn =
new UI::Button
(capsbuttons, "dismantle", 0, 0, 34, 34,
g_gr->get_picture(PicMod_UI, "pics/but4.png"),
- g_gr->get_picture(PicMod_Game, pic_dismantle),
- _("Dismantle"));
+ g_gr->get_picture(PicMod_Game, pic_dismantle));
dismantlebtn->sigclicked.connect(boost::bind(&Building_Window::act_dismantle, boost::ref(*this)));
+ dismantlebtn->sigmousein.connect
+ (boost::bind
+ (&Building_Window::show_costPrev,
+ boost::ref(*this),
+ wares,
+ _("Dismantle")));
+ dismantlebtn->sigmouseout.connect
+ (boost::bind(&Building_Window::hide_costPrev, boost::ref(*this)));
capsbuttons->add
(dismantlebtn,
UI::Box::AlignCenter);
@@ -361,6 +391,29 @@
igbase().game().map().get_fcoords(m_building.get_position()));
}
+/*
+===============
+Show the enhancecosts / dismanteleresults preview
+===============
+*/
+void Building_Window::show_costPrev(WaresMapDisplay::maptype const & cost, std::string text)
+{
+ m_enhancecostPrev->set_map(&cost);
+ m_prevtext->set_text(text);
+}
+
+/*
+===============
+Hide the Preview
+===============
+*/
+void Building_Window::hide_costPrev()
+{
+ m_enhancecostPrev->set_map(NULL);
+ m_prevtext->set_text("");
+ m_prevtext->set_desired_size(0, 0);
+}
+
/**
* Show the building's workarea (if it has one).
*/
=== modified file 'src/wui/buildingwindow.h'
--- src/wui/buildingwindow.h 2012-02-15 21:25:34 +0000
+++ src/wui/buildingwindow.h 2012-06-25 21:55:27 +0000
@@ -25,6 +25,7 @@
#include "interactive_gamebase.h"
#include "ui_basic/button.h"
#include "ui_basic/window.h"
+#include "waresdisplay.h"
/**
* Base class for all building windows.
@@ -66,6 +67,8 @@
void act_start_stop();
void act_enhance(Widelands::Building_Index);
void clicked_goto();
+ void show_costPrev(WaresMapDisplay::maptype const & cost, std::string text);
+ void hide_costPrev();
void create_ware_queue_panel
(UI::Box *, Widelands::Building &, Widelands::WaresQueue *, bool = false);
@@ -80,6 +83,9 @@
UI::Tab_Panel * m_tabs;
+ UI::Textarea * m_prevtext;
+ WaresMapDisplay * m_enhancecostPrev;
+
UI::Box * m_capsbuttons; ///< \ref UI::Box that contains capabilities buttons
UI::Button * m_toggle_workarea;
=== modified file 'src/wui/fieldaction.cc'
--- src/wui/fieldaction.cc 2012-02-20 15:54:26 +0000
+++ src/wui/fieldaction.cc 2012-06-25 21:55:27 +0000
@@ -37,6 +37,7 @@
#include "logic/tribe.h"
#include "logic/warehouse.h"
#include "military_box.h"
+#include "waresdisplay.h"
#include "watchwindow.h"
#include "ui_basic/box.h"
@@ -221,6 +222,8 @@
Widelands::FCoords m_node;
+ UI::Box m_box;
+ WaresMapDisplay m_buildcostPrev;
UI::Tab_Panel m_tabpanel;
bool m_fastclick; // if true, put the mouse over first button in first tab
uint32_t m_best_tab;
@@ -281,7 +284,9 @@
m_map(&ib->egbase().map()),
m_overlay_manager(*m_map->get_overlay_manager()),
m_node(ib->get_sel_pos().node, &(*m_map)[ib->get_sel_pos().node]),
- m_tabpanel(this, 0, 0, g_gr->get_picture(PicMod_UI, "pics/but1.png")),
+ m_box(this, 0, 0, UI::Box::Vertical),
+ m_buildcostPrev(&m_box, 0, 0, 6, m_plr->tribe(), NULL),
+ m_tabpanel(&m_box, 0, 0, g_gr->get_picture(PicMod_UI, "pics/but1.png")),
m_fastclick(true),
m_best_tab(0),
m_workarea_preview_job_id(Overlay_Manager::Job_Id::Null()),
@@ -289,7 +294,9 @@
{
ib->set_sel_freeze(true);
- set_center_panel(&m_tabpanel);
+ m_box.add(&m_tabpanel, UI::Box::AlignCenter);
+ m_box.add(&m_buildcostPrev, UI::Box::AlignLeft);
+ set_center_panel(&m_box);
char filename[] = "pics/workarea0cumulative.png";
compile_assert(NUMBER_OF_WORKAREA_PICS <= 9);
@@ -831,6 +838,7 @@
void FieldActionWindow::building_icon_mouse_out
(Widelands::Building_Index::value_t)
{
+ m_buildcostPrev.set_map(NULL);
if (m_workarea_preview_job_id) {
m_overlay_manager.remove_overlay(m_workarea_preview_job_id);
m_workarea_preview_job_id = Overlay_Manager::Job_Id::Null();
@@ -841,6 +849,9 @@
void FieldActionWindow::building_icon_mouse_in
(Widelands::Building_Index::value_t const idx)
{
+ m_buildcostPrev.set_map
+ (&m_plr->tribe().get_building_descr(Widelands::Building_Index(idx))->buildcost());
+
if (ibase().m_show_workarea_preview and not m_workarea_preview_job_id) {
m_workarea_preview_job_id = m_overlay_manager.get_a_job_id();
Widelands::HollowArea<> hollow_area(Widelands::Area<>(m_node, 0), 0);
=== modified file 'src/wui/waresdisplay.cc'
--- src/wui/waresdisplay.cc 2012-06-08 22:33:16 +0000
+++ src/wui/waresdisplay.cc 2012-06-25 21:55:27 +0000
@@ -346,3 +346,89 @@
// If you register something twice, it is counted twice. Not my problem.
m_warelists.push_back(&wares);
}
+
+
+/*
+====================================================
+struct BuildcostDisplay
+====================================================
+*/
+
+WaresMapDisplay::WaresMapDisplay
+ (UI::Panel * const parent,
+ const int32_t x, const int32_t y,
+ int32_t columns,
+ Widelands::Tribe_Descr const & tribe,
+ maptype const * map)
+ :
+ UI::Panel (parent, x, y, 0, 0), m_tribe(tribe), m_columns(columns)
+{
+ set_map(map);
+}
+
+WaresMapDisplay::~WaresMapDisplay()
+{}
+
+void WaresMapDisplay::set_map(maptype const * map) {
+ m_map = map;
+ if (m_map) {
+ int32_t c = m_map->size();
+ set_desired_size
+ ((c < m_columns ? c : m_columns) * (WARE_MENU_PIC_WIDTH + 4) + 1,
+ ((c / m_columns) + (c % m_columns != 0)) * (WARE_MENU_PIC_HEIGHT + 3 + 8) + 1);
+ set_visible(true);
+ } else {
+ set_desired_size(0, 0);
+ set_visible(false);
+ }
+}
+
+void WaresMapDisplay::draw(RenderTarget & dst)
+{
+ if (not m_map)
+ return;
+
+ Point p = Point(2, 2);
+
+ maptype::const_iterator c;
+
+ Widelands::Tribe_Descr::WaresOrder::iterator i;
+ std::vector<Widelands::Ware_Index>::iterator j;
+ Widelands::Tribe_Descr::WaresOrder order = m_tribe.wares_order();
+
+ for (i = order.begin(); i != order.end(); i++)
+ for (j = i->begin(); j != i->end(); j++)
+ if ((c = m_map->find(*j)) != m_map->end()) {
+ // draw a background
+ const PictureID picid =
+ g_gr->get_picture (PicMod_Game, "pics/ware_list_bg.png");
+ uint32_t w, h;
+ g_gr->get_picture_size(picid, w, h);
+
+ dst.blit(p, picid);
+
+ const Point pos = p + Point((w - WARE_MENU_PIC_WIDTH) / 2, 1);
+ // Draw it
+ dst.blit
+ (pos,
+ m_tribe.get_ware_descr(c->first)->icon());
+ dst.fill_rect
+ (Rect(pos + Point(0, WARE_MENU_PIC_HEIGHT), WARE_MENU_PIC_WIDTH, 8),
+ RGBColor(0, 0, 0));
+
+ UI::g_fh->draw_text
+ (dst, UI::TextStyle::ui_ultrasmall(),
+ p + Point(WARE_MENU_PIC_WIDTH, WARE_MENU_PIC_HEIGHT - 4),
+ boost::lexical_cast<std::string, uint32_t>(c->second),
+ UI::Align_Right);
+
+ p.x += (WARE_MENU_PIC_WIDTH + 4);
+ if (p.x >= (m_columns * (WARE_MENU_PIC_WIDTH + 4))) {
+ p.x = 2;
+ p.y += (WARE_MENU_PIC_HEIGHT + 3 + 8);
+ }
+ }
+}
+
+
+
=== modified file 'src/wui/waresdisplay.h'
--- src/wui/waresdisplay.h 2012-02-15 21:25:34 +0000
+++ src/wui/waresdisplay.h 2012-06-25 21:55:27 +0000
@@ -135,4 +135,32 @@
vector_type m_warelists;
};
+
+/**
+ * Displays the build costs of a given building
+ */
+
+struct WaresMapDisplay : public UI::Panel {
+ typedef std::map<Widelands::Ware_Index, uint8_t> maptype;
+
+ WaresMapDisplay
+ (UI::Panel * const parent,
+ int32_t const x, int32_t const y,
+ int32_t columns,
+ Widelands::Tribe_Descr const & tribe,
+ maptype const * map = NULL);
+
+ virtual ~WaresMapDisplay();
+
+ void set_map(maptype const * map);
+
+private:
+ virtual void draw(RenderTarget &);
+
+private:
+ Widelands::Tribe_Descr const & m_tribe;
+ maptype const * m_map;
+ int32_t m_columns;
+};
+
#endif
Follow ups