~ubuntu-branches/ubuntu/precise/widelands/precise-backports

« back to all changes in this revision

Viewing changes to src/editor/ui_menus/editor_player_menu.cc

  • Committer: Bazaar Package Importer
  • Author(s): Martin Quinson
  • Date: 2005-02-14 10:41:12 UTC
  • Revision ID: james.westby@ubuntu.com-20050214104112-6v08iux9fptxpva9
Tags: upstream-build9
Import upstream version build9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2002-4 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
 *
 
18
 */
 
19
 
 
20
#include "editor.h"
 
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"
 
26
#include "error.h"
 
27
#include "graphic.h"
 
28
#include "map.h"
 
29
#include "overlay_manager.h"
 
30
#include "player.h"
 
31
#include "tribe.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"
 
37
 
 
38
/*
 
39
=================================================
 
40
 
 
41
class Editor_Tool_Set_Starting_Pos_Options_Menu
 
42
 
 
43
=================================================
 
44
*/
 
45
 
 
46
 
 
47
/*
 
48
===============
 
49
Editor_Player_Menu::Editor_Player_Menu
 
50
 
 
51
Create all the buttons etc...
 
52
===============
 
53
*/
 
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")
 
57
{
 
58
   // Initialisation
 
59
   m_parent=parent;
 
60
   m_tools=tools;
 
61
   m_spt_index=spt_tool_index;
 
62
   m_mis_index=make_infrs_tindex;
 
63
 
 
64
   // User Interface
 
65
   int offsx=5;
 
66
   int offsy=30;
 
67
   int spacing=5;
 
68
   int height=20;
 
69
   int width=20;
 
70
   int posx=offsx;
 
71
   int posy=offsy;
 
72
      
 
73
   Tribe_Descr::get_all_tribes(&m_tribes);
 
74
 
 
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);
 
78
 
 
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);
 
81
   posy+=spacing+width;
 
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;
 
91
 
 
92
   m_posy=posy;
 
93
 
 
94
   int i=0;
 
95
   for(i=0; i<MAX_PLAYERS; i++) {
 
96
      m_plr_names[i]=0;
 
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;
 
101
   }
 
102
   update();
 
103
 
 
104
   set_think(true);
 
105
}
 
106
 
 
107
/*
 
108
 * Think function. Some things may change while this window
 
109
 * is open
 
110
 */
 
111
void Editor_Player_Menu::think(void) {
 
112
   update();
 
113
}
 
114
 
 
115
/*
 
116
===============
 
117
Editor_Player_Menu::update()
 
118
 
 
119
Update all
 
120
===============
 
121
*/
 
122
void Editor_Player_Menu::update(void) {
 
123
   if(is_minimized()) return;
 
124
 
 
125
   int nr_players=m_parent->get_map()->get_nrplayers();
 
126
   std::string text="";
 
127
   if(nr_players/10) text+=static_cast<char>(nr_players/10 + 0x30);
 
128
   text+=static_cast<char>((nr_players%10) + 0x30);
 
129
 
 
130
   m_nr_of_players_ta->set_text(text.c_str());
 
131
 
 
132
   // Now remove all the unneeded stuff
 
133
   int i=0;
 
134
   for(i=nr_players; i<MAX_PLAYERS; i++) {
 
135
      if(m_plr_names[i]) {
 
136
         delete m_plr_names[i];
 
137
         m_plr_names[i]=0;
 
138
      }
 
139
      if(m_plr_set_pos_buts[i]) {
 
140
         delete m_plr_set_pos_buts[i];
 
141
         m_plr_set_pos_buts[i]=0;
 
142
      }
 
143
      if(m_plr_set_tribes_buts[i]) {
 
144
         delete m_plr_set_tribes_buts[i];
 
145
         m_plr_set_tribes_buts[i]=0;
 
146
      }
 
147
      if(m_plr_set_tribes_buts[i]) {
 
148
         delete m_plr_make_infrastructure_buts[i];
 
149
         m_plr_make_infrastructure_buts[i]=0;
 
150
      }
 
151
      if(m_plr_allowed_buildings[i]) {
 
152
         delete m_plr_allowed_buildings[i];
 
153
         m_plr_allowed_buildings[i]=0;
 
154
      }
 
155
   }
 
156
   int posy=m_posy;
 
157
   int spacing=5;
 
158
   int size=20;
 
159
   int posx=spacing;
 
160
   
 
161
 
 
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; 
 
168
      
 
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);
 
172
          posx+=140+spacing;
 
173
          m_plr_names[i]->set_text(m_parent->get_map()->get_scenario_player_name(i+1).c_str());
 
174
      }
 
175
 
 
176
      if(!m_plr_set_tribes_buts[i]) {
 
177
         m_plr_set_tribes_buts[i]=new UIButton(this, posx, posy, 140, size, 0, i);
 
178
         posx+=140+spacing;
 
179
         m_plr_set_tribes_buts[i]->clickedid.set(this, &Editor_Player_Menu::player_tribe_clicked);
 
180
      }
 
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());
 
183
      else { 
 
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]);
 
186
      }
 
187
 
 
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);
 
192
          posx+=size+spacing;
 
193
      }
 
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);
 
197
      text+="_pos.png";
 
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);
 
203
         posx+=size+spacing;
 
204
      }
 
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
 
207
      // Allowed buildings
 
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);
 
211
         posx+=size+spacing;
 
212
      }
 
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
 
215
  
 
216
      posx=spacing;
 
217
      posy+=size+spacing;
 
218
   }
 
219
   set_inner_size(get_inner_w(),posy+spacing);
 
220
}
 
221
 
 
222
/*
 
223
==============
 
224
Editor_Player_Menu::button_clicked()
 
225
 
 
226
called when a button is clicked
 
227
==============
 
228
*/
 
229
void Editor_Player_Menu::button_clicked(int n) {
 
230
   int nr_players=m_parent->get_map()->get_nrplayers();
 
231
   // Up down button
 
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);
 
242
      name.append(1,c2);
 
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);
 
247
   } else {
 
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);
 
255
      } else {
 
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);
 
258
         mmb->run();
 
259
         delete mmb;
 
260
      }
 
261
   }
 
262
   update();
 
263
}
 
264
 
 
265
 
 
266
/*
 
267
 * Player Tribe Button clicked
 
268
 */
 
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());
 
276
      uint i;
 
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);
 
283
   } else {
 
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);
 
286
      mmb->run();
 
287
      delete mmb;
 
288
   }
 
289
   update();
 
290
}
 
291
 
 
292
 
 
293
/*
 
294
 * Set Current Start Position button selected
 
295
 */
 
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);
 
301
 
 
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;
 
309
      }
 
310
   }
 
311
   
 
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);
 
315
 
 
316
   // Reselect tool, so everything is in a defined state
 
317
   m_parent->select_tool(m_parent->get_selected_tool(),0);
 
318
 
 
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();
 
322
   update();
 
323
}
 
324
 
 
325
/*
 
326
 * Player name has changed
 
327
 */
 
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();
 
331
   if(text=="") {
 
332
      text=m_parent->get_map()->get_scenario_player_name(m+1);
 
333
      m_plr_names[m]->set_text(text.c_str());
 
334
   }
 
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);
 
338
}
 
339
 
 
340
/*
 
341
 * Make infrastructure button clicked
 
342
 */
 
343
void Editor_Player_Menu::make_infrastructure_clicked(int n) {
 
344
   // Check if starting position is valid (was checked before
 
345
   // so must be true)
 
346
   Coords start_pos=m_parent->get_map()->get_starting_pos(n);
 
347
   assert(start_pos.x!=-1 && start_pos.y!=-1); 
 
348
   
 
349
   Editor* editor=m_parent->get_editor();
 
350
 
 
351
   Player* p=editor->get_player(n);
 
352
   if(!p) {
 
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());
 
356
 
 
357
      p=editor->get_player(n);
 
358
      p->init(m_parent->get_egbase(),false);
 
359
   }
 
360
 
 
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();
 
365
   if(!imm) {
 
366
      // place HQ
 
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");
 
369
      if (idx < 0)
 
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);
 
372
 
 
373
      m_parent->reference_player_tribe(n, p->get_tribe());
 
374
 
 
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);
 
384
   }
 
385
 
 
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();
 
390
}
 
391
 
 
392
/*
 
393
 * Allowed building button clicked
 
394
 */
 
395
void Editor_Player_Menu::allowed_buildings_clicked(int n) {
 
396
   
 
397
   Editor* editor=m_parent->get_editor();
 
398
   
 
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);
 
402
   }
 
403
   
 
404
   // Create the menu
 
405
   if (m_allow_buildings_menu.window) {
 
406
      delete m_allow_buildings_menu.window;
 
407
   }
 
408
   else {
 
409
      new Editor_Player_Menu_Allowed_Buildings_Menu(m_parent, editor->get_player(n), &m_allow_buildings_menu);
 
410
   }
 
411
}