Objects by Category
#1

This may or may not be the right place for this but whatever.
I'm trying to sort a list of objects by the category they're in (Like MTA).

I swore I saw an include that had something like that a few years ago but I can't seem to find it anywhere. Just wondering if anyone knew what it was/a simple way to sort the objects.
Reply
#2

There's a few ways you can do this. You need arrays for all of them. Here's how I would do it by preference:

First, create an enumerator with all categories you want to list, and make an array for your category names using the constants from the enum.

pawn Код:
enum {
    // We make a bunch of constants so that
    // we can call them later under functions
    // and to address the appropiate index(es).

    CAT_BAR_ITEMS,
    CAT_SHOP_ITEMS

    // and so on
} ;

enum E_CATEGORY_DATA {

    E_CAT_NAME [ 32 ],
    E_CAT_DESC [ 64 ],
    E_CAT_CONST
} ;

// Shows category names with a description. Could be used in dialogs, but isn't even mandatory.
// Only included this since you refered to MTA, and this is one of the ways you can use to attain it.
new Categories [ ] [ E_CATEGORY_DATA ] = {

    { "Bar Items", "All items used in bars", CAT_BAR_ITEMS },
    { "Shop Items", "All items used in shops", CAT_SHOP_ITEMS }

    // and so on
} ;
Showing is as simple as doing this:

pawn Код:
ShowCategoryList () {

    new string [ 128 * sizeof ( Categories ) ] ;

    for ( new i; i < sizeof ( Categories ); i ++ ) {

        // Do whatever you want with the data now:
        format ( string, sizeof ( string ), "[%d] %s: %s",
            i, Categories [ i ] [ E_CAT_NAME ], Categories [ i ] [ E_CAT_DESC ] ) ;
    }

    return string ;
}
Assuming you're gonna put these in a dialog, you can simply pass "listitem" as the param needed for the category contents. Here's an example:

pawn Код:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) {

    if ( dialogid == DIALOG_CATEGORY_LIST ) {

        if ( response ) {

            ShowCategoryItems ( playerid, listitem ) ;
        }

    }

    return false ;
}
This shouldn't return a runtime, as long as you keep the size of the array and the constant enum the same.

Instead, create a new constant for each entry you add. The way we pull the list of items to add under specific categories is by matching the category_id, so if you re-use the constant it's not going to work anyway.

Here's the ShowCategoryItems function, with the array setup:

pawn Код:
enum E_CATEGORY_ITEMS {

    E_CAT_CONST,
    E_CAT_OBJECT,
    E_CAT_NAME [ 32 ]
} ;

new CategoryData [ ] [ E_CATEGORY_ITEMS ] = {

    { CAT_BAR_ITEMS, 1330, "Object name for bar_items #1" },
    { CAT_BAR_ITEMS, 1331, "Object name for bar_items #2" },
    { CAT_BAR_ITEMS, 1332, "Object name for bar_items #3" },
    { CAT_BAR_ITEMS, 1333, "Object name for bar_items #4" },


    { CAT_SHOP_ITEMS, 1334, "Object name for shop_items #1" },
    { CAT_SHOP_ITEMS, 1335, "Object name for shop_items #2" },
    { CAT_SHOP_ITEMS, 1336, "Object name for shop_items #3" },
    { CAT_SHOP_ITEMS, 1337, "Object name for shop_items #4" }
} ;

ShowCategoryItems ( playerid, category_id ) {

    // Not the most resourceful way, If you're set on making it more "efficient", write a new function that gets the amount of indexes and use it in your loop or do something else. It's only an example.

    for ( new i; i < sizeof ( CategoryData ); i ++ ) {

        if ( CategoryData [ i ] [ E_CAT_CONST ] == category_id ) {

            /*  
                Since we have an index now, we can use the array accordingly now:

                    CategoryData [ i ] [ E_CAT_OBJECT ]
                    CategoryData [ i ] [ E_CAT_NAME ]

                Put it in a string, dialog, or smth else
            */

        }

        else continue ;
    }

    return true ;
}

You can also do it this way, by creating seperate arrays and then calling them accordingly. The header stays the same:

pawn Код:
enum E_CATEGORY_ITEM_DATA {

    E_CAT_ITEM_NAME [ 32 ],
    E_CAT_ITEM_OBJECT [ 32 ]
} ;

new Category_ShopItems [ ] [ E_CATEGORY_ITEM_DATA ] = {

    { "Shop item 1", 1337 },
    { "Shop item 2", 1338 },
    { "Shop item 3", 1339 },
    { "Shop item 4", 1340 }
} ;

new Category_BarItems [ ] [ E_CATEGORY_ITEM_DATA ] = {

    { "Bar item 1", 1337 },
    { "Bar item 2", 1338 },
    { "Bar item 3", 1339 },
    { "Bar item 4", 1340 }
} ;

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) {

    if ( dialogid == DIALOG_CATEGORY_LIST ) {

        if ( response ) {

            switch ( listitem ) {

                case CAT_BAR_ITEMS: {

                    for ( new i; i < sizeof ( Category_BarItems ); i ++) {

                        // Category_BarItems [ i ] [ E_CAT_ITEM_NAME ],
                        // Category_BarItems [ i ] [ E_CAT_ITEM_OBJECT ],
                    }
                }
                case CAT_SHOP_ITEMS: {

                    for ( new i; i < sizeof ( Category_ShopItems ); i ++) {

                        // Category_ShopItems [ i ] [ E_CAT_ITEM_NAME ],
                        // Category_ShopItems [ i ] [ E_CAT_ITEM_OBJECT ],
                    }
                }
            }
        }
    }

    return false ;
}
Reply
#3

Appreciated, though there's thousands of objects and I don't feel like sorting through them. I know i saw a script with them organized before I just can't find it now.
Reply
#4

EDIT:

http://www.gamerxserver.com/ObjectsByCategory.php

Click on the headers and it will parse all the data.

EDIT 2: Here's an example: https://pastebin.com/raw/D0cFTX97
Reply
#5

That's exactly what I needed, thanks!
Reply
#6

http://github.com/Naseband/SAMP-MapD.../master/OC.inc

Same categories, however this also includes all SAMP Objects (if you need them).
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)