]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into BuddyFriendGuy/mapStringFilter
authorBuddyFriendGuy <bfggeneral@gmail.com>
Fri, 10 Apr 2015 04:13:10 +0000 (00:13 -0400)
committerBuddyFriendGuy <bfggeneral@gmail.com>
Fri, 10 Apr 2015 04:13:10 +0000 (00:13 -0400)
qcsrc/common/mapinfo.qc
qcsrc/common/mapinfo.qh
qcsrc/menu/xonotic/dialog_multiplayer_create.qc
qcsrc/menu/xonotic/maplist.qc
tooltips.db

index c3f15d1937e4963b06a1f6343c0d896c6ac44ce4..b8e35902653047eda3012894529ed11e9ebddcff 100644 (file)
@@ -187,6 +187,32 @@ float MapInfo_FilterGametype(int pGametype, int pFeatures, int pFlagsRequired, i
 
        return 1;
 }
+void MapInfo_FilterString(string sf)
+{
+       // this function further filters _MapInfo_filtered, which is prepared by MapInfo_FilterGametype by string
+       float i, j;
+       string title;
+
+       for(i = 0, j = -1; i < MapInfo_count; ++i)
+       {
+               if (MapInfo_Get_ByID(i))
+               {
+                       // prepare for keyword filter
+                       if (MapInfo_Map_title && strstrofs(MapInfo_Map_title, "<TITLE>", 0) == -1)
+                               title = MapInfo_Map_title;
+                       else
+                               title = MapInfo_Map_bspname;
+                       // keyword filter
+                       if((strstrofs(strtolower(title), strtolower(sf), 0)) >= 0)
+                               bufstr_set(_MapInfo_filtered, ++j, bufstr_get(_MapInfo_filtered, i));
+               }
+       }
+       MapInfo_count = j + 1;
+       MapInfo_ClearTemps();
+
+       // sometimes the glob isn't sorted nicely, so fix it here...
+       heapsort(MapInfo_count, _MapInfo_FilterList_swap, _MapInfo_FilterList_cmp, world);
+}
 
 void MapInfo_Filter_Free()
 {
index 54255ec8d2aa153abfb6da7242d08b3635c40423..021f2feec2da03c8dbfe5255ed84919996d26924 100644 (file)
@@ -118,6 +118,7 @@ void MapInfo_Enumerate();
 // filter the info by game type mask (updates MapInfo_count)
 float MapInfo_progress;
 float MapInfo_FilterGametype(float gametype, float features, float pFlagsRequired, float pFlagsForbidden, float pAbortOnGenerate); // 1 on success, 0 on temporary failure (call it again next frame then; use MapInfo_progress as progress indicator)
+void MapInfo_FilterString(string sf); // filter _MapInfo_filtered (created by MapInfo_FilterGametype) with keyword
 int MapInfo_CurrentFeatures(); // retrieves currently required features from cvars
 int MapInfo_CurrentGametype(); // retrieves current gametype from cvars
 int MapInfo_ForbiddenFlags(); // retrieves current flags from cvars
index 4e76cbc6d3a5095560d41dd71da3bbb969476678..c7961c4f9eab1f0f1f8edfb255da846b7eaf7af0 100644 (file)
@@ -65,6 +65,8 @@ void XonoticServerCreateTab_fill(entity me)
 {
        entity e, e0;
 
+       // the left half begins here
+
        me.gotoRC(me, 0.5, 0);
                me.TD(me, 1, 3, makeXonoticHeaderLabel(_("Gametype")));
        me.TR(me);
@@ -135,6 +137,8 @@ void XonoticServerCreateTab_fill(entity me)
                        e0.textEntity = main.mutatorsDialog;
                        e0.allowCut = 1;
                        //e0.allowWrap = 1;
+
+       me.mapListBox = makeXonoticMapList();
        me.TR(me);
                me.TDempty(me, 0.5);
                me.TD(me, 1, 2, e = makeXonoticButton(_("Mutators"), '0 0 0'));
@@ -142,21 +146,40 @@ void XonoticServerCreateTab_fill(entity me)
                        e.onClickEntity = main.mutatorsDialog;
                        main.mutatorsDialog.refilterEntity = me.mapListBox;
 
+       // The right half begins here
+
        me.gotoRC(me, 0.5, 3.2); me.setFirstColumn(me, me.currentColumn);
-               me.mapListBox = makeXonoticMapList();
+               // the maplistbox
                me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Maplist")));
                        makeCallback(e, me.mapListBox, me.mapListBox.refilterCallback);
        me.TR(me);
-               me.TD(me, me.rows - 4, 3, me.mapListBox);
-       me.gotoRC(me, me.rows - 2.5, 3.2);
-               me.TDempty(me, 0.375);
-               me.TD(me, 1, 1.125, e = makeXonoticButton(_("Select all"), '0 0 0'));
-                       e.onClick = MapList_All;
+               me.TD(me, me.rows - 6, 3, me.mapListBox);
+
+       me.gotoRC(me, me.rows - 3.5, me.firstColumn);
+               // string filter label and box
+               me.TD(me, 1, 0.35, e = makeXonoticTextLabel(1, _("Filter:")));
+               me.mapListBox.stringFilterBox = makeXonoticMapListStringFilterBox(me, 0, string_null);
+               me.mapListBox.stringFilterBox.tooltip = getZonedTooltipForIdentifier("XonoticMultiplayerDialog_StringFilterBox");
+               me.TD(me, 1, me.columns - me.firstColumn - 0.35, e = me.mapListBox.stringFilterBox);
+                       e.onChange = MapList_StringFilterBox_Change;
+                       e.keyDown = MapList_StringFilterBox_keyDown;
+                       e.onChangeEntity = me.mapListBox;
+                       me.mapListBox.controlledTextbox = e;
+
+       me.TR(me);
+               // the selection buttons
+               me.TD(me, 1, 1, e = makeXonoticButton(_("Add shown"), '0 0 0'));
+                       e.onClick = MapList_Add_Shown;
+                       e.onClickEntity = me.mapListBox;
+               me.TD(me, 1, 1, e = makeXonoticButton(_("Remove shown"), '0 0 0'));
+                       e.onClick = MapList_Remove_Shown;
                        e.onClickEntity = me.mapListBox;
-               me.TD(me, 1, 1.125, e = makeXonoticButton(_("Select none"), '0 0 0'));
-                       e.onClick = MapList_None;
+               me.TD(me, 1, 1, e = makeXonoticButton(_("Remove all"), '0 0 0'));
+                       e.onClick = MapList_Remove_All;
                        e.onClickEntity = me.mapListBox;
 
+       // The big button at the bottom
+
        me.gotoRC(me, me.rows - 1, 0);
                me.TD(me, 1, me.columns, e = makeXonoticButton(_("Start Multiplayer!"), '0 0 0'));
                        e.onClick = MapList_LoadMap;
index d88ad0e8e6747beddf8296226b33a7d03fad2289..e06c3084c34a3696318be1661b0474ff79c46dba 100644 (file)
@@ -31,6 +31,9 @@ CLASS(XonoticMapList) EXTENDS(XonoticListBox)
        METHOD(XonoticMapList, g_maplistCacheToggle, void(entity, float))
        METHOD(XonoticMapList, g_maplistCacheQuery, float(entity, float))
 
+       ATTRIB(XonoticMapList, stringFilter, string, string_null)
+       ATTRIB(XonoticMapList, stringFilterBox, entity, NULL)
+
        ATTRIB(XonoticMapList, startButton, entity, NULL)
 
        METHOD(XonoticMapList, loadCvars, void(entity))
@@ -43,8 +46,12 @@ CLASS(XonoticMapList) EXTENDS(XonoticListBox)
        ATTRIB(XonoticListBox, alphaBG, float, 0)
 ENDCLASS(XonoticMapList)
 entity makeXonoticMapList();
-void MapList_All(entity btn, entity me);
-void MapList_None(entity btn, entity me);
+entity makeXonoticMapListStringFilterBox(entity me, float doEditColorCodes, string theCvar);
+void MapList_StringFilterBox_Change(entity box, entity me);
+float MapList_StringFilterBox_keyDown(entity me, float key, float ascii, float shift);
+void MapList_Add_Shown(entity btn, entity me);
+void MapList_Remove_Shown(entity btn, entity me);
+void MapList_Remove_All(entity btn, entity me);
 void MapList_LoadMap(entity btn, entity me);
 #endif
 
@@ -54,6 +61,10 @@ void XonoticMapList_destroy(entity me)
        MapInfo_Shutdown();
 }
 
+entity makeXonoticMapListStringFilterBox(entity me, float doEditColorCodes, string theCvar)
+{
+       return makeXonoticInputBox(doEditColorCodes, theCvar);
+}
 entity makeXonoticMapList()
 {
        entity me;
@@ -62,6 +73,12 @@ entity makeXonoticMapList()
        return me;
 }
 
+entity MapList_Set_String_Filter_Box(entity me, entity e)
+{
+       me.stringFilterBox = e;
+       return e;
+}
+
 void XonoticMapList_configureXonoticMapList(entity me)
 {
        me.configureXonoticListBox(me);
@@ -73,6 +90,7 @@ void XonoticMapList_loadCvars(entity me)
        me.refilter(me);
 }
 
+
 float XonoticMapList_g_maplistCacheQuery(entity me, float i)
 {
        return stof(substring(me.g_maplistCache, i, 1));
@@ -203,7 +221,10 @@ void XonoticMapList_refilter(entity me)
        gt = MapInfo_CurrentGametype();
        f = MapInfo_CurrentFeatures();
        MapInfo_FilterGametype(gt, f, MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
+       if (me.stringFilter)
+               MapInfo_FilterString(me.stringFilter);
        me.nItems = MapInfo_count;
+
        for(i = 0; i < MapInfo_count; ++i)
                draw_PreloadPicture(strcat("/maps/", MapInfo_BSPName_ByID(i)));
        if(me.g_maplistCache)
@@ -236,19 +257,43 @@ void XonoticMapList_refilterCallback(entity me, entity cb)
        me.refilter(me);
 }
 
-void MapList_All(entity btn, entity me)
+void MapList_StringFilterBox_Change(entity box, entity me)
 {
-       float i;
-       string s;
-       MapInfo_FilterGametype(MAPINFO_TYPE_ALL, 0, 0, MapInfo_ForbiddenFlags(), 0); // all
-       s = "";
-       for(i = 0; i < MapInfo_count; ++i)
-               s = strcat(s, " ", MapInfo_BSPName_ByID(i));
-       cvar_set("g_maplist", substring(s, 1, strlen(s) - 1));
+       if(me.stringFilter)
+               strunzone(me.stringFilter);
+       if(box.text != "")
+               me.stringFilter = strzone(box.text);
+       else
+               me.stringFilter = string_null;
+       
+       me.refilter(me);
+}
+
+void MapList_Add_Shown(entity btn, entity me)
+{
+       float i, n;
+       n = strlen(me.g_maplistCache);
+       for (i = 0 ; i < n; i++)
+       {
+               if (!me.g_maplistCacheQuery(me, i))
+                       me.g_maplistCacheToggle(me, i);
+       }
+       me.refilter(me);
+}
+
+void MapList_Remove_Shown(entity btn, entity me)
+{
+       float i, n;
+       n = strlen(me.g_maplistCache);
+       for (i = 0 ; i < n; i++)
+       {
+               if (me.g_maplistCacheQuery(me, i))
+                       me.g_maplistCacheToggle(me, i);
+       }
        me.refilter(me);
 }
 
-void MapList_None(entity btn, entity me)
+void MapList_Remove_All(entity btn, entity me)
 {
        cvar_set("g_maplist", "");
        me.refilter(me);
@@ -357,9 +402,38 @@ float XonoticMapList_keyDown(entity me, float scan, float ascii, float shift)
                if(MapInfo_FindName_firstResult >= 0)
                        me.setSelected(me, MapInfo_FindName_firstResult);
        }
+       else if(shift & S_CTRL && scan == 'f') // ctrl-f (as in "F"ind)
+       {
+               me.parent.setFocus(me.parent, me.stringFilterBox);
+       }
+       else if(shift & S_CTRL && scan == 'u') // ctrl-u (remove stringFilter line
+       {
+               me.stringFilterBox.setText(me.stringFilterBox, "");
+               MapList_StringFilterBox_Change(me.stringFilterBox, me);
+       }
        else
                return SUPER(XonoticMapList).keyDown(me, scan, ascii, shift);
        return 1;
 }
 
+float MapList_StringFilterBox_keyDown(entity me, float scan, float ascii, float shift)
+{
+       // in this section, note that onChangeEntity has the ref to mapListBox
+       // we make use of that, instead of extending a class to add one more attrib
+       switch(scan)
+       {
+               case K_KP_ENTER:
+               case K_ENTER:
+                       // move the focus to the mapListBox
+                       me.onChangeEntity.parent.setFocus(me.onChangeEntity.parent, me.onChangeEntity);
+                       return 1;
+               case K_KP_UPARROW:
+               case K_UPARROW:
+               case K_KP_DOWNARROW:
+               case K_DOWNARROW:
+                       // pass the event to the mapListBox (to scroll up and down)
+                       return me.onChangeEntity.keyDown(me.onChangeEntity, scan, ascii, shift);
+       }
+       return SUPER(XonoticInputBox).keyDown(me, scan, ascii, shift);
+}
 #endif
index a0c06485b20cb4b950049f05c5bc00ed9a5be66c..57e22b998a52d6420e2dbdc6fac8b20b85e31cb4 100644 (file)
 \g_instagib\Players will be given the Minstanex, which is a railgun with infinite damage. If the player runs out of ammo, he will have 10 seconds to find some or if he fails to do so, face death. The secondary fire mode is a laser which does not inflict any damage and is good for doing trickjumps.
 \g_nix\No items Xonotic - instead of pickup items, everyone plays with the same weapon. After some time, a countdown will start, after which everyone will switch to another weapon.
 \g_nix_with_laser\Always carry the laser as an additional weapon in Nix
-\XonoticMultiplayerDialog/Select all\Select all maps
-\XonoticMultiplayerDialog/Select none\Unselect all maps
+
+\XonoticMultiplayerDialog_StringFilterBox\Click here or Ctrl-F to provide a keyword to narrow down the maplist above. Ctrl-Delete to clear; Enter when done.
+\XonoticMultiplayerDialog/Add shown\Add the maps shown in Maplist above to your selection
+\XonoticMultiplayerDialog/Remove shown\Remove the maps shown in Maplist above from your selection
+\XonoticMultiplayerDialog/Remove all\Remove all the maps from your selection
 
 
 \XonoticMultiplayerDialog/Timedemo\Benchmark how fast your computer can run the highlighted demo