1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. The poll for Hive's 12th Concept Art Contest is up! Go cast your vote for your favourite genie!
    Dismiss Notice
  4. Travel to distant realms and encounter scenes unknown to the common folk. The Greatest of Adventures is upon us with the 8th Cinematic Contest. Join in on a fun ride.
    Dismiss Notice
  5. The 18th Icon Contest is ON! Choose any ingame unit and give him/her Hero abilities. Good luck to all.
    Dismiss Notice
  6. Contestants are to create a scene set in the Stone Age. Come and see what you can come up with. We wish you the best of luck!
    Dismiss Notice
  7. Colour outside the lines! Techtree Contest #13 is a go. The contest is optionally paired.
    Dismiss Notice
  8. Greetings cerebrates, our Swarm needs new spawners that will have numerous children. Join the HIVE's 31st Modeling Contest - Spawners and Spawned! The contest is optionally paired.
    Dismiss Notice
  9. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[Lua] Unit ID string to integer

Discussion in 'The Lab' started by strange_loop, Jul 19, 2019.

Tags:
  1. strange_loop

    strange_loop

    Joined:
    Jul 18, 2019
    Messages:
    2
    Resources:
    0
    Resources:
    0
    I'm new around here and I just recently started getting into W3 scripting now that Lua is a thing! I came up with a function that might be useful. If it's not, please just archive this thread and carry on :gg:

    Functions like
    Code (Text):

    native CreateUnit takes player id, integer unitid, real x, real y, real face returns unit
     
    expect an integer unit id. In JASS, you can pass a 4-character string (such as "hfoo" for a footman) as an integer and Jass converts the string into its corresponding bytes. Lua does not do this automatically and it's more tricky. Here's a short little utility function that does this conversion.

    Code (Text):

    function getUnitId (idString)
        local b1, b2, b3, b4 = string.byte(idString, 1, 4)
        return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4
    end
     
    Then you can use it like this

    Code (Text):

    local unit = CreateUnit(GetLocalPlayer(), getUnitId("hfoo"), 0, 0, 0)
     
    Is there an easier solution that I'm not aware of? If not, I hope this serves useful!
     
  2. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    2,788
    Resources:
    1
    Spells:
    1
    Resources:
    1
    There is a default Lua function that does this: FourCC("i000")
     
  3. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,015
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Came here to say this.
     
  4. strange_loop

    strange_loop

    Joined:
    Jul 18, 2019
    Messages:
    2
    Resources:
    0
    Resources:
    0
    Good to know. I'm looking at the Lua reference and don't see that function. Nor do I see it in common.j. Where is it from?
     
  5. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,462
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    There is also a way to do this by using string.unpack to unpack a 4 character type ID as an integer.
     
  6. yxq1122

    yxq1122

    Joined:
    Jun 5, 2018
    Messages:
    97
    Resources:
    0
    Resources:
    0
    This is an issue that also confuses me. If any one could present a tutorial that clarifies the differences between Jass/vJass and Lua, it would be great.
     
  7. Prometheus3375

    Prometheus3375

    Joined:
    Jul 20, 2018
    Messages:
    90
    Resources:
    0
    Resources:
    0
    Just read Lua manual on Lua site. 'word' and "word" are strings, quotes can be either single or double.
     
  8. mori

    mori

    Joined:
    Jun 13, 2016
    Messages:
    336
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    It doesn't really make sense to approach Lua in terms of its differences from Jass, because there's just so many. It's a different language with a different history and semantics. There's a lot of things that are done one way in Jass that are done differently in Lua. If you want to program in it, you should really just learn it like any other new language that isn't JASS, and not make any assumptions about its semantics. The PIL book is a good starting point.
     
  9. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,015
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Syntax-wise, conversion from JASS to Lua is mostly find and replace:

    Endfunction/loop/if become end
    Loop becomes while (true) do
    != becomes ~=
    Takes becomes (
    Returns becomes )
    Null becomes nil
    Delete all types (integer, boolean, agent)

    Exitwhen works differently (just uses 'break') and you may want to utilize some more simple iterations provided by Lua. For that you need to look over the Lua loop tutorials.

    Arrays are declared differently - instead of "array name" it is "name = {}".

    Arrays are not pre-initialized so sometimes you have to manually initialize indices.

    Arrays are virtually infinite and work similarly to Hashtables (so no need for the Table vJass library).

    Functions are just variables and can be assigned and passed dynamically. Calling code is very lightweight.

    Plenty of others!
     
  10. mori

    mori

    Joined:
    Jun 13, 2016
    Messages:
    336
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    There's also:

    - Arrays are 1-indexed, unlike most other languages
    - You don't need to null local variables
    - Equality comparisons between handle types are currently somewhat broken and don't work. If you have two "unit" variables that come from different "sources", they may not compare equal. This is a major difference to jass, where equality comparisons work correctly.
    - Strings are not limited to 2040-whatever character, and can be basically treated as binary buffers

    This is why I don't recommend blindly rewriting existing JASS code in Lua. It will probably work, but unless you pay attention to all the small details and differences, you're going to run into some trouble. If you don't already know Lua and just think its a different version of JASS, you're going to run into a lot of trouble.
     
  11. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,462
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    Only when operating in list mode. Lua itself will still accept index 0 as valid, although with a performance impact (hash table rather than array).
     
  12. mori

    mori

    Joined:
    Jun 13, 2016
    Messages:
    336
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Unfortunately, a lot of things assume 1-based indexing in lua. The length operator (#) only counts elements from 1. table.insert will insert into an empty table at position 1. Table literals enumerate elements starting from 1. ipairs will only iterate starting from 1 as well. And like you mentioned, there's a performance impact associated with using 0 as an index.
     
  13. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    2,788
    Resources:
    1
    Spells:
    1
    Resources:
    1
    So instead just compare handle ids?
     
  14. mori

    mori

    Joined:
    Jun 13, 2016
    Messages:
    336
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Yes, that's the solution for now. It's just important to note since this is a major difference to JASS. Blizzard is aware of this issue and they'll hopefully fix it in the future, however.
     
  15. Prometheus3375

    Prometheus3375

    Joined:
    Jul 20, 2018
    Messages:
    90
    Resources:
    0
    Resources:
    0
    Another difference between JASS and Lua - boolexp are cached in JASS, but not in Lua. I.e. every time you call Condition() or Filter() for the same callback, boolexpr will be created only once in JASS, in Lua a new boolexpr will be created every time.
     
  16. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,462
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    And is this a leak hazard?
     
  17. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,252
    Resources:
    16
    Tools:
    2
    Maps:
    2
    Spells:
    7
    Tutorials:
    4
    JASS:
    1
    Resources:
    16
    one does not write "call" as one does not write "set".
    Combines 2 strings with 2 "." example: "Hello" .. " World"
    comments are -- it also supports multiline comments --[[ to --]]
    one does not need a globals block (for variables) or Init_trig function, one can just write that lines defining variables, CreatingTriggers, starting timers... anywhere outside of functions.

    This code can be placed anywhere outside of functions in Lua mode and it will create an any unit attacked trigger. That trigger prints attack Units. Prints after game started "TestTimer" and sets Reds Gold to 5000 before map Init TriggersActions were executed.
    Code (Lua):

    MyTrigger = CreateTrigger()
    TriggerRegisterAnyUnitEventBJ(MyTrigger, EVENT_PLAYER_UNIT_ATTACKED)
    TriggerAddAction(MyTrigger, function() print(GetUnitName(GetAttacker()), "attacks", GetUnitName(GetTriggerUnit())) end)
    function Test()
        print("TestTimer")
    end
    TimerStart(CreateTimer(),0.0, false, Test)

    function TestGold()
        SetPlayerState(Player(0), PLAYER_STATE_RESOURCE_GOLD, 5000)
    end
    TestGold()
     
    Edit: MyTrigger is seen as garbage and is cleaned when the garbage collector runs.
     
    Last edited: Jul 23, 2019
  18. Prometheus3375

    Prometheus3375

    Joined:
    Jul 20, 2018
    Messages:
    90
    Resources:
    0
    Resources:
    0
    Yes.
    Here (JASS) filter will be created once.
    Code (vJASS):
    call GroupEnumUnitsInRange(g, x, y, r, Filter(function SomeFunc))

    Here (Lua) filter will be created every time you execute this string.
    Code (Text):
    GroupEnumUnitsInRange(g, x, y, r, Filter(SomeFunc))
    You can check this easily just comparing handle ids every time.
     
    Last edited: Jul 23, 2019
  19. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,252
    Resources:
    16
    Tools:
    2
    Maps:
    2
    Spells:
    7
    Tutorials:
    4
    JASS:
    1
    Resources:
    16
    Does running the garbage collector afterwards changes the result? I also thought that annonym functions in ForGroup/TimerStart would leak cause the handleIds were rising, but after forcing the garbage collector to run the ids were reused after 3 further executions of the same function. This function forced collectgarbage() as last action. collectgarbage was only added for the test.
     
  20. Prometheus3375

    Prometheus3375

    Joined:
    Jul 20, 2018
    Messages:
    90
    Resources:
    0
    Resources:
    0
    Perhaps, I did not make that test, it was made by one of XGM users.

    You are correct.
    Create test map where N times per second you create and instantly delete timer outputting its handle id. In JASS they will be close to each other, in Lua handle id will increase. But if you add collectgarbage() at the end in Lua code then it will behave as JASS code.

    Therefore, there is a big question when garbage collector runs automatically in WC3 Lua. Calling collectgarbage() manually in heavy maps can lead to freezes and may cause desyncs. Everything depends on how Blizzard have implemented Lua in WC3.
     
    Last edited: Jul 23, 2019