• 🏆 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!

Get bonus damage via trigger

Status
Not open for further replies.
In custom maps in which each player has only one hero/unit being almost non stop selected, one can read/parse the displayed text for attack 0 and sync that to all players. That synced value then could be used for that stuff.

BlzSendSyncData
totalAttack = BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0))
 
Level 7
Joined
Apr 18, 2010
Messages
102
In custom maps in which each player has only one hero/unit being almost non stop selected, one can read/parse the displayed text for attack 0 and sync that to all players. That synced value then could be used for that stuff.

BlzSendSyncData
totalAttack = BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0))

How would you use that?

//insert spellcode

local real damage = BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0))
>deal damage to target

//insert spell

is is as simple as that? (or do I need to specify which InfoPanelIconValue? belongs to which player)
 
It is not that simple, totalAttack = BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0)) is a text shown in the UI for Attack 0 (1 from Object Editor). It is only known to the local player, hence it probably differs between players. if you use that directly the game will desync with other players.
One would constantly check the displayed value of ("InfoPanelIconValue", 0) if it differs to an value in a array holding the last synced value tell the other players about that new value. For Gameplay one would only use the value from the synced array. This text also needs be parsed and converted into numbers.
There is also BlzGetFrameByName("InfoPanelIconValue", 1) for the secondary attack.

That is what I wrote for the mentioned technique it frequently reads the Frame's text, parses the bonusdamage and syncs that bonusdamage into SyncDamage[player]. Now one could use baseDamage(unit) + SyncDamage[player] to deal damage to an unit based on attack damage. Although that code does not check for the selected Unit at all but it shows the concept. As said that only works for 1 hero a player RPGs or maybe Moba, Arena or such gameTypes... It also can be exploited.
Edit: simpliefied the code
Lua:
SyncDamage = {}
TimerStart(CreateTimer(), 0.0 ,false, function()
    print("Start")
  
    SyncDamage.Trigger = CreateTrigger()
    for playerIndex = 0, bj_MAX_PLAYERS - 1 do
        BlzTriggerRegisterPlayerSyncEvent(SyncDamage.Trigger, Player(playerIndex) , "BonusDamage", false)
    end

    TriggerAddAction(SyncDamage.Trigger, function()
        SyncDamage[GetTriggerPlayer()] = tonumber(BlzGetTriggerSyncData())
        print(GetPlayerName(GetTriggerPlayer()), SyncDamage[GetTriggerPlayer()])
    end)

    SyncDamage.Timer = CreateTimer()
    TimerStart(SyncDamage.Timer, 0.2, true, function()
        local totalAttack = BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0))
        local colorStartIndex = string.find(totalAttack, "|", 1, true)
        if colorStartIndex then
            local bonusDamage = string.sub(totalAttack, colorStartIndex + 10, -3)

            if not SyncDamage[GetLocalPlayer()] or SyncDamage[GetLocalPlayer()] ~= tonumber(bonusDamage) then
                --print(bonusDamage)
                BlzSendSyncData("BonusDamage", bonusDamage)
            end
        else
            --print("no bonus")
            if SyncDamage[GetLocalPlayer()] ~= 0 then
                BlzSendSyncData("BonusDamage", "0")
            end
        end
    end)
    print("Done")
end)
 
Last edited:
Level 7
Joined
Apr 18, 2010
Messages
102
It is not that simple, totalAttack = BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0)) is a text shown in the UI for Attack 0 (1 from Object Editor). It is only known to the local player, hence it probably differs between players. if you use that directly the game will desync with other players.
One would constantly check the displayed value of ("InfoPanelIconValue", 0) if it differs to an value in a array holding the last synced value tell the other players about that new value. For Gameplay one would only use the value from the synced array. This text also needs be parsed and converted into numbers.
There is also BlzGetFrameByName("InfoPanelIconValue", 1) for the secondary attack.

That is what I wrote for the mentioned technique it frequently reads the Frame's text, parses the bonusdamage and syncs that bonusdamage into SyncDamage[player]. Now one could use baseDamage(unit) + SyncDamage[player] to deal damage to an unit based on attack damage. Although that code does not check for the selected Unit at all but it shows the concept. As said that only works for 1 hero a player RPGs or maybe Moba, Arena or such gameTypes... It also can be exploited.
Lua:
SyncDamage = {}
TimerStart(CreateTimer(), 0.0 ,false, function()
    print("Start")
 
    SyncDamage.Trigger = CreateTrigger()
    for playerIndex = 0, bj_MAX_PLAYERS - 1 do
        BlzTriggerRegisterPlayerSyncEvent(SyncDamage.Trigger, Player(playerIndex) , "BonusDamage", false)
    end

    TriggerAddAction(SyncDamage.Trigger, function()
        SyncDamage[GetTriggerPlayer()] = tonumber(BlzGetTriggerSyncData())
        print(GetPlayerName(GetTriggerPlayer()), SyncDamage[GetTriggerPlayer()])
    end)

    SyncDamage.Timer = CreateTimer()
    TimerStart(SyncDamage.Timer, 0.2, true, function()
        local totalAttack = BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0))
     
        if string.find(totalAttack, "|", 1, true) then
            local totalAttackReverse = string.reverse(totalAttack)
            local index = string.find(totalAttackReverse, "+", 1, true)
            if not index then
                index = string.find(totalAttackReverse, "-", 1, true)
            else
                index = index - 1
            end

            local bonusDamage
            if not index then
                bonusDamage  = "0"
            else
                bonusDamage = string.sub(totalAttack, -index, -3)
            end

            --print(not SyncDamage[GetLocalPlayer()] or SyncDamage[GetLocalPlayer()] ~= tonumber(bonusDamage))
            if not SyncDamage[GetLocalPlayer()] or SyncDamage[GetLocalPlayer()] ~= tonumber(bonusDamage) then
                --print(bonusDamage)
                BlzSendSyncData("BonusDamage", bonusDamage)
            end
        else
            --print("no bonus")
            if SyncDamage[GetLocalPlayer()] ~= 0 then
                BlzSendSyncData("BonusDamage", "0")
            end
        end
    end)
    print("Done")
end)

Wow. it is not that simple... I'll try to study this and recreate it in Vjass. thank you sir!!!
 
Status
Not open for further replies.
Top