2
* Copyright (C) 2002-4 by the Widelands Development Team
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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21
#include "editorinteractive.h"
22
#include "editor_make_infrastructure_tool.h"
23
#include "editor_player_menu.h"
24
#include "editor_player_menu_allowed_buildings_menu.h"
25
#include "editor_set_starting_pos_tool.h"
29
#include "overlay_manager.h"
32
#include "ui_button.h"
33
#include "ui_editbox.h"
34
#include "ui_modal_messagebox.h"
35
#include "ui_textarea.h"
36
#include "wexception.h"
39
=================================================
41
class Editor_Tool_Set_Starting_Pos_Options_Menu
43
=================================================
49
Editor_Player_Menu::Editor_Player_Menu
51
Create all the buttons etc...
54
Editor_Player_Menu::Editor_Player_Menu(Editor_Interactive *parent,
55
Editor_Interactive::Editor_Tools* tools, int spt_tool_index, int make_infrs_tindex, UIUniqueWindowRegistry* registry)
56
: UIUniqueWindow(parent, registry, 340, 400, "Player Options")
61
m_spt_index=spt_tool_index;
62
m_mis_index=make_infrs_tindex;
73
Tribe_Descr::get_all_tribes(&m_tribes);
75
set_inner_size(375, 135);
76
UITextarea* ta=new UITextarea(this, 0, 0, "Player Options", Align_Left);
77
ta->set_pos((get_inner_w()-ta->get_w())/2, 5);
79
ta=new UITextarea(this, 0, 0, "Number of Players", Align_Left);
80
ta->set_pos((get_inner_w()-ta->get_w())/2, posy+5);
82
UIButton* b=new UIButton(this, posx, posy, width, height, 1, 0);
83
b->clickedid.set(this, &Editor_Player_Menu::button_clicked);
84
b->set_pic(g_gr->get_picture(PicMod_Game, "pics/scrollbar_up.png", true));
85
b=new UIButton(this, get_inner_w()-spacing-width, posy, width, height, 1, 1);
86
b->clickedid.set(this, &Editor_Player_Menu::button_clicked);
87
b->set_pic(g_gr->get_picture(PicMod_Game, "pics/scrollbar_down.png", true));
88
m_nr_of_players_ta=new UITextarea(this, 0, 0, "5", Align_Left);
89
m_nr_of_players_ta->set_pos((get_inner_w()-m_nr_of_players_ta->get_w())/2, posy+5);
90
posy+=width+spacing+spacing;
95
for(i=0; i<MAX_PLAYERS; i++) {
97
m_plr_set_pos_buts[i]=0;
98
m_plr_set_tribes_buts[i]=0;
99
m_plr_make_infrastructure_buts[i]=0;
100
m_plr_allowed_buildings[i]=0;
108
* Think function. Some things may change while this window
111
void Editor_Player_Menu::think(void) {
117
Editor_Player_Menu::update()
122
void Editor_Player_Menu::update(void) {
123
if(is_minimized()) return;
125
int nr_players=m_parent->get_map()->get_nrplayers();
127
if(nr_players/10) text+=static_cast<char>(nr_players/10 + 0x30);
128
text+=static_cast<char>((nr_players%10) + 0x30);
130
m_nr_of_players_ta->set_text(text.c_str());
132
// Now remove all the unneeded stuff
134
for(i=nr_players; i<MAX_PLAYERS; i++) {
136
delete m_plr_names[i];
139
if(m_plr_set_pos_buts[i]) {
140
delete m_plr_set_pos_buts[i];
141
m_plr_set_pos_buts[i]=0;
143
if(m_plr_set_tribes_buts[i]) {
144
delete m_plr_set_tribes_buts[i];
145
m_plr_set_tribes_buts[i]=0;
147
if(m_plr_set_tribes_buts[i]) {
148
delete m_plr_make_infrastructure_buts[i];
149
m_plr_make_infrastructure_buts[i]=0;
151
if(m_plr_allowed_buildings[i]) {
152
delete m_plr_allowed_buildings[i];
153
m_plr_allowed_buildings[i]=0;
162
// And recreate the needed
163
for(i=0; i<nr_players; i++) {
164
// Check if starting position is valid
165
bool start_pos_valid=true;
166
Coords start_pos=m_parent->get_map()->get_starting_pos(i+1);
167
if(start_pos.x==-1 && start_pos.y==-1) start_pos_valid=false;
169
if(!m_plr_names[i]) {
170
m_plr_names[i]=new UIEdit_Box(this, posx, posy, 140, size, 0, i);
171
m_plr_names[i]->changedid.set(this, &Editor_Player_Menu::name_changed);
173
m_plr_names[i]->set_text(m_parent->get_map()->get_scenario_player_name(i+1).c_str());
176
if(!m_plr_set_tribes_buts[i]) {
177
m_plr_set_tribes_buts[i]=new UIButton(this, posx, posy, 140, size, 0, i);
179
m_plr_set_tribes_buts[i]->clickedid.set(this, &Editor_Player_Menu::player_tribe_clicked);
181
if(m_parent->get_map()->get_scenario_player_tribe(i+1)!="<undefined>")
182
m_plr_set_tribes_buts[i]->set_title(m_parent->get_map()->get_scenario_player_tribe(i+1).c_str());
184
m_plr_set_tribes_buts[i]->set_title(m_tribes[0].c_str());
185
m_parent->get_map()->set_scenario_player_tribe(i+1,m_tribes[0]);
188
// Set Starting pos button
189
if(!m_plr_set_pos_buts[i]) {
190
m_plr_set_pos_buts[i]=new UIButton(this, posx, posy, size, size, 0, i+1);
191
m_plr_set_pos_buts[i]->clickedid.set(this, &Editor_Player_Menu::set_starting_pos_clicked);
194
text="pics/fsel_editor_set_player_";
195
text+=static_cast<char>(((i+1)/10) + 0x30);
196
text+=static_cast<char>(((i+1)%10) + 0x30);
198
m_plr_set_pos_buts[i]->set_pic(g_gr->get_picture(PicMod_Game, text.c_str(), true));
199
// Build infrastructure but
200
if(!m_plr_make_infrastructure_buts[i]) {
201
m_plr_make_infrastructure_buts[i]=new UIButton(this, posx, posy, size, size, 0, i+1);
202
m_plr_make_infrastructure_buts[i]->clickedid.set(this, &Editor_Player_Menu::make_infrastructure_clicked);
205
m_plr_make_infrastructure_buts[i]->set_enabled(0); // TODO enable this again: ->set_enabled(start_pos_valid)
206
m_plr_make_infrastructure_buts[i]->set_title("I"); // TODO: come up with a picture for this
208
if(!m_plr_allowed_buildings[i]) {
209
m_plr_allowed_buildings[i]=new UIButton(this, posx, posy, size, size, 0, i+1);
210
m_plr_allowed_buildings[i]->clickedid.set(this, &Editor_Player_Menu::allowed_buildings_clicked);
213
m_plr_allowed_buildings[i]->set_enabled(0); // TODO enable this again: ->set_enabled(start_pos_valid)
214
m_plr_allowed_buildings[i]->set_title("B"); // TODO: come up with a picture for this
219
set_inner_size(get_inner_w(),posy+spacing);
224
Editor_Player_Menu::button_clicked()
226
called when a button is clicked
229
void Editor_Player_Menu::button_clicked(int n) {
230
int nr_players=m_parent->get_map()->get_nrplayers();
232
if(n==0) ++nr_players;
233
if(n==1) --nr_players;
234
if(nr_players<1) nr_players=1;
235
if(nr_players>MAX_PLAYERS) nr_players=MAX_PLAYERS;
236
if(nr_players>m_parent->get_map()->get_nrplayers()) {
237
// register new default name for this players
238
char c1= (nr_players/10) ? (nr_players/10) + 0x30 : 0;
239
char c2= (nr_players%10) + 0x30;
240
std::string name="Player ";
241
if(c1) name.append(1,c1);
243
m_parent->get_map()->set_nrplayers(nr_players);
244
m_parent->get_map()->set_scenario_player_name(nr_players, name);
245
m_parent->get_map()->set_scenario_player_tribe(nr_players, m_tribes[0]);
246
m_parent->set_need_save(true);
248
if(!m_parent->is_player_tribe_referenced(nr_players)) {
249
std::string name= m_parent->get_map()->get_scenario_player_name(nr_players);
250
std::string tribe= m_parent->get_map()->get_scenario_player_tribe(nr_players);
251
m_parent->get_map()->set_nrplayers(nr_players);
252
m_parent->get_map()->set_scenario_player_name(nr_players, name);
253
m_parent->get_map()->set_scenario_player_tribe(nr_players, tribe);
254
m_parent->set_need_save(true);
256
UIModal_Message_Box* mmb=new UIModal_Message_Box(m_parent, "Error!", "Can't remove player. It is referenced in some place."
257
"Remove all buildings, bobs, triggers and events that depend of this player and try again", UIModal_Message_Box::OK);
267
* Player Tribe Button clicked
269
void Editor_Player_Menu::player_tribe_clicked(int n) {
270
// Tribe button has been clicked
271
if(!m_parent->is_player_tribe_referenced(n+1)) {
272
UIButton* but=m_plr_set_tribes_buts[n];
273
std::string t= but->get_title();
274
if(!Tribe_Descr::exists_tribe(t))
275
throw wexception("Map defines tribe %s, but it doesn't exist!\n", t.c_str());
277
for(i=0; i<m_tribes.size(); i++)
278
if(m_tribes[i]==t) break;
279
if(i==m_tribes.size()-1) t=m_tribes[0];
280
else t=m_tribes[++i];
281
m_parent->get_map()->set_scenario_player_tribe(n+1,t);
282
m_parent->set_need_save(true);
284
UIModal_Message_Box* mmb=new UIModal_Message_Box(m_parent, "Error!", "Can't change player tribe. It is referenced in some place."
285
"Remove all buildings, bobs, triggers and events that depend on this tribe and try again", UIModal_Message_Box::OK);
294
* Set Current Start Position button selected
296
void Editor_Player_Menu::set_starting_pos_clicked(int n) {
297
// jump to the current field
298
Coords c=m_parent->get_map()->get_starting_pos(n);
299
if(c.x!= -1 && c.y!= -1)
300
m_parent->move_view_to(c.x,c.y);
302
// If the player is already created in the editor, this means
303
// that there might be already a hq placed somewhere. This needs to be
304
// deleted before a starting position change can occure
305
if(m_parent->get_editor()->get_player(n)) {
306
if(m_parent->get_map()->get_starting_pos(n) != Coords(-1,-1)) {
307
BaseImmovable* imm = m_parent->get_map()->get_field(m_parent->get_map()->get_starting_pos(n))->get_immovable();
308
if(imm && imm->get_type() == Map_Object::BUILDING) return;
312
// Select tool set mplayer
313
m_parent->select_tool(m_spt_index,0);
314
static_cast<Editor_Set_Starting_Pos_Tool*>(m_tools->tools[m_spt_index])->set_current_player(n);
316
// Reselect tool, so everything is in a defined state
317
m_parent->select_tool(m_parent->get_selected_tool(),0);
319
// Register callback function to make sure that only valid fields are selected.
320
m_parent->get_map()->get_overlay_manager()->register_overlay_callback_function(&Editor_Tool_Set_Starting_Pos_Callback, m_parent->get_map());
321
m_parent->get_map()->recalc_whole_map();
326
* Player name has changed
328
void Editor_Player_Menu::name_changed(int m) {
329
// Player name has been changed
330
std::string text=m_plr_names[m]->get_text();
332
text=m_parent->get_map()->get_scenario_player_name(m+1);
333
m_plr_names[m]->set_text(text.c_str());
335
m_parent->get_map()->set_scenario_player_name(m+1, text);
336
m_plr_names[m]->set_text(m_parent->get_map()->get_scenario_player_name(m+1).c_str());
337
m_parent->set_need_save(true);
341
* Make infrastructure button clicked
343
void Editor_Player_Menu::make_infrastructure_clicked(int n) {
344
// Check if starting position is valid (was checked before
346
Coords start_pos=m_parent->get_map()->get_starting_pos(n);
347
assert(start_pos.x!=-1 && start_pos.y!=-1);
349
Editor* editor=m_parent->get_editor();
351
Player* p=editor->get_player(n);
353
// This player is unknown, register it, place a hq and reference the tribe
354
// so that this tribe can not be changed
355
editor->add_player(n, Player::playerLocal, m_plr_set_tribes_buts[n-1]->get_title(), m_plr_names[n-1]->get_text());
357
p=editor->get_player(n);
358
p->init(m_parent->get_egbase(),false);
361
// If the player is already created in the editor, this means
362
// that there might be already a hq placed somewhere. This needs to be
363
// deleted before a starting position change can occure
364
BaseImmovable* imm = m_parent->get_map()->get_field(m_parent->get_map()->get_starting_pos(p->get_player_number()))->get_immovable();
367
const Coords &c = m_parent->get_map()->get_starting_pos(p->get_player_number());
368
int idx = p->get_tribe()->get_building_index("headquarters");
370
throw wexception("Tribe %s lacks headquarters", p->get_tribe()->get_name());
371
m_parent->get_egbase()->warp_building(c, p->get_player_number(), idx);
373
m_parent->reference_player_tribe(n, p->get_tribe());
375
// Remove the player overlay from this starting pos.
376
// A HQ is overlay enough
377
std::string picsname="pics/editor_player_";
378
picsname+=static_cast<char>((n/10) + 0x30);
379
picsname+=static_cast<char>((n%10) + 0x30);
380
picsname+="_starting_pos.png";
381
int picid=g_gr->get_picture(PicMod_Game, picsname.c_str(), true);
382
// Remove old overlay if any
383
m_parent->get_editor()->get_map()->get_overlay_manager()->remove_overlay(start_pos,picid);
386
m_parent->select_tool(m_mis_index,0);
387
static_cast<Editor_Make_Infrastructure_Tool*>(m_tools->tools[m_mis_index])->set_player(n);
388
m_parent->get_editor()->get_map()->get_overlay_manager()->register_overlay_callback_function(&Editor_Make_Infrastructure_Tool_Callback, static_cast<void*>(m_parent->get_editor()),n);
389
m_parent->get_editor()->get_map()->recalc_whole_map();
393
* Allowed building button clicked
395
void Editor_Player_Menu::allowed_buildings_clicked(int n) {
397
Editor* editor=m_parent->get_editor();
399
if(!editor->get_player(n)) {
400
// The player is not yet really on the map, call make infrastructure button first
401
make_infrastructure_clicked(n);
405
if (m_allow_buildings_menu.window) {
406
delete m_allow_buildings_menu.window;
409
new Editor_Player_Menu_Allowed_Buildings_Menu(m_parent, editor->get_player(n), &m_allow_buildings_menu);