00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <sstream>
00023 #include <pgimage.h>
00024
00025 #include <pgpropertyeditor.h>
00026 #include <pgpropertyfield_integer.h>
00027
00028 #include "eventeditor.h"
00029 #include "../paradialog.h"
00030 #include "../gamemap.h"
00031 #include "../spfst.h"
00032 #include "../gameeventsystem.h"
00033 #include "../gameevents.h"
00034
00035 #include "../widgets/dropdownselector.h"
00036 #include "../widgets/multilistbox.h"
00037
00038 class EventEditor : public ASC_PG_Dialog {
00039 private:
00040 vector<ASCString> triggerNames;
00041 vector<ASCString> actionNames;
00042
00043 DropDownSelector* eventType;
00044 DropDownSelector* triggerConnection;
00045 PG_LineEdit* description;
00046 Event* event;
00047 bool result;
00048 PG_ListBox* playerlistbox;
00049 PG_PropertyEditor* properties;
00050
00051 GameMap* gamemap;
00052
00053 bool setupEvent()
00054 {
00055 if ( event->action )
00056 event->action->setup();
00057 return true;
00058 }
00059
00060 void actionSelected( int i )
00061 {
00062 if ( i < 0 )
00063 return;
00064
00065 EventActionID eai = eventActionFactory::Instance().getID( actionNames.at(i) );
00066
00067 if ( !event->action )
00068 event->spawnAction( eai );
00069 else
00070 if ( event->action->getActionID() != eai ) {
00071 delete event->action;
00072 event->action = NULL;
00073 event->spawnAction( eai );
00074 }
00075
00076 event->action->setup();
00077 }
00078
00079 bool setupTrigger( int num )
00080 {
00081 if ( event->trigger.size() > num )
00082 if ( event->trigger[num] )
00083 event->trigger[num]->setup();
00084
00085 return true;
00086 }
00087
00088 void triggerSelected( int type, int num )
00089 {
00090 if ( type>= 0 ) {
00091 EventTriggerID triggerID = eventTriggerFactory::Instance().getID( triggerNames.at(type) );
00092
00093 if ( event->trigger.size() <= num ) {
00094 int oldSize = event->trigger.size();
00095 event->trigger.resize(num+1);
00096 for ( int i = oldSize; i < event->trigger.size(); ++i )
00097 if ( i != num )
00098 event->trigger[i] = event->spawnTrigger( Trigger_NothingFalse );
00099
00100 event->trigger[num] = event->spawnTrigger( triggerID );
00101 event->trigger[num]->setup();
00102 } else {
00103 if ( event->trigger[num]->getTriggerID() == triggerID )
00104 event->trigger[num]->setup();
00105 else {
00106 delete event->trigger[num];
00107 event->trigger[num] = event->spawnTrigger( triggerID );
00108 event->trigger[num]->setup();
00109 }
00110 }
00111 }
00112 }
00113
00114 bool invertTrigger( bool invert, int e )
00115 {
00116 if ( event->trigger.size() > e ) {
00117 event->trigger[e]->invert = invert;
00118 return true;
00119 } else
00120 return false;
00121 }
00122
00123
00124 bool ok()
00125 {
00126 if ( !properties->Apply() )
00127 return false;
00128
00129 if ( event->trigger.size() < 1 ) {
00130 warningMessage( "no trigger defined !" );
00131 return false;
00132 }
00133
00134 if ( !event->action ) {
00135 warningMessage ( "no action defined !" );
00136 return false;
00137 }
00138 if ( event->reArmNum && event->delayedexecution.turn < 1 ) {
00139 warningMessage ( "without delayed execution, reArming the event makes no sense !" );
00140 return false;
00141 }
00142
00143 event->description = description->GetText();
00144
00145 if ( triggerConnection->GetSelectedItemIndex() == 0 )
00146 event->triggerConnection = Event::AND;
00147 else
00148 event->triggerConnection = Event::OR;
00149
00150 event->playerBitmap = 0;
00151 for ( int i = 0; i < playerlistbox->GetWidgetCount(); ++i ) {
00152 PG_ListBoxBaseItem* bi = dynamic_cast<PG_ListBoxBaseItem*>(playerlistbox->FindWidget(i));
00153 if ( bi && bi->IsSelected() )
00154 event->playerBitmap |= 1 << i;
00155 }
00156
00157 result = true;
00158 QuitModal();
00159
00160 return true;
00161 }
00162
00163 public:
00164 EventEditor( GameMap* actmap, Event* event ) : ASC_PG_Dialog( NULL, PG_Rect( -1, -1, 700, 500 ), "Edit Event" ), result(false), gamemap(actmap)
00165 {
00166 this->event = event;
00167
00168 int labelWidth = 80;
00169 int ypos = 30;
00170
00171 new PG_Label( this, PG_Rect( 10, ypos, labelWidth, 25 ), "Action:" );
00172
00173 triggerNames = eventTriggerFactory::Instance().getNames();
00174 actionNames = eventActionFactory::Instance().getNames();
00175
00176 eventType = new DropDownSelector( this, PG_Rect( labelWidth+30, ypos, 300, 25 ), actionNames );
00177 if ( event->action )
00178 for ( int i = 0; i < actionNames.size(); ++i )
00179 if ( event->action->getName() == actionNames[i] )
00180 eventType->SelectItem ( i );
00181
00182 eventType->selectionSignal.connect( SigC::slot( *this, &EventEditor::actionSelected ));
00183 (new PG_Button( this, PG_Rect( labelWidth + 50 + 300, ypos, 100, 25 ), "setup"))->sigClick.connect( SigC::slot( *this, &EventEditor::setupEvent ));
00184 ypos += 40;
00185
00186 new PG_Label( this, PG_Rect( 10, ypos, labelWidth, 25 ), "Description:" );
00187 description = new PG_LineEdit( this, PG_Rect( labelWidth+30, ypos, 420, 25 ) );
00188 description->SetText( event->description );
00189 ypos += 40;
00190
00191 for ( int e = 0; e < 4; ++e ) {
00192 new PG_Label( this, PG_Rect( 10, ypos, labelWidth, 25), "Trigger " + ASCString::toString(e));
00193
00194 DropDownSelector* trigger = new DropDownSelector( this, PG_Rect( labelWidth+30, ypos, 200,25 ), triggerNames );
00195
00196 (new PG_Button( this, PG_Rect( labelWidth+50+200, ypos, 100, 25 ), "setup"))->sigClick.connect( SigC::bind( SigC::slot( *this, &EventEditor::setupTrigger ), e));
00197
00198 PG_CheckButton* inv = new PG_CheckButton( this, PG_Rect( labelWidth+70+300, ypos, 100, 25 ), "invert");
00199 inv->sigClick.connect( SigC::bind( SigC::slot( *this, &EventEditor::invertTrigger ), e));
00200 if ( event->trigger.size() > e ) {
00201 if ( event->trigger[e]->invert )
00202 inv->SetPressed();
00203
00204 for ( int i = 0; i < triggerNames.size(); ++i )
00205 if ( event->trigger[e]->getTypeName() == triggerNames[i] )
00206 trigger->SelectItem ( i );
00207 } else
00208 for ( int i = 0; i < triggerNames.size(); ++i )
00209 if ( triggerNames[i] == "Nothing (always false)" )
00210 trigger->SelectItem ( i );
00211
00212 trigger->selectionSignal.connect( SigC::bind( SigC::slot( *this, &EventEditor::triggerSelected), e ));
00213 ypos += 40;
00214 }
00215
00216 new PG_Label( this, PG_Rect( 10, ypos, labelWidth, 25 ), "Players:" );
00217 playerlistbox = (new MultiListBox( this, PG_Rect( labelWidth+30, ypos, 150, 160 )))->getListBox();
00218 for ( int i = 0; i < event->getMap()->getPlayerCount(); ++i ) {
00219 PG_ListBoxItem* item;
00220 if ( gamemap->player[i].exist() )
00221 item = new PG_ListBoxItem( playerlistbox, 20, event->getMap()->player[i].getName() );
00222 else
00223 item = new PG_ListBoxItem( playerlistbox, 20, "inactive player " + ASCString::toString(i) );
00224
00225 if ( event->playerBitmap & (1 << i))
00226 item->Select();
00227 }
00228
00229 properties = new PG_PropertyEditor( this, PG_Rect( labelWidth + 80 + 160, ypos, 150, 160 ));
00230 new PG_PropertyField_Integer<int>( properties, "Rearm Num", &event->reArmNum );
00231 new PG_PropertyField_Integer<int>( properties, "Offset Turn", &event->delayedexecution.turn );
00232 new PG_PropertyField_Integer<int>( properties, "Offset Move", &event->delayedexecution.move );
00233 ypos += 200;
00234
00235
00236 new PG_Label( this, PG_Rect( 10, ypos, labelWidth, 25 ), "Logic:" );
00237 static const char* connectionNames[2] = {"all trigger must be triggered", "only one trigger must be triggered" };
00238 triggerConnection = new DropDownSelector( this, PG_Rect( labelWidth+30, ypos, 300, 25 ), 2, connectionNames );
00239 if ( event->triggerConnection == Event::AND )
00240 triggerConnection->SelectItem( 0 );
00241 else
00242 triggerConnection->SelectItem( 1 );
00243 ypos += 40;
00244
00245
00246 AddStandardButton ( "Cancel" )->sigClick.connect( SigC::slot( *this, &EventEditor::QuitModal ));
00247 AddStandardButton ( "OK" )->sigClick.connect( SigC::slot( *this, &EventEditor::ok ));
00248
00249 };
00250
00251 bool GetResult()
00252 {
00253 return result;
00254 }
00255 };
00256
00257
00258
00259
00260
00261 bool createevent( GameMap* gamemap, Event* event )
00262 {
00263 EventEditor ee ( gamemap, event );
00264 ee.Show();
00265 ee.RunModal();
00266 return ee.GetResult();
00267 }
00268
00269
00270
00271
00272 class EventList : public ASC_PG_Dialog {
00273 private:
00274 GameMap* gamemap;
00275
00276 bool ButtonNew()
00277 {
00278 Event* ev = new Event(*gamemap);
00279 if ( !createevent( gamemap, ev ) ) {
00280 delete ev;
00281 return true;
00282 }
00283
00284 gamemap->events.push_back( ev );
00285
00286 updateListbox();
00287 return true;
00288 }
00289
00290 bool ButtonDelete()
00291 {
00292 int marked = listbox->GetSelectedIndex();
00293 if ( marked < 0 )
00294 return false;
00295
00296 GameMap::Events::iterator e = gamemap->events.begin();
00297 for ( int t = 0; t < marked && e != gamemap->events.end(); t++ )
00298 ++e;
00299
00300 if ( e != gamemap->events.end() ) {
00301 delete *e;
00302 gamemap->events.erase ( e );
00303 updateListbox();
00304 }
00305
00306 return true;
00307 }
00308
00309 bool ButtonEdit()
00310 {
00311 if ( gamemap->events.size() ) {
00312 MemoryStreamStorage buf;
00313
00314
00315 int marked = listbox->GetSelectedIndex();
00316 if ( marked < 0 )
00317 return false;
00318
00319 GameMap::Events::iterator e = gamemap->events.begin();
00320 for ( int t = 0; t < marked && e != gamemap->events.end(); t++ )
00321 ++e;
00322
00323 {
00324 MemoryStream stream ( &buf, tnstream::writing );
00325 (*e)->write ( stream );
00326 }
00327
00328 if ( ! createevent( gamemap, *e ) ) {
00329
00330 MemoryStream stream ( &buf, tnstream::reading );
00331 (*e)->read ( stream );
00332 }
00333
00334 updateListbox();
00335 return true;
00336 } else
00337 return false;
00338
00339 }
00340
00341 bool ButtonOK()
00342 {
00343 QuitModal();
00344 return true;
00345 }
00346
00347 PG_ListBox* listbox;
00348
00349
00350 void updateListbox()
00351 {
00352 listbox->DeleteAll();
00353 for ( GameMap::Events::iterator i = gamemap->events.begin(); i != gamemap->events.end(); ++i ) {
00354 ASCString text = (*i)->action->getName();
00355 text += " - " + (*i)->description;
00356
00357 new PG_ListBoxItem( listbox, 20, text );
00358 }
00359 listbox->Update();
00360 }
00361
00362
00363
00364 public:
00365 EventList( GameMap* gameMap) : ASC_PG_Dialog( NULL, PG_Rect( -1, -1, 600, 400 ), "Edit Events" ) , gamemap ( gameMap )
00366 {
00367 int w = 500;
00368 PG_Button* b = new PG_Button( this, PG_Rect ( w, 40, 90, 25 ), "~N~ew" );
00369 b->sigClick.connect( SigC::slot( *this, &EventList::ButtonNew ));
00370
00371 b = new PG_Button( this, PG_Rect ( w, 80, 90, 25 ), "~E~dit" );
00372 b->sigClick.connect( SigC::slot( *this, &EventList::ButtonEdit ));
00373
00374 b = new PG_Button( this, PG_Rect ( w, 120, 90, 25 ), "~D~elete" );
00375 b->sigClick.connect( SigC::slot( *this, &EventList::ButtonDelete ));
00376
00377 b = new PG_Button( this, PG_Rect ( w, 160, 90, 25 ), "~O~K" );
00378 b->sigClick.connect( SigC::slot( *this, &EventList::ButtonOK ));
00379
00380
00381 listbox = new PG_ListBox( this, PG_Rect( 20, 40, w - 30, Height()-50 ));
00382 listbox->SetTransparency(255);
00383 updateListbox();
00384 };
00385
00386 };
00387
00388
00389 void eventEditor( GameMap* gamemap )
00390 {
00391 EventList te ( gamemap );
00392 te.Show();
00393 te.RunModal();
00394 }
00395
00396