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

[JASS] Hero Damage Bonus

Status
Not open for further replies.
Level 7
Joined
Feb 26, 2005
Messages
210
I want Heroes in my map to deal extra damage depending on how much hit points they have left. For every 10% of they deal 1 additional damage. How I got this to work is I gave every hero an ability based on the item damage bonus; made that ability have eleven levels which at level one adds 10 damage and at level eleven adds 0 damage; then I made the following trigger and it works. The code also moves the hero to the player's base for unrelated reasons.

JASS:
function Trig_Hero_Conditions takes nothing returns boolean
    if ( not ( IsUnitType(GetSoldUnit(), UNIT_TYPE_HERO) == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_Hero_Actions takes nothing returns nothing
    local unit u = GetSoldUnit()
    local integer i = 1
    local location l
    local location l2
    set l = GetUnitLoc(udg_PlayerBase[GetConvertedPlayerId(GetOwningPlayer(u))])
    set l2 = GetRectCenter(gg_rct_Battlefield)
    set l = PolarProjectionBJ(l, 275.00, AngleBetweenPoints(l, l2))
    call SetUnitPositionLoc( u, l )
    call SetUnitFacingToFaceLocTimed( u, l2, 0 )
    call RemoveLocation (l)
    call RemoveLocation (l2)
    loop
        call TriggerSleepAction( 0.05 )
        set i = 11 - (R2I(GetUnitLifePercent(u)) / 10)
        if GetUnitAbilityLevelSwapped('A001', u) != i then
            call SetUnitAbilityLevelSwapped( 'A001', u, i )
        endif
    endloop
    set u = null
endfunction

//===========================================================================
function InitTrig_Hero_Damage_Bonus takes nothing returns nothing
    set gg_trg_Hero_Damage_Bonus = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Hero_Damage_Bonus, EVENT_PLAYER_UNIT_SELL )
    call TriggerAddCondition( gg_trg_Hero_Damage_Bonus, Condition( function Trig_Hero_Conditions ) )
    call TriggerAddAction( gg_trg_Hero_Damage_Bonus, function Trig_Hero_Actions )
endfunction

However; I do not know if this trigger is going to cause problems in multiplayer due to leaks or bad coding on my part. What ways can I improve this code?
 
Level 12
Joined
Oct 16, 2010
Messages
680
a big improve would be to replace the bj functions with their natives and clear the leaks

GetConvertedPlayerdId ---> GetPlayerId("player")+1

GetRectCenter ----> Location(GetRectCenterX(whichRect), GetRectCenterY(whichRect))

SetUnitFacingToFaceLocTimed -----

-->local location unitLoc = GetUnitLoc(whichUnit)

call SetUnitFacingTimed(whichUnit, AngleBetweenPoints(unitLoc, target), duration)
call RemoveLocation(unitLoc)

GetUnitAbilityLevelSwapped ----> GetUnitAbilityLevel(whichUnit, abilcode)
SetUnitAbilityLevelSwapped-----> SetUnitAbilityLevel(whichUnit, abilcode)
 
Level 7
Joined
Feb 26, 2005
Messages
210
BonusMod requires a custom editor which does not gel well with Warcraft 3. Further, it is not going to help with keeping track of hp and applying the bonus accordingly. No thanks.

Since when does "call RemoveLocation" not kills leaks? Nulling the location seems redundant. Unless I am mistaken in which case someone explain to me how this is incorrect.

Replacing BJs with natives.

Anything else I can do?
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
Something like this. Might contain some errors, didin't try to compile it. I'm not sure what you want to do with the loop.

JASS:
function Trig_Hero_Conditions takes nothing returns boolean
    return IsUnitType(GetSoldUnit(), UNIT_TYPE_HERO)
endfunction

function Trig_Hero_Actions takes nothing returns nothing
    local unit u = GetSoldUnit()
    local integer pid = GetConvertedPlayerId(GetOwningPlayer(u))
    local integer i = 1
    local real x1 = GetUnitX(udg_PlayerBase[pid]
    local real y1 = GetUnitY(udg_PlayerBase[pid]
    local real x2 = GetRectCenterX(gg_rct_Battlefield)
    local real y2 = GetRectCenterY(gg_rct_Battlefield)
    local real a = Atan2(y2-y1, x2-x1)
    set x2 = x1 + 275 * Cos(a)
    set y2 = y1 + 275 * Sin(a)
    call SetUnitPosition(u, x2, y2)
    call SetUnitFacing( u, a*bj_RADTODEG)
    loop
        call TriggerSleepAction( 0.05 )
        set i = 11 - (R2I(GetUnitLifePercent(u)) / 10)
        if GetUnitAbilityLevel(u, 'A001') != i then
            call SetUnitAbilityLevel(u, 'A001', i )
        endif
    endloop
    set u = null
endfunction

//===========================================================================
function InitTrig_Hero_Damage_Bonus takes nothing returns nothing
    set gg_trg_Hero_Damage_Bonus = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Hero_Damage_Bonus, EVENT_PLAYER_UNIT_SELL )
    call TriggerAddCondition( gg_trg_Hero_Damage_Bonus, Condition( function Trig_Hero_Conditions ) )
    call TriggerAddAction( gg_trg_Hero_Damage_Bonus, function Trig_Hero_Actions )
endfunction
 
Level 7
Joined
Feb 26, 2005
Messages
210
The loop checks for remaining hit points and sets the level of the damage bonus ability accordingly. At 100% hp the hero will have 10 bonus damage; at 90-99.99% hp the hero will have 9 bonus damage; at 80-89.99% hp the hero will have 8 bonus damage; etc.
 
Level 7
Joined
Feb 26, 2005
Messages
210
Using the sell event to keep track of every hero which avoids using unit groups and saves me a headache.

What is this about sleep time not equaling actual gameplay time? I want proof of this. Further; if the actual delay is still less than a third of a second it probably will not matter in this case.
 
BonusMod requires a custom editor which does not gel well with Warcraft 3

->huh? really? how come? it only uses NewGen which is perfectly compatible with wc3, and a lot of users use it...


RemoveLocation clears the location leak of the actual location, but the local variable will still be there...

haven't you read my explanation?

l1 -> location something -> null (since you destroyed it, so the location doesn't leak anymore)

if you null the local variable after destroying the location

l1 -> null

Both points to null but the first one points first to a location something which points to null


though I would prefer that you use Coordinates rather than locations, faster and you don't need to destroy or nullify anything
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
What is this about sleep time not equaling actual gameplay time? I want proof of this.

  • Wait
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Countdown Timer - Start timer as a One-shot timer that will expire in 30.00 seconds
      • Wait 0.00 seconds
      • Game - Display to Player Group - Player 1 (Red) the text: (String((Elapsed time for timer)))
      • Trigger - Run (This trigger) (checking conditions)
 
Status
Not open for further replies.
Top