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

Converting mpi aoe hp buff to mui

Status
Not open for further replies.
Level 17
Joined
Nov 13, 2006
Messages
1,814
The mpi aoe buff

basically:
-each player have 1 Hero (Hero unit array [player number])
-each hero can do aoe hp buff the other heroes
-if picked Hero was buffed/enemy then he dont get another buff)
(only applied to self and other Hero[picked player number])
-every Hero who reicived buff get X second time (buff_timer[player number]-integer variable) and this integer decreased each second, buff_value[picked player number]=increased hp amount
-if buff timer is 10 then havea msg buff disapear soon (could be skipped if have a solution where this is hard)
-if buff timer is 1 then decrease the hp with buff value[player number]
-if Hero[] dieing then buff timer paused until he revived (since i dont think i can decrease the max hp to a unit what already death).

problems:
i dont know how to make mui
-i thought about indexer and timer based on hero custom value, add event the timer expired Timer[custom value of unit]&buff_value[custom value of unit]=x but problem when hero[x] revive then he get different custom value or just another another unit get same custom value, or another hero when timer is expired is dead

Update
pls check the jass, somebody see something problem with it?

  • HP Buff
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Battle Roar
    • Actions
      • Set TempPoint = (Position of (Triggering unit))
      • Set TempUnitGroup = (Units within 600.00 of TempPoint matching (Hero[(Player number of (Owner of (Matching unit)))] Equal to (Matching unit)))
      • Custom script: call RemoveLocation(udg_TempPoint)
      • Unit Group - Pick every unit in TempUnitGroup and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Buff_Value[(((Player number of (Owner of (Picked unit))) x 30) + 8)] Equal to 0
            • Then - Actions
              • Set PlayerGroup = (Player group((Picked player)))
              • Game - Display to PlayerGroup the text: Your HP increased w...
              • Custom script: call DestroyForce(udg_PlayerGroup)
              • Set Buff_Value[(((Player number of (Owner of (Picked unit))) x 30) + 8)] = (Integer(((Life of (Picked unit)) x 0.30)))
              • Set Buff_Timer[(((Player number of (Picked player)) x 30) + 8)] = 5
              • Custom script: set udg_Max_HP = udg_Buff_Value[( ( GetConvertedPlayerId(GetOwningPlayer(GetEnumUnit())) * 30 ) + 8 )]
              • Set unit = (Picked unit)
              • Custom script: call AddHPMP(true, udg_Max_HP, udg_unit)
            • Else - Actions
      • Custom script: call DestroyForce(udg_PlayerGroup)
  • Buff timer
  • Buff timer Copy
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 10, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Player((Integer A))) slot status) Equal to Is playing
              • ((Player((Integer A))) controller) Equal to User
            • Then - Actions
              • Set TempUnit = Hero[(Integer A)]
              • For each (Integer B) from 1 to 12, do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • Buff_Timer[(((Integer A) x 30) + (Integer B))] Greater than 0
                      • Buff_Pause[(((Integer A) x 30) + (Integer B))] Equal to False
                    • Then - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • Buff_Timer[(((Integer A) x 30) + (Integer B))] Equal to 10
                        • Then - Actions
                          • Set PlayerGroup = (Player group((Player((Integer A)))))
                          • Game - Display to PlayerGroup the text: (|cffffcc00 + (Buff_Name[(30 + (Integer B))] + buff|r disapear soon!))
                          • Custom script: call DestroyForce(udg_PlayerGroup)
                        • Else - Actions
                      • Set Buff_Timer[(((Integer A) x 30) + (Integer B))] = (Buff_Timer[(((Integer A) x 30) + (Integer B))] - 1)
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Integer B) Not equal to 8
                          • Buff_Value[(((Integer A) x 30) + (Integer B))] Not equal to 0
                        • Then - Actions
                          • Set Buff_Value[(((Integer A) x 30) + (Integer B))] = 0
                          • Set PlayerGroup = (Player group((Player((Integer A)))))
                          • Game - Display to PlayerGroup the text: (|cffffcc00 + (Buff_Name[(30 + (Integer B))] + buff|r gone!))
                          • Custom script: call DestroyForce(udg_PlayerGroup)
                        • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Buff_Timer[(((Integer A) x 30) + 8)] Equal to 0
                  • Buff_Value[(((Integer A) x 30) + 8)] Not equal to 0
                • Then - Actions
                  • Set Max_HP = Buff_Value[(((Integer A) x 30) + 8)]
                  • Custom script: call AddHPMP(true, udg_Max_HP, udg_TempUnit)
                  • Set Buff_Value[(((Integer A) x 30) + 8)] = 0
                • Else - Actions
            • Else - Actions
  • Hero Death Copy
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Dying unit) Equal to Hero[(Player number of (Triggering player))]
    • Actions
      • For each (Integer A) from 1 to 30, do (Actions)
        • Loop - Actions
          • Set Buff_Pause[((plNR x 30) + (Integer A))] = True
      • Wait 5.00 seconds
      • Set Attachment_Unit = (Triggering unit)
      • Set plNR = (Player number of (Triggering player))
      • Set TempPoint = (Random point in Starter <gen>)
      • Camera - Pan camera for (Owner of (Triggering unit)) to TempPoint over 0.00 seconds
      • Hero - Instantly revive (Triggering unit) at TempPoint, Show revival graphics
      • Custom script: call RemoveLocation(udg_TempPoint)
      • Selection - Select (Triggering unit) for (Owner of (Triggering unit))
      • For each (Integer A) from 1 to 30, do (Actions)
        • Loop - Actions
          • Set Buff_Pause[((plNR x 30) + (Integer A))] = False


Please check this if its ok \|/


JASS:
function Trig_HP_Buff_Copy_Conditions takes nothing returns boolean
    local boolean b = false
    if (GetSpellAbilityId() == 'A00L') and (LoadInteger(udg_Buff_Table, GetUnitUserData(GetSpellAbilityUnit()), 8) == 0) then
        set b = true
    endif
    return b
endfunction
function Trig_HP_Buff_Copy_Actions takes nothing returns nothing
    local boolean exit = false
    local unit u = GetTriggerUnit()
    local unit up
    local real hprate = (GetUnitAbilityLevel( u, 'A00L') * 5.00 + 5.00) / 100
    local integer b
    local integer hp
    local integer hpdur = 10
    local integer i = 0
    local integer pnr
    local player p
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local group gr1 = CreateGroup()
    local group gr2 = CreateGroup()

    call GroupEnumUnitsInRange(gr1, x, y, 600.00, null)
    loop
        set up = FirstOfGroup(gr1)
        exitwhen up==null
        call GroupRemoveUnit(gr1, up)
        set b = LoadInteger(udg_Buff_Table, GetUnitUserData(up), 8)
        if (IsUnitEnemy(up, p)==false) and (b==0) and (GetUnitState(up, ConvertUnitState(0)) > 0) then
            set p = GetOwningPlayer(up)
            call GroupAddUnit(gr2, up)
            set hp = R2I ( GetUnitState(up, ConvertUnitState(1)) * hprate )
            call SaveInteger(udg_Buff_Table, GetUnitUserData(up), 8, hp)
            call AddHPMP(true, hp, up)
            call DisplayTextToPlayer( p, 0, 0, "|cffffff77" + GetUnitName(up) + "|r reicived hp buff (+" + R2S (hprate * 100) + "%, +" + I2S(hp) + " )" )
        endif
    endloop
    call TriggerSleepAction(hpdur)
    loop
        set up = FirstOfGroup(gr2)
        exitwhen up==null
        set p = GetOwningPlayer(up)
        call GroupRemoveUnit(gr2, up)
        set b = LoadInteger(udg_Buff_Table, GetUnitUserData(up), 8)
        if (b > 0) then
            if (GetUnitState(up, ConvertUnitState(0)) > 0) then
                call SaveInteger(udg_Buff_Table, GetUnitUserData(up), 8, 0)
                call AddHPMP(true, b * - 1, up)
                call DisplayTextToPlayer( p, 0, 0, "|cffffff77" + GetUnitName(up) + "|r lost the hp buff (-" + R2S (hprate * 100) + "%, -" + I2S(b) + " )" )
            else
                set pnr = GetPlayerId(GetOwningPlayer(up)) + 1
                if (udg_Hero[pnr] == up ) then
                    loop
                        exitwhen ( exit == true )
                        if (GetUnitState(up, ConvertUnitState(0)) > 0) then
                            call SaveInteger(udg_Buff_Table, GetUnitUserData(up), 8, 0)
                            call AddHPMP(true, b * - 1, up)
                            call DisplayTextToPlayer( p, 0, 0, "|cffffff77" + GetUnitName(up) + "|r lost the hp buff (-" + R2S (hprate * 100) + "%, -" + I2S(b) + " )" )
                            set exit = true
                        endif
                        call TriggerSleepAction(1)
                    endloop
                endif
            endif
        endif
    endloop
//set pnr = GetPlayerId(GetOwningPlayer(up))+1
    call DestroyGroup(gr1)
    call DestroyGroup(gr2)
    set gr1 = null
    set gr2 = null
    set u = null
    set p = null
endfunction

//===========================================================================
function InitTrig_HP_Buff takes nothing returns nothing
    set gg_trg_HP_Buff = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_HP_Buff, EVENT_PLAYER_UNIT_SPELL_ENDCAST )
    call TriggerAddCondition( gg_trg_HP_Buff, Condition( function Trig_HP_Buff_Copy_Conditions ) )
    call TriggerAddAction( gg_trg_HP_Buff, function Trig_HP_Buff_Copy_Actions )
endfunction
 
Last edited:
Unit indexer doesn't allow two units to have the same custom value. Each value is unique. And it doesn't change at any point in the game, unless the unit doesn't exist any more. Which doesn't happen with heroes unless you use removeunit on it.

If you want to store data by player id and unit values as well, then use different arrays for each.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Please somebody can see this?
a try for aoe mui hp buff

(if hp dur expired then remove the buff but if picked unit is dead & is rpg Hero then wait till he is alive)


JASS:
function Trig_HP_Buff_Copy_Conditions takes nothing returns boolean
local boolean b = false
    if (GetSpellAbilityId() == 'A00L') and (LoadInteger(udg_Buff_Table, GetUnitUserData(GetSpellAbilityUnit()), 8) == 0) then
        set b = true
    endif
    return b
endfunction
function Trig_HP_Buff_Copy_Actions takes nothing returns nothing
local boolean exit = false
local unit u = GetTriggerUnit()
local unit up
local real hprate = (GetUnitAbilityLevel( u, 'A00L') * 5.00  + 5.00) / 100
local integer b
local integer hp 
local integer hpdur = 10
local integer i = 0
local integer pnr 
local player p 
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local group gr1 = CreateGroup()
local group gr2 = CreateGroup()

call GroupEnumUnitsInRange(gr1,x,y,600.00,null)
loop
   set up = FirstOfGroup(gr1)
   exitwhen up==null
   call GroupRemoveUnit(gr1, up) 
   set b = LoadInteger(udg_Buff_Table, GetUnitUserData(up), 8)
   if (IsUnitEnemy(up, p)==false) and (b==0) and (GetUnitState(up, ConvertUnitState(0)) > 0) then
       set p = GetOwningPlayer(up)
       call GroupAddUnit(gr2, up)
       set hp = R2I ( GetUnitState(up, ConvertUnitState(1)) * hprate )
       call SaveInteger(udg_Buff_Table, GetUnitUserData(up), 8, hp)
       call AddHPMP(true, hp, up)
       call DisplayTextToPlayer( p,0,0, "|cffffff77" + GetUnitName(up) + "|r reicived hp buff (+" + R2S (hprate*100) + "%, +" + I2S(hp)+" )" )
   endif  
endloop
call TriggerSleepAction(hpdur)
loop
   set up = FirstOfGroup(gr2)
   exitwhen up==null
    set p = GetOwningPlayer(up)
    call GroupRemoveUnit(gr2, up) 
    set b = LoadInteger(udg_Buff_Table, GetUnitUserData(up), 8)
    if (b>0) then
      if (GetUnitState(up, ConvertUnitState(0)) > 0) then
       call SaveInteger(udg_Buff_Table, GetUnitUserData(up), 8, 0)
       call AddHPMP(true, b*-1, up)
       call DisplayTextToPlayer( p,0,0, "|cffffff77" + GetUnitName(up) + "|r lost the hp buff (-" + R2S (hprate*100) + "%, -" + I2S(b)+" )" )
      else
          set pnr = GetPlayerId(GetOwningPlayer(up))+1
       if (udg_Hero[pnr] == up ) then
           loop
            exitwhen ( exit == true )
                if (GetUnitState(up, ConvertUnitState(0)) > 0) then
                call SaveInteger(udg_Buff_Table, GetUnitUserData(up), 8, 0)
                call AddHPMP(true, b*-1, up)
                call DisplayTextToPlayer( p,0,0, "|cffffff77" + GetUnitName(up) + "|r lost the hp buff (-" + R2S (hprate*100) + "%, -" + I2S(b)+" )" )
                set exit = true
                endif             
              call TriggerSleepAction(1)
            endloop
       endif
      endif
    endif  
endloop
//set pnr = GetPlayerId(GetOwningPlayer(up))+1
call DestroyGroup(gr1)
call DestroyGroup(gr2)
set gr1 = null
set gr2 = null
set u = null
set p = null
endfunction

//===========================================================================
function InitTrig_HP_Buff takes nothing returns nothing
    set gg_trg_HP_Buff = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_HP_Buff, EVENT_PLAYER_UNIT_SPELL_ENDCAST )
    call TriggerAddCondition( gg_trg_HP_Buff, Condition( function Trig_HP_Buff_Copy_Conditions ) )
    call TriggerAddAction( gg_trg_HP_Buff, function Trig_HP_Buff_Copy_Actions )
endfunction
 
Level 10
Joined
May 28, 2011
Messages
455
Use group and hashtable. Its easy. And mui.

Btw, i assume when a specific hero gets a buff, the hero wont get the same buff type again.

Requirement
Unit Indexer

Add unit (buffed hero) into a group

Save "time remain for buff to complete" in a hashtable by using the unit user data as the parent key

Timer check the conditions of every unit in the group for every interval (conditions such as is unit alive, is unit has buff?, time remain has completed?)

If unit alive, update the time remain in the hashtable (decrease time) Save n load.

Else, dont update

Unit in the group is a unit that has the specific buff, so check if the unit is in the group, then the unit cant be targeted again (or anything else you would like to do)

If the time remain completed, remove unit from the group. flush hashtable.

within the duration, you can manipulate anything you want. (your case is manipulating the units hp)
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Use group and hashtable. Its easy. And mui.

Btw, i assume when a specific hero gets a buff, the hero wont get the same buff type again.

Requirement
Unit Indexer

Add unit (buffed hero) into a group

Save "time remain for buff to complete" in a hashtable by using the unit user data as the parent key

Timer check the conditions of every unit in the group for every interval (conditions such as is unit alive, is unit has buff?, time remain has completed?)

If unit alive, update the time remain in the hashtable (decrease time) Save n load.

Else, dont update

Unit in the group is a unit that has the specific buff, so check if the unit is in the group, then the unit cant be targeted again (or anything else you would like to do)

If the time remain completed, remove unit from the group. flush hashtable.

within the duration, you can manipulate anything you want. (your case is manipulating the units hp)

its everything nice but the problem was the timer... how could make it without make alot timer and periodic triggers...
i posted a trigger above and i wait comment to that now
 
Level 10
Joined
May 28, 2011
Messages
455
make it vjass. more sophisticated...

one timer can check all buffs' remaining time for every interval. But i dont really advise that. one timer per buff is enough and just fine.

what i see from the trigger is a loop that will end until the buff finish. am i right? sory i just glance through.

my comment is...
You need a global group not local. so you can detect if the targeted unit is in unit group... which evidently enable you to know the unit has buff or not... the same thing goes to hashtable.

Instead of using loop, use timer or Time - Periodic Event... for every interval.. access every unit in the group (ForGroup or loop through copied).. and do anything you want...
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
make it vjass. more sophisticated...

one timer can check all buffs' remaining time for every interval. But i dont really advise that. one timer per buff is enough and just fine.

what i see from the trigger is a loop that will end until the buff finish. am i right? sory i just glance through.

my comment is...
You need a global group not local. so you can detect if the targeted unit is in unit group... which evidently enable you to know the unit has buff or not... the same thing goes to hashtable.

Instead of using loop, use timer or Time - Periodic Event... for every interval.. access every unit in the group (ForGroup or loop through copied).. and do anything you want...

the loop is only for Hero[player number] (each player got a hero who dont change the custom value coz get revive after x second) anybody else just got debuffed after trigger sleep but loop is for hero who died, so loop wait till hero respawn and remove the hp after he respawned

once i tryed with global group but annyoing coz each player can do buff, and tottally i want 20+ buff atleast on map what is over 20+ variable array or +1 harshtable and 20x X timer depend how many in group.

i can do a timer i think (Timer[unit custom value]=start timer) or something like this but idk how can i check wich timer is expired..... so i cant get the timer array index what is the unit custom value (if possible i want skip the periodic events)
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
You need to learn vjass... Take your time learning instead of solving the problems...
Tutorials is your best friend JASS tutorials

Since you are using custom value for spell purpose and i am sure that you organized heroes in an array based on their player's number... There will be less in option...

i dont see nothing in vjass what impossible in jass (just maybe with more work or different way). seems u also dont know how to detect the expired timer also u dont readed well the posted code :p
 
Level 10
Joined
May 28, 2011
Messages
455
vjass... uses struct.. well organized code.. so your trigger will be clear to read... and more efficient as well..

Btw, i dont directly help you to solve the code you had posted. I am advising you to redo them again in an effective way. Because, i did something like that before. believe me. its not dynamic and very hard to manipulate. for example, let say i want the target unit is not magic immune. i will have to go through the code again...

You use hashtable to detect if the targeted unit has buff.
Fixed number of time for buff to complete.
You sleep the trigger and without check them within the duration.
I stop there. i think there will be massive of errors. but still dedicated to continue :)

What i understand is..
a unit make area effect spell with 600 radius within its position. correct*
loop each unit selected. check if the unit match your conditions. correct*
add unit to another group. save hp in hashtable. wrong* -add to global group-
call a function that i dont know what it does. ???
wait 10 sec. wrong* -within this duration you are suppose to check dead alive condition not after the duration completed-
read units in the another group. no need this anymore*
load the saved hp. if more than 0. no need this anymore*
check unit is alive. if alive then remove buff. no need this anymore*
else (unit is dead). if read unit is same as hero[player number of owner of read unit]. then loop to check until if the unit alive. no need this anymore*

* indicate my comments

expired timer is easy in vjass though... -.-" up to you. its your decision. :)
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
vjass... uses struct.. well organized code.. so your trigger will be clear to read... and more efficient as well..

Btw, i dont directly help you to solve the code you had posted. I am advising you to redo them again in an effective way. Because, i did something like that before. believe me. its not dynamic and very hard to manipulate. for example, let say i want the target unit is not magic immune. i will have to go through the code again...

You use hashtable to detect if the targeted unit has buff.
Fixed number of time for buff to complete.
You sleep the trigger and without check them within the duration.
I stop there. i think there will be massive of errors. but still dedicated to continue :)

What i understand is..
a unit make area effect spell with 600 radius within its position. correct*
loop each unit selected. check if the unit match your conditions. correct*
add unit to another group. save hp in hashtable. wrong* -add to global group-
call a function that i dont know what it does. ???
wait 10 sec. wrong* -within this duration you are suppose to check dead alive condition not after the duration completed-
read units in the another group. no need this anymore*
load the saved hp. if more than 0. no need this anymore*
check unit is alive. if alive then remove buff. no need this anymore*
else (unit is dead). if read unit is same as hero[player number of owner of read unit]. then loop to check until if the unit alive. no need this anymore*

* indicate my comments

expired timer is easy in vjass though... -.-" up to you. its your decision. :)

i dont got nothing usefull in about ,,custom timer buff'' or ,,expiration timer detection'' in google ....

about unitgroup, last time i got a bit problem with unit groups also got sick when i already have damn much global variable, but i still thinking on makeing it with global variable since mp/hp buff not similiar with other buffs, coz example eva/def/critical chance i can handle easily with variable like total crit= base crit + buff and just modify the buff variable but in hp / mp case i must add/remove ability for change hp/mp (this is what that function do in example)

i dont care if buffed target die during duration simple reason after respawned a buffed mob he lost the +hp also he isnt same unit anymore than what i stored in local variable, still buff value is registered in harshtable but cant be applied coz buffed unit is not exist.

heroes dont lose the hp bonus coz they arent recreated, they are revived.

kinda weak point if hero die then he have still same hp but could be fixable with nulling in harshtable his hp buff in dying trigger and decrease hp after revive.

since i searched, belive me, but dont got better ideea or just idk how to find a solution (coz i am sure if possible in vjass then its could make in jass too but still i dont got the vjass solution too)

or u mean to local timers like this?
JASS:
// Example #3
 function Handlerfunc takes nothing returns nothing
     local timer t=GetExpiredTimer()
     call PauseTimer(t)
     call DestroyTimer(t)
     set t=null
 endfunction

 function foo_function takes nothing returns nothing
     local timer t=CreateTimer()
     call TimerStart(t, 5.00, false, function Handlerfunc)
     set t=null
 endfunction

this just replacement for triggersleep but i dont see nothing else in this
 
Status
Not open for further replies.
Top