]> icculus.org git repositories - divverent/nexuiz.git/blob - scmenu/source/custom/creategame/maps.qc
Wazat's menu
[divverent/nexuiz.git] / scmenu / source / custom / creategame / maps.qc
1 // Property of Alientrap/AK
2 // custom/creategame/maps.qc
3
4 /*
5 ===================
6 Item_Nex_Map_Info
7 ===================
8 */
9
10 /*
11 ===================
12 Item_Nex_Map_Info_Destroy
13 ===================
14 */
15 void() Item_Nex_Map_Info_Destroy =
16 {
17         String_EntityFree( self, link );
18         String_EntityFree( self, picture );
19         String_EntityFree( self, text );
20         String_EntityFree( self, normal );
21 };
22
23 /*
24 ===================
25 Item_Nex_Map_Info_Spawn
26 ===================
27 */
28 void() Item_Nex_Map_Info_Spawn =
29 {
30         String_EntityZone( self, link );
31         String_EntityZone( self, picture );
32         String_EntityZone( self, text );
33         String_EntityZone( self, normal );
34
35         Gfx_Precache( self.picture );
36
37         self._destroy = Item_Nex_Map_Info_Destroy;
38 };
39
40 /*
41 ===================
42 Item_Nex_MapDB
43 ===================
44 */
45 string _Nex_MapList_FullPath;
46 string _Nex_MapList_Name;
47 entity _Nex_MapList_Root;
48
49
50
51
52 /*
53 ===================
54 Nex_MapDB_RefreshFiles
55 ===================
56 */
57
58         /*  fixme:
59
60 <Black> use a switch for gametypes
61 <Black> and just set the action field to Nex_MapDB_RefreshFiles
62
63 <Black> Better to write a new action function though..
64 <Black> And call Nex_Action_TestOnChange to set the Data value
65 <Black> then set up the filter and then call RefreshFiles
66 <Black> or if you put the filter handling into RefrehFiles just call TestOnChange and then RefreshFiles
67         */
68
69
70 void() Nex_MapDB_RefreshFiles =
71 {
72         local entity oldself;
73         oldself = self;
74
75         Nex_Action_TestOnChange();
76
77         Menu_EmptyWindow( _Nex_MapList_Root );
78
79         String_Free( _Nex_MapList_FullPath );
80         String_Free( _Nex_MapList_Name );
81         _Nex_MapList_FullPath = String_Create();
82         _Nex_MapList_Name = String_Create();
83
84         self = _Nex_MapList_Root;
85         Item_Nex_MapDB_EnumFiles();
86
87
88         self = Menu_GetItem( "::Data::Server::Map::Selector" );
89         Item_DataLink_Nex_MapList_InitWithMapList();
90         //DataLink_Nex_MapList_UpdateRange(self);
91         //Item_DataLink_Nex_MapList_Load();
92
93
94         // fixme: need to change which map the map selector is pointing to right now
95
96         Raise_DataEvent( self, ITEM_DATALINK_GET );
97         if(self._realValue > self.maxValue)
98                 self._realValue = self.maxValue;
99         Raise_DataEvent( self, ITEM_DATALINK_SET );
100
101         //Nex_MapSelector_UpdateMap();
102         //Nex_MapSelector_Synchronize();
103
104
105         self = oldself; 
106 };
107
108 /*
109 ===================
110 Item_Nex_MapDB_EnumFiles
111 ===================
112 */
113 // map definition format
114 // name
115 // rest: description text
116 void() Item_Nex_MapDB_EnumFiles =
117 {
118         local float     lSearchHandle;
119         local float     lSearchSize;
120         local float     lSearchCounter;
121         local entity    lMap;//, lMapType;
122         local string    map_query;
123         local float     lMapType;
124
125         lMapType = cvar("menu_map_type");
126         //lMapType = Menu_GetItem( "::Data::Server::MapType" );
127         if(lMapType == 6)//.value == "Rune Match")
128         {
129                 map_query = "maps/rune_*.mapcfg";
130         }
131         else if(lMapType == 5)//.value == "CTF")
132         {
133                 map_query = "maps/ctf_*.mapcfg";
134         }
135         else if(lMapType == 4)//.value == "Domination")
136         {
137                 map_query = "maps/dom_*.mapcfg";
138         }
139         else if(lMapType == 3)//.value == "Team Deathmatch")
140         {
141                 map_query = "maps/tdm_*.mapcfg";
142         }
143         else if(lMapType == 2)//.value == "Classic Deathmatch")
144         {
145                 map_query = "maps/dm_*.mapcfg";
146         }
147         else // list all
148         {
149                 map_query = "maps/*.mapcfg";
150         }
151
152
153         lSearchHandle = search_begin( map_query, true, true ); // "maps/*.mapcfg"
154         if( lSearchHandle < 0 )
155                 return;
156         for( lSearchSize = search_getsize( lSearchHandle ), lSearchCounter = 0;
157         lSearchCounter < lSearchSize; ++lSearchCounter ) {
158                 local float     lHandle;
159
160                 local string    lFilename;
161                 local string    lStripped;
162                 local string    lPic;
163                 local string    lName;
164                 local string    lDescription;
165                 local string    lTitle;
166
167                 lFilename = search_getfilename( lSearchHandle, lSearchCounter );
168                 lStripped = String_Zone( substring( lFilename, 0, strlen( lFilename ) - 7 ) ); // - 4
169                 lName = String_Zone( substring( lStripped, 5, 100000 ) );
170
171                 lHandle = fopen( strcat( lStripped, ".txt" ), FILE_READ );
172                 if( lHandle < 0 ) {
173                         lTitle = String_Zone( lName );
174                         lDescription = String_Zone( strcat( "--NO INFORMATION AVAILABLE--\n", lFilename ) );
175                 } else {
176                         // uncomment this line and comment the other if you have the old map info files
177                         //lTitle = String_Zone( lName );
178                         lTitle = String_Zone( fgets( lHandle ) );
179                         lPic = fgets( lHandle ); // also get picture
180                         if(lPic)
181                         {
182                                 lStripped = String_Zone( lPic );
183                         }
184
185                         lDescription = String_Create();
186                         do {
187                                 local string lLine;
188
189                                 lLine = fgets( lHandle );
190                                 lDescription = String_Append( lDescription, strcat( lLine, "\n" ) );
191                         } while( validstring( lLine ) );
192
193                         fclose( lHandle );
194                 }
195
196                 // save this in a new Map_Info
197                 lMap = Menu_CreateItem( "Item_Nex_Map_Info", ftos( lSearchCounter ), self.name );
198
199                 lMap.link = lName;
200                 // check the picture
201                 if( Gfx_Precache( lStripped ) ) {
202                         lMap.picture = lStripped;
203                 } else {
204                         lMap.picture = "gfx/m_nomap";
205                 }
206                 lMap.normal = lTitle;
207                 lMap.text = lDescription;
208
209                 _Nex_MapList_FullPath = Util_AltStringPushBack( _Nex_MapList_FullPath, lName );
210                 _Nex_MapList_Name = Util_AltStringPushBack( _Nex_MapList_Name, lTitle );
211
212                 Menu_LinkItem( lMap );
213
214                 String_Free( lTitle );
215                 String_Free( lName );
216                 String_Free( lStripped );
217                 String_Free( lDescription );
218         }
219
220         search_end( lSearchHandle );
221
222         Menu_LinkChildren( self );
223
224         self.minValue = 1;
225         self.stepValue = 1;
226         self.maxValue = fabs( lMap.orderPos );
227 };
228
229 /*
230 ===================
231 Item_Nex_MapDB_Destroy
232 ===================
233 */
234 void() Item_Nex_MapDB_Destroy =
235 {
236         String_Free( _Nex_MapList_FullPath );
237         String_Free( _Nex_MapList_Name );
238
239         _Nex_MapList_Root = null_entity;
240 };
241
242 /*
243 ===================
244 Item_Nex_MapDB_Spawn
245 ===================
246 */
247 void() Item_Nex_MapDB_Spawn =
248 {
249         if( _Nex_MapList_Root )
250                 error( "There is already another Item_Nex_MapDB object!" );
251
252         _Nex_MapList_FullPath = String_Create();
253         _Nex_MapList_Name = String_Create();
254         _Nex_MapList_Root = self;
255
256         Item_Nex_MapDB_EnumFiles();
257
258         self._destroy = Item_Nex_MapDB_Destroy;
259 };
260
261 /*
262 ===================
263 Nex_MapDB_GetByName
264 ===================
265 */
266 entity( string pPath ) Nex_MapDB_GetByPath =
267 {
268         local entity lNode;
269
270         if( !_Nex_MapList_Root )
271                 error( "No Item_Nex_MapDB found!" );
272
273         for( lNode = _Nex_MapList_Root._child ; lNode ; lNode = lNode._next ) {
274                 if( lNode.link == pPath ) {
275                         return lNode;
276                 }
277         }
278
279         return null_entity;
280 };
281
282 /*
283 ===================
284 Nex_MapDB_GetByIndex
285 ===================
286 */
287 entity( float pIndex ) Nex_MapDB_GetByIndex =
288 {
289         local entity lNode;
290
291         if( !_Nex_MapList_Root )
292                 error( "No Item_Nex_MapDB found!" );
293
294         pIndex = fabs( pIndex );
295         for( lNode = _Nex_MapList_Root._child ; lNode ; lNode = lNode._next ) {
296                 if( fabs( lNode.orderPos ) == pIndex ) {
297                         return lNode;
298                 }
299         }
300
301         return null_entity;
302 };
303
304 /*
305 ===================
306 Nex_MapDB_GetPathAltString
307 ===================
308 */
309 string() Nex_MapDB_GetPathAltString =
310 {
311         return _Nex_MapList_FullPath;
312 };
313
314 /*
315 ===================
316 Nex_MapDB_GetNameAltString
317 ===================
318 */
319 string() Nex_MapDB_GetNameAltString =
320 {
321         return _Nex_MapList_Name;
322 };
323
324 /*
325 ===================
326 Nex_MapDB_GetIndex
327 ===================
328 */
329 float( entity pItem ) Nex_MapDB_GetIndex =
330 {
331         return fabs( pItem.orderPos );
332 };
333
334 void() Item_DataLink_Nex_MapList_Save =
335 {
336         local float lCount;
337         local float lIndex;
338         local string lOutput;
339
340         lOutput = String_Create();
341
342         lCount = Util_GetAltStringCount( self.valueList );
343         for( lIndex = 0 ; lIndex < lCount ; lIndex++ ) {
344                 lOutput = String_Append( lOutput, strcat( "\'", String_Normal( Util_GetAltStringItem( self.valueList, lIndex ) ), "\'" ) );
345         }
346
347         cvar_set( self.cvarName, lOutput );
348         cvar_set( strcat( self.cvarName, "_index" ), "0" );
349
350         String_Free( lOutput );
351 };
352
353 void() Item_DataLink_Nex_MapList_Load =
354 {
355         local string lEntry;
356         local entity lMapInfo;
357         local float lCounter;
358         local float lCount;
359
360         DataLink_Nex_MapList_Clear( self );
361
362         lCount = tokenize( cvar_string( self.cvarName ) );
363
364         lEntry = String_Create();
365         for( lCounter = 0 ; lCounter < lCount ; lCounter++ ) {
366                 lEntry = String_Set( lEntry, argv( lCounter ) );
367
368                 lMapInfo = Nex_MapDB_GetByPath( lEntry );
369                 if( lMapInfo == null_entity ) {
370                         print( self.cvarName, ": Map '", lEntry, "' not found in database - ignored\n" );
371                         continue;
372                 }
373
374                 self.descList = Util_AltStringPushBack( self.descList, lMapInfo.normal );
375                 self.valueList = Util_AltStringPushBack( self.valueList, lMapInfo.link );
376         }
377         String_Free( lEntry );
378
379         DataLink_Nex_MapList_UpdateRange( self );
380         Nex_MapSelector_Synchronize();
381 };
382
383 void() Item_DataLink_Nex_MapList_ExecString =
384 {
385         local float lCount;
386         local float lIndex;
387
388         Data_ExecString = String_Append( Data_ExecString, strcat( "set \"", self.cvarName, "_index\" \"0\"\nset \"", self.cvarName, "\" \"" ) );
389
390         lCount = Util_GetAltStringCount( self.valueList );
391         for( lIndex = 0 ; lIndex < lCount ; lIndex++ ) {
392                 Data_ExecString = String_Append( Data_ExecString, strcat( "\'", String_Normal( Util_GetAltStringItem( self.valueList, lIndex ) ), "\'" ) );
393         }
394
395         Data_ExecString = String_Append( Data_ExecString, "\"\n" );
396 };
397
398 /*
399 ===================
400 Item_DataLink_Nex_MapList_DataEvent
401 ===================
402 */
403 void( float pEvent ) Item_DataLink_Nex_MapList_DataEvent =
404 {
405         switch( pEvent ) {
406         case ITEM_DATA_SYNC:
407                 if( self.cvarName != "" ) {
408                         Item_DataLink_Nex_MapList_Load();
409                 }
410                 break;
411         case ITEM_DATA_SEND:
412                 if( self.cvarName != "" ) {
413                         Item_DataLink_Nex_MapList_Save();
414                 }
415                 break;
416         case ITEM_DATA_RESET:
417                 self._realValue = 1.0;
418                 break;
419         case ITEM_DATA_TEST_START:
420                 break;
421         case ITEM_DATA_TEST_END:
422                 break;
423         case ITEM_DATA_SAVE_EXECSTRING:
424                 if( self.cvarName != "" ) {
425                         Item_DataLink_Nex_MapList_ExecString();
426                 }
427                 break;
428         case ITEM_DATALINK_SET:
429         case ITEM_DATALINK_GET:
430                 self._realValue = floor( self._realValue );
431                 if( self._realValue < 1.0 ) {
432                         self._realValue = 1.0;
433                 } else if( self._realValue > self.maxValue ) {
434                         self._realValue = self.maxValue;
435                 }
436
437                 break;
438         }
439 };
440
441 void() IDLNML_Reinit =
442 {
443         Raise_DataEvent( self, ITEM_DATA_SYNC );
444 };
445
446 /*
447 ===================
448 Item_DataLink_Nex_MapList_Destroy
449 ===================
450 */
451 void() Item_DataLink_Nex_MapList_Destroy =
452 {
453         String_EntityFree( self, valueList );
454         String_EntityFree( self, cvarName );
455
456         Item_DataLink_Switch_Destroy();
457 };
458
459 /*
460 ===================
461 Item_DataLink_Nex_MapList_Spawn
462 ===================
463 */
464 void() Item_DataLink_Nex_MapList_Spawn =
465 {
466         Item_DataLink_Switch_Init();
467         String_EntityZone( self, valueList );
468         String_EntityZone( self, cvarName );
469
470         if( self.cvarName != "" ) {
471                 registercvar( self.cvarName, "", CVAR_SAVE );
472                 registercvar( strcat( self.cvarName, "_index" ), "", CVAR_SAVE );
473         }
474
475         self.minValue = 1.0;
476         self.maxValue = 1.0;
477         self.stepValue = 0.0;
478
479         self._reinit = IDLNML_Reinit;
480         self._dataEvent = Item_DataLink_Nex_MapList_DataEvent;
481         self._destroy = Item_DataLink_Nex_MapList_Destroy;
482
483         CtCall_Init();
484 };
485
486 /*
487 ===================
488 Item_DataLink_Nex_MapList_InitWithMapList
489 ===================
490 */
491 void() Item_DataLink_Nex_MapList_InitWithMapList =
492 {
493         String_EntitySet( self, valueList, Nex_MapDB_GetPathAltString() );
494         String_EntitySet( self, descList, Nex_MapDB_GetNameAltString() );
495
496         DataLink_Nex_MapList_UpdateRange( self );
497 };
498
499 /*
500 ===================
501 DataLink_Nex_MapList_UpdateRange
502 ===================
503 */
504 void( entity pItem ) DataLink_Nex_MapList_UpdateRange =
505 {
506         pItem.minValue = 1.0;
507         pItem.maxValue = Util_GetAltStringCount( pItem.descList );
508
509         if( pItem.maxValue >= 1 ) {
510                 pItem.stepValue = 1.0;
511         } else {
512                 pItem.maxValue = 1.0;
513                 pItem.stepValue = 0.0;
514         }
515 };
516
517 /*
518 ===================
519 DataLink_Nex_MapList_InsertEntryAfter
520 ===================
521 */
522 void( entity pItem, string pName, string pPath ) DataLink_Nex_MapList_InsertEntryAfter =
523 {
524         local float lIndex;
525
526         Raise_DataEvent( pItem, ITEM_DATALINK_GET );
527         // - 1, because minValue == 1
528         lIndex = pItem._realValue - 1;
529         pItem.descList = Util_InsAltStringItem( pItem.descList, lIndex, pName );
530         pItem.valueList = Util_InsAltStringItem( pItem.valueList, lIndex, pPath );
531
532         DataLink_Nex_MapList_UpdateRange( pItem );
533 };
534
535 /*
536 ===================
537 DataLink_Nex_MapList_DeleteEntry
538 ===================
539 */
540 void( entity pItem ) DataLink_Nex_MapList_DeleteEntry =
541 {
542         local float lIndex;
543
544         if( pItem.stepValue == 0.0 )
545                 return;
546
547         Raise_DataEvent( pItem, ITEM_DATALINK_GET );
548         lIndex = pItem._realValue - 1;
549         pItem.descList = Util_DelAltStringItem( pItem.descList, lIndex );
550         pItem.valueList = Util_DelAltStringItem( pItem.valueList, lIndex );
551
552         DataLink_Nex_MapList_UpdateRange( pItem );
553 };
554
555 /*
556 ===================
557 DataLink_Nex_MapList_MoveEntryUp
558 ===================
559 */
560 void( entity pItem ) DataLink_Nex_MapList_MoveEntryUp =
561 {
562         local string lName;
563         local string lPath;
564         local float lIndexNew;
565         local float lIndexOld;
566
567         Raise_DataEvent( pItem, ITEM_DATALINK_GET );
568         if( pItem._realValue == 1 )
569                 return;
570
571         // map 1..n to 0..n-1
572         lIndexOld = pItem._realValue - 1;
573
574         // we want to insert it up by one, ie. insert it after up by two
575         lIndexNew = lIndexOld - 2;
576
577         lName = Util_GetAltStringItem( pItem.descList, lIndexOld );
578         lPath = Util_GetAltStringItem( pItem.valueList, lIndexOld );
579
580         pItem.descList = Util_InsAltStringItem( pItem.descList, lIndexNew, String_Normal( lName ) );
581         pItem.valueList = Util_InsAltStringItem( pItem.valueList, lIndexNew, String_Normal( lPath ) );
582
583         // adjust lIndexOld for the entry that has been inserted before it
584         lIndexOld = lIndexOld + 1;
585
586         pItem.descList = Util_DelAltStringItem( pItem.descList, lIndexOld );
587         pItem.valueList = Util_DelAltStringItem( pItem.valueList, lIndexOld );
588
589         DataLink_Nex_MapList_UpdateRange( pItem );
590 };
591
592 /*
593 ===================
594 DataLink_Nex_MapList_MoveEntryDown
595 ===================
596 */
597 void( entity pItem ) DataLink_Nex_MapList_MoveEntryDown =
598 {
599         local string lName;
600         local string lPath;
601         local float lIndexNew;
602         local float lIndexOld;
603
604         Raise_DataEvent( pItem, ITEM_DATALINK_GET );
605         if( pItem._realValue == pItem.maxValue )
606                 return;
607
608         // map 1..n to 0..n-1
609         lIndexOld = pItem._realValue - 1;
610
611         // we want to insert it down by one
612         lIndexNew = lIndexOld + 1;
613
614         lName = Util_GetAltStringItem( pItem.descList, lIndexOld );
615         lPath = Util_GetAltStringItem( pItem.valueList, lIndexOld );
616
617         pItem.descList = Util_InsAltStringItem( pItem.descList, lIndexNew, String_Normal( lName ) );
618         pItem.valueList = Util_InsAltStringItem( pItem.valueList, lIndexNew, String_Normal( lPath ) );
619
620         pItem.descList = Util_DelAltStringItem( pItem.descList, lIndexOld );
621         pItem.valueList = Util_DelAltStringItem( pItem.valueList, lIndexOld );
622
623         DataLink_Nex_MapList_UpdateRange( pItem );
624 };
625
626 /*
627 ===================
628 DataLink_Nex_MapList_SetFirst
629 ===================
630 */
631 void( entity pItem, string pName, string pPath ) DataLink_Nex_MapList_SetFirst =
632 {
633         if( pItem.stepValue == 0.0 ) {
634                 pItem.descList = Util_AltStringPush( pItem.descList, pName );
635                 pItem.valueList = Util_AltStringPush( pItem.valueList, pPath );
636         } else {
637                 pItem.descList = Util_SetAltStringItem( pItem.descList, 0, pName );
638                 pItem.valueList = Util_SetAltStringItem( pItem.valueList, 0, pPath );
639         }
640
641         DataLink_Nex_MapList_UpdateRange( pItem );
642 };
643
644 /*
645 ===================
646 DataLink_Nex_MapList_Clear
647 ===================
648 */
649 void( entity pItem ) DataLink_Nex_MapList_Clear =
650 {
651         String_EntitySet( pItem, descList, "" );
652         String_EntitySet( pItem, valueList, "" );
653
654         DataLink_Nex_MapList_UpdateRange( pItem );
655 };
656
657 /*
658 ===================
659 DataLink_Nex_MapList_GetCurrentName
660 ===================
661 */
662 string( entity pItem ) DataLink_Nex_MapList_GetCurrentName =
663 {
664         Raise_DataEvent( pItem, ITEM_DATALINK_GET );
665         return Util_GetAltStringItem( pItem.descList, pItem._realValue - 1 );
666 };
667
668 /*
669 ===================
670 DataLink_Nex_MapList_GetCurrentPath
671 ===================
672 */
673 string( entity pItem ) DataLink_Nex_MapList_GetCurrentPath =
674 {
675         Raise_DataEvent( pItem, ITEM_DATALINK_GET );
676         return Util_GetAltStringItem( pItem.valueList, pItem._realValue - 1 );
677 };