1 /* Copyright (C) 2007 The SpringLobby Team. All rights reserved. */
2 //
3 // Class: BattleMapTab
4 //
5
6 #include <wx/splitter.h>
7 #include <wx/intl.h>
8 #include <wx/combobox.h>
9 #include <wx/stattext.h>
10 #include <wx/statline.h>
11 #include <wx/checkbox.h>
12 #include <wx/button.h>
13 #include <wx/sizer.h>
14 #include <wx/radiobox.h>
15 #include <wx/window.h>
16 #include <wx/listctrl.h>
17 #include <wx/settings.h>
18 #include <wx/arrstr.h>
19 #include <wx/choice.h>
20
21 #include <stdexcept>
22
23 #include "battlemaptab.h"
24 #include <lslutils/conversion.h>
25 #include "user.h"
26 #include "battle.h"
27 #include "utils/debug.h"
28 #include "utils/controls.h"
29 #include "chatpanel.h"
30 #include "mapctrl.h"
31 #include "mapselectdialog.h"
32 #include "uiutils.h"
33 #include "server.h"
34 #include "settings.h"
35 #include "aui/auimanager.h"
36
BEGIN_EVENT_TABLE(BattleMapTab,wxPanel)37 BEGIN_EVENT_TABLE( BattleMapTab, wxPanel )
38
39 EVT_CHOICE ( BMAP_MAP_SEL, BattleMapTab::OnMapSelect )
40 EVT_BUTTON ( BMAP_MAP_BROWSE, BattleMapTab::OnMapBrowse )
41 EVT_RADIOBOX ( BMAP_START_TYPE, BattleMapTab::OnStartTypeSelect )
42
43 END_EVENT_TABLE()
44
45
46 BattleMapTab::BattleMapTab( wxWindow* parent, Battle* battle )
47 : wxScrolledWindow( parent, -1 ),
48 m_battle( battle )
49 {
50 GetAui().manager->AddPane( this, wxLEFT, _T( "battlemaptab" ) );
51
52 wxBoxSizer* m_main_sizer = new wxBoxSizer( wxHORIZONTAL );
53 wxBoxSizer* m_map_sizer = new wxBoxSizer( wxVERTICAL );
54
55 m_map_sizer->SetMinSize( wxSize( 352, -1 ) );
56 m_minimap = new MapCtrl( this, 352, m_battle, true, false, true, false );
57
58 m_minimap->SetMinSize( wxSize( 352, 352 ) );
59
60 m_map_sizer->Add( m_minimap, 1, wxALL | wxEXPAND, 2 );
61
62 wxBoxSizer* m_selmap_sizer = new wxBoxSizer( wxHORIZONTAL );
63
64 m_map_combo = new wxChoice( this, BMAP_MAP_SEL, wxDefaultPosition, wxDefaultSize );
65 m_selmap_sizer->Add( m_map_combo, 1, wxALL, 2 );
66
67 m_browse_btn = new wxButton( this, BMAP_MAP_BROWSE, _( "Select" ), wxDefaultPosition, wxDefaultSize, 0 );
68
69 m_selmap_sizer->Add( m_browse_btn, 0, wxALL, 2 );
70
71 m_map_sizer->Add( m_selmap_sizer, 0, wxEXPAND, 5 );
72
73 m_main_sizer->Add( m_map_sizer, 1, wxEXPAND, 5 );
74
75 wxBoxSizer* m_opts_sizer = new wxBoxSizer( wxVERTICAL );
76
77 //m_opts_sizer->SetMinSize(wxSize( 200,-1 ));
78 m_map_opts_list = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxSize( 150, 160 ), wxLC_NO_HEADER | wxLC_REPORT );
79 m_map_opts_list->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
80 m_map_opts_list->SetFont( wxFont( 8, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_LIGHT ) );
81
82 wxListItem col;
83
84 col.SetText( _( "Option" ) );
85 m_map_opts_list->InsertColumn( 0, col );
86 col.SetText( _( "Value" ) );
87 m_map_opts_list->InsertColumn( 1, col );
88 m_map_opts_list->SetColumnWidth( 0, 90 );
89 m_map_opts_list->SetColumnWidth( 1, 50 );
90
91 m_map_opts_list->InsertItem( 0, _( "Size" ) );
92 m_map_opts_list->InsertItem( 1, _( "Windspeed" ) );
93 m_map_opts_list->InsertItem( 2, _( "Tidal strength" ) );
94 m_map_opts_list->InsertItem( 3, _( "Gravity" ) );
95 m_map_opts_list->InsertItem( 4, _( "Extractor radius" ) );
96 m_map_opts_list->InsertItem( 5, _( "Max metal" ) );
97
98 m_opts_sizer->Add( m_map_opts_list, 0, wxALL, 2 );
99
100
101 wxString m_start_radiosChoices[] = { _( "Fixed" ), _( "Random" ), _( "Choose in game" ), _( "Chose before game" ) };
102 int m_start_radiosNChoices = sizeof( m_start_radiosChoices ) / sizeof( wxString );
103 //TODO these need to be tooltipped, no idea how yet
104 m_start_radios = new wxRadioBox( this, BMAP_START_TYPE, _( "Startpositions" ), wxDefaultPosition, wxSize( 150, -1 ), m_start_radiosNChoices, m_start_radiosChoices, 1, wxRA_SPECIFY_COLS );
105
106 m_opts_sizer->Add( m_start_radios, 0, wxALL, 2 );
107
108 m_map_desc = new wxStaticText(this,-1,wxEmptyString);
109 m_map_desc->Wrap(160);
110
111 m_opts_sizer->Add( m_map_desc, 0, wxALL, 2 );
112
113 m_main_sizer->Add( m_opts_sizer, 0, wxEXPAND, 5 );
114 //m_main_sizer->AddStretchSpacer();
115 SetSizer( m_main_sizer );
116 Layout();
117
118 SetBattle( battle );
119
120 SetScrollRate( SCROLL_RATE, SCROLL_RATE );
121 Layout();
122 ConnectGlobalEvent(this, GlobalEvent::OnUnitsyncReloaded, wxObjectEventFunction(&BattleMapTab::OnUnitsyncReloaded));
123 }
124
125
~BattleMapTab()126 BattleMapTab::~BattleMapTab()
127 {
128 if ( GetAui().manager )
129 GetAui().manager->DetachPane( this );
130 }
131
Update()132 void BattleMapTab::Update()
133 {
134 if ( !m_battle ) return;
135 const long longval = LSL::Util::FromString<long>(
136 m_battle->CustomBattleOptions().getSingleValue( "startpostype", LSL::OptionsWrapper::EngineOption ));
137 m_start_radios->SetSelection( longval );
138
139 m_minimap->UpdateMinimap();
140
141 if ( !m_battle->MapExists() ) return;
142
143 LSL::UnitsyncMap map = m_battle->LoadMap();
144
145 m_map_opts_list->SetItem( 0, 1, wxFormat( _T( "%dx%d" ) ) % (map.info.width / 512) % (map.info.height / 512) );
146 m_map_opts_list->SetItem( 1, 1, wxFormat( _T( "%d-%d" ) ) % map.info.minWind % map.info.maxWind );
147 m_map_opts_list->SetItem( 2, 1, wxFormat( _T( "%d" ) ) % map.info.tidalStrength );
148 m_map_opts_list->SetItem( 3, 1, wxFormat( _T( "%d" ) ) % map.info.gravity );
149 m_map_opts_list->SetItem( 4, 1, wxFormat( _T( "%d" ) ) % map.info.extractorRadius );
150 m_map_opts_list->SetItem( 5, 1, wxFormat( _T( "%.3f" ) ) % map.info.maxMetal );
151
152 m_map_desc->SetLabel(TowxString(map.info.description));
153 m_map_desc->Wrap(160);
154
155 int index = m_map_combo->FindString( TowxString(map.name) );
156 if ( index == wxNOT_FOUND ) return;
157 m_map_combo->SetSelection( index );
158 }
159
160
Update(const wxString & Tag)161 void BattleMapTab::Update( const wxString& Tag )
162 {
163 if ( !m_battle ) return;
164 long type;
165 Tag.BeforeFirst( '_' ).ToLong( &type );
166 const std::string key = STD_STRING(Tag.AfterFirst( '_' ));
167 const long longval = LSL::Util::FromString<long>(
168 m_battle->CustomBattleOptions().getSingleValue( key, ( LSL::OptionsWrapper::GameOption )type ));
169 if ( type == LSL::OptionsWrapper::EngineOption )
170 {
171 if ( key == "startpostype" )
172 {
173 m_start_radios->SetSelection( longval );
174 m_minimap->UpdateMinimap();
175 }
176 }
177 else if ( type == LSL::OptionsWrapper::PrivateOptions )
178 {
179 if ( key == "mapname" )
180 {
181 Update();
182 }
183 }
184 }
185
186
ReloadMaplist()187 void BattleMapTab::ReloadMaplist()
188 {
189 if ( !m_battle ) return;
190 m_map_combo->Clear();
191 int i = 0;
192 for (auto map : LSL::usync().GetMapList())
193 m_map_combo->Insert( TowxString(map), i++ );
194 }
195
196
UpdateUser(User & user)197 void BattleMapTab::UpdateUser( User& user )
198 {
199 if ( !m_battle ) return;
200 if ( &m_battle->GetMe() == &user ) {
201 try {
202 m_minimap->UpdateMinimap();
203 } catch ( ... ) { }
204 }
205 }
206
207
SetMap(int index)208 void BattleMapTab::SetMap( int index )
209 {
210 if ( !m_battle ) return;
211 try
212 {
213 LSL::UnitsyncMap map = LSL::usync().GetMapEx( index );
214 m_battle->SetLocalMap( map );
215
216 m_battle->SendHostInfo( IBattle::HI_Map );
217 } catch ( ... ) {}
218 }
219
220
OnMapSelect(wxCommandEvent &)221 void BattleMapTab::OnMapSelect( wxCommandEvent& /*unused*/ )
222 {
223 if ( !m_battle ) return;
224 if ( !m_battle->IsFounderMe() )
225 {
226 try
227 {
228 m_battle->DoAction(TowxString("suggests " + LSL::usync().GetMap( m_map_combo->GetCurrentSelection() ).name));
229 }
230 catch ( ... )
231 {
232 }
233 return;
234 }
235 SetMap( m_map_combo->GetCurrentSelection() );
236 }
237
238
OnMapBrowse(wxCommandEvent &)239 void BattleMapTab::OnMapBrowse( wxCommandEvent& /*unused*/ )
240 {
241 if ( !m_battle ) return;
242 wxLogDebugFunc( wxEmptyString );
243
244 wxString mapname = mapSelectDialog();
245 if ( !mapname.empty() )
246 {
247 wxLogDebugFunc( mapname );
248 if ( !m_battle->IsFounderMe() )
249 {
250 m_battle->DoAction( _T( "suggests " ) + mapname );
251 return;
252 }
253 const int idx = m_map_combo->FindString( mapname, true /*case sensitive*/ );
254 if ( idx != wxNOT_FOUND )
255 SetMap( idx );
256 }
257
258 }
259
260
OnStartTypeSelect(wxCommandEvent &)261 void BattleMapTab::OnStartTypeSelect( wxCommandEvent& /*unused*/ )
262 {
263 if ( !m_battle ) return;
264 const std::string pos = wxFormat( _T( "%d" ) ) % m_start_radios->GetSelection();
265 m_battle->CustomBattleOptions().setSingleOption( "startpostype", pos, LSL::OptionsWrapper::EngineOption );
266 m_battle->SendHostInfo( wxFormat( _T( "%d_startpostype" ) ) % LSL::OptionsWrapper::EngineOption );
267 }
268
269
OnUnitsyncReloaded(wxCommandEvent &)270 void BattleMapTab::OnUnitsyncReloaded( wxCommandEvent& /*data*/ )
271 {
272 if ( !m_battle ) return;
273 ReloadMaplist();
274 }
275
SetBattle(Battle * battle)276 void BattleMapTab::SetBattle( Battle* battle )
277 {
278 m_battle = battle;
279
280 m_start_radios->Enable( m_battle );
281 m_minimap->Enable( m_battle );
282 m_map_combo->Enable( m_battle );
283 m_browse_btn->Enable( m_battle );
284 m_map_opts_list->Enable( m_battle );
285 m_minimap->SetBattle( m_battle );
286 if ( m_battle )
287 {
288 m_minimap->SetReadOnly( !m_battle->IsFounderMe() );
289 m_start_radios->Enable( m_battle->IsFounderMe() );
290 ReloadMaplist();
291 Update();
292 }
293
294 }
295