1. The Melee Mapping Contest #4: 2v2 - Results are out! Step by to congratulate the winners!
    Dismiss Notice
  2. We're hosting the 15th Mini-Mapping Contest with YouTuber Abelhawk! The contestants are to create a custom map that uses the hidden content within Warcraft 3 or is inspired by any of the many secrets within the game.
    Dismiss Notice
  3. The 20th iteration of the Terraining Contest is upon us! Join and create exquisite Water Structures for it.
    Dismiss Notice
  4. Check out the Staff job openings thread.
    Dismiss Notice

Warcraft III - Patch 1.31 PTR

Discussion in 'Latest Updates and News' started by TriggerHappy, Apr 24, 2019.

  1. Ardenaso

    Ardenaso

    Joined:
    Jun 22, 2013
    Messages:
    291
    Resources:
    0
    Resources:
    0
    Kinda going off-topic here, but would you rather recommend saving for a new laptop instead of buying a new memory card then?
     
  2. Sir Moriarty

    Sir Moriarty

    Joined:
    Jun 13, 2016
    Messages:
    315
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    1. It doesn't work in JASS either. JASS simply treats any single-quote enclosed "string" as an integer, and does the conversion for you. 'xxxx' in JASS is not a string, it's an integer.
    2. This might be related to the fact that the standalone Lua runner is compiled in x64 mode, while WC3's Lua may be x86, which would limit numbers (integers and floats) to 32 bits.
    3. This isn't entirely true. Lua has a single "number" type which can be both integer and float, but it switches internal representations depending on what you do with the number. For example, bitshift operators always convert the arguments to integers, and produce integers.

    You're encouraged to take use of Lua's inbuilt bitwise operators. With those, the String2Id function becomes trivial:

    Code (Lua):

    function String2Int(input)
        local bytes = {string.byte(input, 1, 4)}

        return (bytes[1] << 24) | (bytes[2] << 16) | (bytes[3] << 8) | bytes[4]
    end
     
     
  3. Neveralice

    Neveralice

    Joined:
    Feb 27, 2015
    Messages:
    8
    Resources:
    0
    Resources:
    0
    1. I know nothing about JASS, so thanks for explaining this.
    2. I'm using the x64 version World Editor and Warcraft III. I also tried this trick from StackOverflow, and #string.pack("T",0)*8 gives 64, so Warcraft's Lua should also be x64. That said, only the devs can be certain about this. Still, I think this issue is worth investigating.
    3. I understand how Lua 5.3 handles the new integer representation. I'm trying to say that when using Jass native function, this difference matters. For example, BlzGetAbilityTooltip(1095263859, 1) works but BlzGetAbilityTooltip(1095263859.0, 1) crashed. There seems to be no automatic conversion here.
    4. Thanks for giving an alternative version. I'm a Python programmer who rarely uses bitwise operators, and I just start to learn Lua specifically for Warcraft III. Your help is much appreciated.
    EDIT: Now I'm certain this problem is very likely caused by a 32-bit float.
    This gives 1095263744.000000 1095263872 (WRONG)
    Code (C):
    float t = pow(256, 3) * 65 + pow(256, 2) * 72 + 256 * 102;
    printf("%f %d", t, (int)(t+115));
    And this gives 1095263744.000000 1095263859 (CORRECT)
    Code (C):
    double t = pow(256, 3) * 65 + pow(256, 2) * 72 + 256 * 102;
    printf("%f %d", t, (int)(t+115));
     
    Last edited: Apr 28, 2019
  4. WeirdEditor

    WeirdEditor

    Joined:
    May 10, 2018
    Messages:
    108
    Resources:
    0
    Resources:
    0
    Yes. Without it, I can't even get the name/tip of an ability.
     
  5. Sir Moriarty

    Sir Moriarty

    Joined:
    Jun 13, 2016
    Messages:
    315
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    That's likely to be expected for a while, now. Blizzard announced Lua support as beta, and it's quite obvious they haven't really adapted anything beyond the bare minimum for Lua.
    Being able to accept both integers and reals (or strings, even) in some of the natives would require special code in the C++ side to handle the different types. Right now, it seems, they just assert that the received argument is of the right type (as declared in common.j) and that's about it.

    I think in the future we might expect more Lua-specific QOL improvements, but for now, there's a lot of rough edges.

    Personally, I think that's fine. For the most part, these things we can deal with.
     
  6. LiSen冯

    LiSen冯

    Joined:
    Feb 24, 2018
    Messages:
    28
    Resources:
    0
    Resources:
    0
    ('>I4'):unpack 'AHfs'
     
  7. 4eb0da

    4eb0da

    Joined:
    May 2, 2017
    Messages:
    5
    Resources:
    0
    Resources:
    0
    I've tested new ui functions and this is what i've got so far
    I'm definitely doing something wrong, but maybe this map would help someone
    Does someone also test it?
     

    Attached Files:

  8. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,257
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    Memory card? Are you referring to a DIMM?

    I would need to know the full specs of your current system to give any sort of recommendation.
    Warcraft III does not use hardware floats. All floats are software emulated. This is required to keep in sync between computers.
    Um what? You might want to add some context to why you posted that.
     
  9. TriggerHappy

    TriggerHappy

    Code Moderator

    Joined:
    Jun 23, 2007
    Messages:
    3,607
    Resources:
    22
    Spells:
    11
    Tutorials:
    2
    JASS:
    9
    Resources:
    22
    He posted a simple way to convert a raw code string to an integer.
     
  10. LiSen冯

    LiSen冯

    Joined:
    Feb 24, 2018
    Messages:
    28
    Resources:
    0
    Resources:
    0
    print ( BlzGetAbilityTooltip (('>I4'):unpack 'AHfs') , 1 ))
    Don't thank me. lol
     
    Last edited: Apr 28, 2019
  11. LiSen冯

    LiSen冯

    Joined:
    Feb 24, 2018
    Messages:
    28
    Resources:
    0
    Resources:
    0
    what about the 1.31ptr worse performance than older versions in the game
     
  12. WeirdEditor

    WeirdEditor

    Joined:
    May 10, 2018
    Messages:
    108
    Resources:
    0
    Resources:
    0
    A Bug found in Campaign!

    In 1.31 ROC Nightelf Campaign Chapter2, Tyrand has no inventory. This doesn't appear in 1.30.4.
     
  13. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,257
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    Well unless you explain what you are posting it is not very helpful.

    To be honest I am still unsure what that statement is doing. I have not seen anything like that in Java, C/C++ or even Python 2.

    And ultimately the use of any function that is not map or load time inlined away will be slower than what JASS allowed.

    Anyway since they clearly cannot be bothered to here is a brief explanation for anyone interested.

    Firstly in Lua they accept single quotes for strings as well as double quotes. This is important to note because in JASS there were clear functional differences between the two. In most languages only double quotes represent strings with single quotes not being a reserved character.

    Secondly unlike most languages Lua allows one to omit the parenthesis when calling a function that takes a single argument and that single argument is "either a literal string or a table constructor". This is a string literal and hence can have the function call parenthesis omitted from the statement.

    Then it is using a strange language feature of Lua which is intended to help with implementing Object Orientated Programming. The string native type has a method table declared for it allowing the use of ":" syntax to make some calls to functions which take string as their first parameter. Specifically in this case it is calling the "string.unpack" function which takes a format string as its first parameter. Note this automatic shortening is only available if the function has been mapped to allow it to be used like such, one cannot just declare a function and try to run it off a variable of the first parameter type using ":" as much Lua documentation might trick us into thinking.

    Finally it is using a pretty much language specific feature to do the expansion. The > means it will use big endian during the expansion while I4 means an unsigned integer of 4 bytes. The unpack function assumes the passed string is a buffer of bytes, and not a sequence of any kind of human readable characters like most languages define string as.

    If people want a more normalized (not Lua specific) form...
    Code (Text):
    string.unpack(">I4", "AHfs")
     
    Last edited: Apr 28, 2019
  14. Quantum_Menace

    Quantum_Menace

    Joined:
    May 17, 2008
    Messages:
    69
    Resources:
    0
    Resources:
    0
    I was afraid of that. Hopefully that capability will be added, I critically need it.

    Something else that came up: Spells and attacks don't ever appear to do less than 1.0 damage, even if you set them to 0.

    In addition, some spells cause 1.0 DAMAGE_TYPE_UNKNOWN in the "damaging" event when applying a buff, for instance, but that is zeroed out in the "damaged" event. An example of this is Storm Bolt, which registers as 1.0 DAMAGE_TYPE_UNKNOWN when the stun is applied and again when it wears off, neither of which really cause damage. It may have been this way before, I seem to remember seeing extra 0.0 damage events being registered in previous versions.

    The minimum damage even applies to some spells that aren't supposed to do any damage to begin with like Drunken Haze. Drunken Haze actually does cause 1.0 DAMAGE_TYPE_NORMAL, which really is applied to the unit.

    The refusal to do less than 1.0 damage breaks one of the systems I worked on that uses 0.01 damage abilities to trigger effects, but it worked in the version before this one.
     
    Last edited: Apr 29, 2019
  15. Razorclaw_X

    Razorclaw_X

    Joined:
    Apr 12, 2018
    Messages:
    87
    Resources:
    0
    Resources:
    0
    I don't think they've given us an AoE Heal like that before. Almost every instant AoE heal is centered on the caster.

    Yes, Stun is treated as a 0 damage attack in the live game.

    There's no such distinguishment as 'melee' and 'ranged' type attacks in Warcraft 3; every attack is a 'ranged' attack in some manner. The form of which the attack takes (Normal/Instant vs Missile) is immaterial to DDS since DDS works on when the damage is done.
     
    Last edited: Apr 29, 2019
  16. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,257
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    Although apparently Blizzard will add garbage collection to locations, groups and the like eventually. This is not the case currently with the 1.31 PTR.

    However that does not mean one cannot manually implement such a system with the awesome power of Lua. Behold...
    Code (Text):

    GCTable = {}
    GCTableMetatable = {__mode = "k"}
    setmetatable(GCTable, GCTableMetatable)

    Location_Metatable = {
    __gc = function(loc)
        RemoveLocation(loc[1])
    end
    }

    function WrapLocation(loc)
        local locman = {loc}
        setmetatable(locman, Location_Metatable)
        GCTable[loc] = locman
        return loc
    end

    LocationImpl = Location
    function Location(x, y)
        return WrapLocation(LocationImpl(x, y))
    end
     
    Thanks to this code the following GUI will no longer leak!
    • Leak Test
      • Events
        • Player - Player 1 (Red) skips a cinematic sequence
      • Conditions
      • Actions
        • Unit - Create 1 Footman for Player 1 (Red) at (Center of (Playable map area)) facing Default building facing degrees


    Note this is the implementation of "Center of region" which is why the above works for it.
    Code (vJASS):

    function GetRectCenter takes rect whichRect returns location
        return Location(GetRectCenterX(whichRect), GetRectCenterY(whichRect))
    endfunction
     

    Now technically one could implement this for all location producing natives. This would result in a script which could be imported into any GUI orientated map to immediately fix all location leaks. It does not even need to stop with locations, and could be expanded to group and force as well!

    For anyone wondering how the madness works... It abuses the mechanics of weak keys in a table. Weak keys do not stop the key object from being garbage collected. However to prevent cyclic object dependencies a table with weak keys will treat all references to a key from its value as weak. All one then needs is a table which tracks the key object with a metatable gc method and the Lua garbage collector does the rest. Once all references to a location are lost, it tries to remove the location key from the weak keyed table but to do so it has to first remove the wrapper table which results in a call to the wrapper table gc metatable method which cleans up the location. After the whole process is complete the location key is removed from the weak keyed table completely freeing all the resources used.

    EDIT:
    Someone raised concerns of possible multiplayer sync issues with this depending on how the Lua garbage collector operates. I have not tested this approach for multiplayer sync stability and if anyone intends to use it outside a single player map I suggest testing it before depending on it too much.
     
    Last edited: Apr 29, 2019
  17. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,243
    Resources:
    5
    Models:
    1
    Icons:
    1
    Spells:
    2
    JASS:
    1
    Resources:
    5
    In GUI, the Unit Weapon Real field that would normally be supplied for the getter function is unitrealfield by mistake. This is also present with other GUI equivalent UnitWeapon<Type>Field getters expecting unitweapon<type>field and getting unit<type>field

    UnitWeaponBooleanField -> UnitBooleanField?
    upload_2019-4-29_15-28-39.png

    UnitWeaponIntegerField -> UnitIntegerField?
    upload_2019-4-29_15-29-41.png

    UnitWeaponStringField -> UnitStringField?
    upload_2019-4-29_15-30-48.png

    In addition, it appears that among the unit weapon type fields' equivalent getters and setters, only the type unitweaponstringfield is functional. (Weapon indices from 1-2)

    upload_2019-4-29_15-23-55.png

    In the tested map, the fields in question were the following:
    • UnitRealField: Sight radius
      Acquisition Range

    • UnitWeaponRealField: Attack Backswing

    • UnitWeaponStringField: Projectile Art

    • UnitWeaponIntegerField: Base Damage

    • UnitWeaponBooleanField: Projectile Homing Flag
    Attack Backswing, Base Damage do not appear at all in the message log. This may indicate that the respective setters and getters do not yet work for UnitWeaponRealField, and UnitWeaponIntegerField.

    EDIT:

    BlzPauseUnitEx does not update IsUnitPaused, whereas PauseUnit does. Moreover, BlzPauseUnitEx keeps the command card, while PauseUnit hides it.

    The Critical Strike multiplier bonus applies even before EVENT_UNIT_DAMAGING and is indistinguishable from an attack.
     
    Last edited: Apr 29, 2019
  18. Death Adder

    Death Adder

    Joined:
    Nov 3, 2013
    Messages:
    879
    Resources:
    0
    Resources:
    0
    You seem to be completely missing the point... If one wants to know when a projectile is fired, not when it deals damage, then it's currently impossible with a DDS...

    For instance, just to give an example, if one were to make a custom searing/cold/dark/etc. arrow-esque ability that costs mana on each attack, you would be able to attack again before the projectile hits and deals damage (if it even hits at all). Now this example in particular can probably be worked around, but that's besides the point.


    I really don't get what's so hard to understand about something so obvious... Yes a DDS can do what a DDS does, I'm not that stupid. But unlike with melee attacks most ranged attacks have projectiles and thus don't deal damage at the same time that the attacks are fired which means that a DDS isn't always sufficient...

    Just imagine if every ability trigger would have to use begins casting event and DDS instead of effect start event...
     
  19. deepstrasz

    deepstrasz

    Map Reviewer

    Joined:
    Jun 4, 2009
    Messages:
    9,223
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Even A Unit Starts the Effect of an Ability isn't too accurate. On Frost Bolt, the effect is considered to start sometime before the projectile hits.
     
  20. Prometheus3375

    Prometheus3375

    Joined:
    Jul 20, 2018
    Messages:
    55
    Resources:
    0
    Resources:
    0
    Because this event triggers at Cast Point of a caster, not at the moment when projectile hits.