Bug Summary

File:wui/game_summary.cc
Location:line 187, column 37
Description:Called C++ object pointer is null

Annotated Source Code

1/*
2 * Copyright (C) 2007-2008 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20#include "wui/game_summary.h"
21
22#include <boost/algorithm/string.hpp>
23#include <boost/foreach.hpp>
24#include <boost/format.hpp>
25
26#include "graphic/graphic.h"
27#include "logic/game.h"
28#include "logic/player.h"
29#include "logic/playersmanager.h"
30#include "timestring.h"
31#include "ui_basic/box.h"
32#include "ui_basic/button.h"
33#include "ui_basic/table.h"
34#include "ui_basic/textarea.h"
35#include "ui_basic/unique_window.h"
36#include "wlapplication.h"
37#include "wui/interactive_gamebase.h"
38#include "wui/interactive_player.h"
39
40#define PADDING4 4
41
42GameSummaryScreen::GameSummaryScreen
43 (Interactive_GameBase * parent, UI::UniqueWindow::Registry * r)
44: UI::UniqueWindow(parent, "game_summary", r, 500, 400, _("Game over")i18n::translate("Game over")),
45m_game(parent->game())
46{
47 // Init boxes
48 UI::Box * vbox = new UI::Box(this, 0, 0, UI::Box::Vertical, 0, 0, PADDING4);
49 m_title_area = new UI::Textarea(vbox, "", UI::Align_HCenter);
50 vbox->add(m_title_area, UI::Box::AlignCenter);
51 vbox->add_space(PADDING4);
52
53 UI::Box * hbox1 = new UI::Box(this, 0, 0, UI::Box::Horizontal);
54 m_players_table = new UI::Table<uintptr_t const>(hbox1, 0, 0, 260, 200);
55 hbox1->add_space(PADDING4);
56 hbox1->add(m_players_table, UI::Box::AlignTop);
57 hbox1->add_space(PADDING4);
58
59 UI::Box * infoBox = new UI::Box(hbox1, 0, 0, UI::Box::Vertical, 0, 0);
60 m_gametime_label = new UI::Textarea(infoBox, _("Elapsed time:")i18n::translate("Elapsed time:"));
61 infoBox->add(m_gametime_label, UI::Box::AlignLeft);
62 m_gametime_value = new UI::Textarea(infoBox);
63 infoBox->add(m_gametime_value, UI::Box::AlignRight);
64 infoBox->add_space(PADDING4);
65 m_info_area = new UI::Multiline_Textarea(infoBox, 0, 0, 130, 130, "");
66 infoBox->add(m_info_area, UI::Box::AlignLeft, true);
67 infoBox->add_space(PADDING4);
68 hbox1->add(infoBox, UI::Box::AlignTop);
69 hbox1->add_space(PADDING4);
70 vbox->add(hbox1, UI::Box::AlignLeft);
71 vbox->add_space(PADDING4);
72
73 UI::Box * buttonBox = new UI::Box(this, 0, 0, UI::Box::Horizontal);
74 m_continue_button = new UI::Button
75 (buttonBox, "continue_button",
76 0, 0, 100, 32, g_gr->images().get("pics/but0.png"),
77 _("Continue")i18n::translate("Continue"), _("Continue playing")i18n::translate("Continue playing"));
78 buttonBox->add(m_continue_button, UI::Box::AlignRight);
79 buttonBox->add_space(PADDING4);
80 m_stop_button = new UI::Button
81 (buttonBox, "stop_button",
82 0, 0, 100, 32, g_gr->images().get("pics/but0.png"),
83 _("Quit")i18n::translate("Quit"), _("Return to main menu")i18n::translate("Return to main menu"));
84 buttonBox->add(m_stop_button, UI::Box::AlignRight);
85 vbox->add(buttonBox, UI::Box::AlignBottom);
86 vbox->add_space(PADDING4);
87 set_center_panel(vbox);
88
89 // Prepare table
90 m_players_table->add_column(150, _("Player")i18n::translate("Player"));
91 m_players_table->add_column(50, _("Team")i18n::translate("Team"), UI::Align_HCenter);
92 m_players_table->add_column(100, _("Status")i18n::translate("Status"), UI::Align_HCenter);
93 m_players_table->add_column(100, _("Time")i18n::translate("Time"));
94
95 // Prepare Elements
96 m_title_area->set_textstyle(UI::TextStyle::ui_big());
97
98 // Connections
99 m_continue_button->sigclicked.connect
100 (boost::bind(&GameSummaryScreen::continue_clicked, this));
101 m_stop_button->sigclicked.connect
102 (boost::bind(&GameSummaryScreen::stop_clicked, this));
103 m_players_table->selected.connect
104 (boost::bind(&GameSummaryScreen::player_selected, this, _1));
105
106 // Window
107 center_to_parent();
108 set_can_focus(true);
109 focus();
110 fill_data();
111}
112
113bool GameSummaryScreen::handle_mousepress(Uint8 btn, int32_t mx, int32_t my)
114{
115 // Prevent closing with right click
116 if (btn == SDL_BUTTON_RIGHT3)
117 return true;
118
119 return UI::Window::handle_mousepress(btn, mx, my);
120}
121
122void GameSummaryScreen::fill_data()
123{
124 std::vector<Widelands::PlayerEndStatus> players_status
125 = m_game.player_manager()->get_players_end_status();
126 bool local_in_game = false;
127 bool local_won = false;
128 Widelands::Player* single_won = NULL__null;
1
'single_won' initialized to a null pointer value
129 uint8_t team_won = 0;
130 Interactive_Player* ipl = m_game.get_ipl();
131
132 for (uintptr_t i = 0; i < players_status.size(); i++) {
2
Loop condition is false. Execution continues on line 178
133 Widelands::PlayerEndStatus pes = players_status.at(i);
134 if (ipl && pes.player == ipl->player_number()) {
135 local_in_game = true;
136 local_won = pes.result == Widelands::PlayerEndResult::PLAYER_WON;
137 }
138 Widelands::Player* p = m_game.get_player(pes.player);
139 UI::Table<uintptr_t const>::Entry_Record & te
140 = m_players_table->add(i);
141 // Player name & pic
142 // Boost doesn't handle uint8_t as integers
143 uint16_t player_number = pes.player;
144 std::string pic_path =
145 (boost::format("pics/genstats_enable_plr_0%|1$u|.png") % player_number).str();
146 const Image* pic = g_gr->images().get(pic_path);
147 te.set_picture(0, pic, p->get_name());
148 // Team
149 uint16_t team_number = p->team_number();
150 std::string team_str =
151 (boost::format("%|1$u|") % team_number).str();
152 te.set_string(1, team_str);
153 // Status
154 std::string stat_str;
155 switch (pes.result) {
156 case Widelands::PlayerEndResult::PLAYER_LOST:
157 stat_str = _("Lost")i18n::translate("Lost");
158 break;
159 case Widelands::PlayerEndResult::PLAYER_WON:
160 stat_str = _("Won")i18n::translate("Won");
161 if (!single_won) {
162 single_won = p;
163 } else {
164 team_won = p->team_number();
165 }
166 break;
167 case Widelands::PlayerEndResult::PLAYER_RESIGNED:
168 stat_str = _("Resigned")i18n::translate("Resigned");
169 break;
170 default:
171 stat_str = _("Unknown")i18n::translate("Unknown");
172 }
173 te.set_string(2, stat_str);
174 // Time
175 te.set_string(3, gametimestring(pes.time));
176 }
177
178 if (local_in_game) {
3
Taking false branch
179 if (local_won) {
180 m_title_area->set_text(_("You won!")i18n::translate("You won!"));
181 } else {
182 m_title_area->set_text(_("You lost.")i18n::translate("You lost."));
183 }
184 } else {
185 if (team_won <= 0) {
4
Taking true branch
186 m_title_area->set_text
187 ((boost::format(_("%s won!")i18n::translate("%s won!")) % single_won->get_name()).str());
5
Called C++ object pointer is null
188 } else {
189 uint16_t team_number = team_won;
190 m_title_area->set_text
191 ((boost::format(_("Team %|1$u| won!")i18n::translate("Team %|1$u| won!")) % team_number).str());
192 }
193 }
194 m_players_table->update();
195 if (players_status.size() > 0) {
196 m_players_table->select(players_status.at(0).player);
197 }
198 m_gametime_value->set_text(gametimestring(m_game.get_gametime()));
199}
200
201void GameSummaryScreen::continue_clicked()
202{
203 die();
204}
205
206void GameSummaryScreen::stop_clicked()
207{
208 m_game.get_ibase()->end_modal(0);
209}
210
211void GameSummaryScreen::player_selected(uint32_t idx)
212{
213 const std::vector <Widelands::PlayerEndStatus >& players_status
214 = m_game.player_manager()->get_players_end_status();
215 for (uintptr_t i = 0; i < players_status.size(); i++) {
216 Widelands::PlayerEndStatus pes = players_status.at(i);
217 if (pes.player == idx) {
218 std::string info_str = parse_player_info(pes.info);
219 m_info_area->set_text(info_str);
220 layout();
221 break;
222 }
223 }
224}
225
226std::string GameSummaryScreen::parse_player_info(std::string& info)
227{
228 typedef boost::split_iterator<std::string::iterator> string_split_iterator;
229 std::string info_str;
230 if (info.empty()) {
231 return info_str;
232 }
233 // Iterate through all key=value pairs
234 string_split_iterator substring_it = boost::make_split_iterator
235 (info, boost::first_finder(";", boost::is_equal()));
236 while (substring_it != string_split_iterator()) {
237 std::string substring = boost::copy_range<std::string>(*substring_it);
238 std::vector<std::string> pair;
239 boost::split(pair, substring, boost::is_any_of("="));
240 assert(pair.size() == 2)((pair.size() == 2) ? static_cast<void> (0) : __assert_fail
("pair.size() == 2", "/home/arch/widelands/src/wui/game_summary.cc"
, 240, __PRETTY_FUNCTION__))
;
241
242 std::string key = pair.at(0);
243 if (key == "score") {
244 info_str +=
245 (boost::format("%1% : %2%\n") % _("Score")i18n::translate("Score") % pair.at(1)).str();
246 } else if (key == "resign_reason") {
247 info_str +=
248 (boost::format("%1%\n") % pair.at(1)).str();
249 }
250 ++substring_it;
251 }
252 if (!info_str.empty()) {
253 info_str =
254 (boost::format("%1% :\n%2%") % _("Player info")i18n::translate("Player info") % info_str).str();
255 }
256 return info_str;
257}
258