• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Lua] FourCCTable

A small Lua snippet. A Table Creator which autoconverts 4 digit RawCodes keys/values into numbers. Quite Handy in table driven data setup in which the keys are Object Editor Raw Codes.

Lua:
do
    --[[ FourCCTable by Tasyen
    
    Table Creator which autoconverts 4 digit RawCodes into numbers.

    function CreateFourCCTable(includeValue)
        Creates a table which will by itself convert 4 string keys into Object Editor Numbers.
        includeValue (true) -> also FourCC value
        returns a new Table
    ]]
    local targets = {}
    local metaTable = {__newindex = function(tab, key, value)
        if type(key) == "string" and string.len(key) == 4 then key = FourCC(key) end
        if targets[tab] and type(value) == "string" and string.len(value) == 4 then value = FourCC(value) end
        rawset(tab, key, value)
    end}
    function CreateFourCCTable(includeValue)
        local object = {}
        targets[object] = includeValue
        return setmetatable(object, metaTable)
    end
end

Example:
Lua:
-- Create a table which autoconverts
Data = CreateFourCCTable()
-- set Data for the Paladin Object Editor RawNumber to 2000
Data['Hpal'] = 2000

--for Paladin this returns the 2000
--Data[GetUnitTypeId(whichUnit)] -> 2000
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
I'll admit, when I saw the title of this resource, I had thought you had done something like caching the value of FourCC. Something like this:

Lua:
do
local ids = {}
function Rawcode(id)
    local i = ids[id]
    if not i then
        i = 0x1000000 * string.byte(id:sub(1,1)) +
              0x10000 * string.byte(id:sub(2,2)) +
                0x100 * string.byte(id:sub(3,3)) +
                        string.byte(id:sub(4,4))
        ids[id] = i
    end
    return i
end
end

I think it is more universal this way, yet still gives users access to the original FourCC in case they aren't sure whether the rawcode exists for the object they are searching. I am not sure what the direct benefit of having a table indexed by the FourCC value is otherwise, rather than just the table being indexed by the 4-character string.
 
Less converting during the execution, When you have the string you can't use GetUnitTypeId/GetSpellAbilityId/GetItemTypeId directly.

This does not take away FourCC it just makes it easier to create tables in which keys are object Editor numbers, because you don't need to write FourCC.
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
Maybe something to convert an existing table would also be useful. Table initialization is shorter and more readable than assigning all values individually.

I use something similar to give all my object data human readable names:
Lua:
Buildings = {
    Demon = {
        Tier1 = 'o002',
        Tier2 = 'o003',
        Tier3 = 'o004',
        Altar = 'o005',
        Ziggurat = 'o00B',
        Tower = 'u000',
        Shop = 'o00C',
        Gate = 'o009',
        Workshop = 'o00A',
        Barracks = 'o006',
        Roost = 'o008',
        Tech = 'o007',
    }
}
Buildings = ObjData(Buildings)

Lua:
local function ObjData(data)
        for key, value in pairs(data) do
            if type(value) == "table" then
                data[key] = ObjData(value)
            elseif type(value) == "string" and #value == 4 then
                data[key] = FourCC(value)
                if value:sub(1,1) ~= "B" then
                    assert(GetObjectName(data[key]) ~= "Default string", "ObjectId " .. value .. " is not valid." )
                end
            else
                assert(false, "Unexpected object data entry: " .. tostring(key) .. "->" .. tostring(value))
            end
        end
        return data
    end
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
I think this currently does not fulfill a very strong purpose in the grand scheme of things, as it isn't much effort to do something like this:

Lua:
local f = FourCC
local myTable = {}
myTable[f"hfoo"] = 2000 --works because Lua doesn't need the parenthesis when it is a function call that takes a delimited value (quotes or curly brackets)
 
Top