Page 1 of 1

Help With StringHash

Posted: Sat Dec 29, 2012 2:13 pm
by Ian
I'm messing around with some ways to make an inventory based menu system. In a few tests, I'm using the function StringHash to save menu labels as integers.

The NewMenu function takes the menu label as a string, and uses StringHash to convert the string into an integer so it can be stored in the "Data" integer variable.
The GetMenu function takes the menu label as a string, uses StringHash on the label given, and then compares it to integers stored in the "Data" integer variable.

For some reason, the integer value given on my second menu's StringHash when using "NewMenu" is not the same when I search for it using "GetMenu". I've tried with several different strings, but the same problem occurs.

I want to know if this is a bug, or if I've overlooked something.

The map is available upon request.

Code: Select all

library MenuSystem initializer onInit uses MenuItemFuncs
    globals
        private constant integer ESC = 'I00B'
        private integer array Data
        private constant integer MENU_MAX = 21
        private integer Total = 0
        //Menu (0)
        //Items1-6 (1-6)
        //Childs1-6 (7-12)
        //Prot1-6 (13-18)
        //Parent Menu (19)
        //Total Items (20)
    endglobals
    private function NewMenu takes string label returns integer
        set Data[Total*MENU_MAX]=StringHash(label)
        static if DEBUG then
            call DebugMsg("(function NewMenu):  "+label+"__"+I2S(Data[Total*MENU_MAX])+"__")
            call DebugMsg("(function NewMenu):  "+I2S(StringHash(label))+"__"+I2S(Data[Total*MENU_MAX])+"__")
        endif
        set Total = Total + 1
        return Total-1
    endfunction
    private function MenuAddItem takes integer whichMenu, integer itemId,  integer whichSlot, integer childMenu, string itemProtocol returns nothing
        static if DEBUG then
            local integer i
        endif
        set Data[(whichMenu+1)*MENU_MAX]=Data[(whichMenu+1)*MENU_MAX]+1
        set Data[whichMenu*MENU_MAX+Data[(whichMenu+1)*MENU_MAX]+whichSlot]=itemId
        set Data[whichMenu*MENU_MAX+6+Data[(whichMenu+1)*MENU_MAX]+whichSlot]=childMenu
        if itemProtocol == "" then
            set Data[whichMenu*MENU_MAX+12+Data[(whichMenu+1)*MENU_MAX]+whichSlot]=ERROR_INTEGER
            return
        endif
        static if DEBUG then
            set i = GetMenuItemProtocol(itemProtocol)
            if i == ERROR_INTEGER then
                call DebugMsg("Invalid Item Protocol Requested ("+itemProtocol+") for Menu ("+I2S(whichMenu)+") in MenuSystem.")
            endif
            set Data[whichMenu*MENU_MAX+12+Data[(whichMenu+1)*MENU_MAX]+whichSlot]=i
        else
            set Data[whichMenu*MENU_MAX+12+Data[(whichMenu+1)*MENU_MAX]+whichSlot]=GetMenuItemProtocol(itemProtocol)
        endif
    endfunction
    private function GetMenu takes string label returns integer
        local integer i = 0
        local integer s = StringHash(label)
        static if DEBUG then
            call DebugMsg("(function GetMenu):  "+label+"__"+I2S(s)+"__")
        endif
        loop
            exitwhen i==Total
            if s == Data[i*MENU_MAX] then
                call DebugMsg("(function GetMenu):  menu found!__"+I2S(Data[i*MENU_MAX])+"=="+I2S(s)+"__")
                return i
            endif
            call DebugMsg("(function GetMenu):  menu not found!__"+I2S(Data[i*MENU_MAX])+"!="+I2S(s)+"__")
            set i = i + 1
        endloop
        static if DEBUG then
            call DebugMsg("Menu not found (function GetMenu @ MenuSystem):  "+label+".")
        endif
        return ERROR_INTEGER
    endfunction
    private function onInit takes nothing returns nothing
        call NewMenu("Main_Menu")
        call NewMenu("Config")
        call NewMenu("Item_Menu")
        call NewMenu("Stat_Menu")
        call NewMenu("Spell_Menu")
        call NewMenu("Status_Menu")
        call NewMenu("Equipment_Menu")
        //=========================================================================
        set tempi=GetMenu("Main_Menu")
        call MenuAddItem(tempi,'I001',1,GetMenu("Status_Menu"),"")
        call MenuAddItem(tempi,'I000',2,GetMenu("Item_Menu"),"")
        call MenuAddItem(tempi,'I003',3,GetMenu("Equipment_Menu"),"")
        call MenuAddItem(tempi,'I004',4,GetMenu("Stat_Menu"),"")
        call MenuAddItem(tempi,'I002',5,GetMenu("Spell_Menu"),"")
        call MenuAddItem(tempi,'I005',6,GetMenu("Config"),"")
        //=========================================================================
        set tempi=GetMenu("Item_Menu")
        call MenuAddItem(tempi,'I006',1,ERROR_INTEGER,"Protocol_ItemMenu_Items")
        call MenuAddItem(tempi,'I007',2,ERROR_INTEGER,"Protocol_ItemMenu_Equipment")
        call MenuAddItem(tempi,'I008',3,ERROR_INTEGER,"Protocol_ItemMenu_KeyItems")
        call MenuAddItem(tempi,'I009',4,ERROR_INTEGER,"Protocol_ItemMenu_Use")
        call MenuAddItem(tempi,'I00A',5,ERROR_INTEGER,"Protocol_ItemMenu_Swap")
        call MenuAddItem(tempi,ESC,6,ERROR_INTEGER,"")
    endfunction
endlibrary

Re: Help With StringHash

Posted: Sat Dec 29, 2012 2:55 pm
by 3ICE
I spent a good 10 minutes looking at your code and couldn't see anything wrong with it.
Though ERROR_INTEGER confuses me a bit.

I would like to see the map.

Re: Help With StringHash

Posted: Sat Dec 29, 2012 6:25 pm
by Ian
ERROR_INTEGER is a value that gets returned in functions that encounter an error (if the function returned this value, then obviously an error has occurred).
It also has multiple purposes right now so I don't have to make new variables.
In the function MenuAddItem, a child menu is asked for. Not all menu items will have a child menu, so instead of making a new variable ("integer NO_CHILD_MENU = StringHash("No_Child_Menu") I'm using ERROR_INTEGER.

Edit2: After a brief nap I came back to look at the system again. I don't know why I ever thought the code inside "function MenuAddItem" would function properly, but it's fixed now. Problem solved =).

Re: Help With StringHash

Posted: Sun Dec 30, 2012 12:20 am
by 3ICE
Solved, hooray!

I suggest you make new variables.

Readable code > a few bytes saved.