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