• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Reduced Damage From Allies

Status
Not open for further replies.

xNS

xNS

Level 2
Joined
May 1, 2010
Messages
9
I need an ability or trigger to make all units or even just heroes receive 50% damage from friendly units.
 
Level 6
Joined
Mar 22, 2009
Messages
276
Do what Pharaoh said, use a damage detection system.
Because if you use the event "Unit - A unit is attacked" it can be abused by canceling the attack order given before it lands an attack making it heal your friendly attacked unit.
 
Level 11
Joined
Aug 1, 2009
Messages
714
Do something like this
Trigger #1
  • Map Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set DD_Sys_Group = (Units in (Playable map area))
      • Unit Group - Pick every unit in DD_Sys_Group and do (Actions)
        • Loop - Actions
          • Trigger - Add to Ally Damage Reduction <gen> the event (Unit - (Picked unit) Takes damage)
      • Custom script: call DestroyGroup (udg_DD_Sys_Group)
Trigger #2
  • Damage Detection Add Unit
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
    • Actions
      • Trigger - Add to Ally Damage Reduction <gen> the event (Unit - (Triggering unit) Takes damage)
Trigger #3
  • Ally Damage Reduction
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Damage source) belongs to an ally of (Owner of (Triggering unit))) Equal to True
        • Then - Actions
          • Unit - Set life of (Triggering unit) to ((Life of (Triggering unit)) + ((Damage taken) x 0.50))
        • Else - Actions
 
Level 11
Joined
Aug 1, 2009
Messages
714
I have edit it.
Trigger #3
  • Ally Damage Reduction
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Damage source) belongs to an ally of (Owner of (Triggering unit))) Equal to True
        • Then - Actions
          • Wait 0.01 seconds
          • Unit - Set life of (Triggering unit) to ((Life of (Triggering unit)) + ((Damage taken) x 0.50))
        • Else - Actions
Well I just put the wait 0.01 seconds.
 
Level 9
Joined
Aug 21, 2008
Messages
533
you cant wait 0.01 seconds, waits always is at least 0.25(or 0.27?).
putting it to a lower value does not have hte effect.

You have to use a timer, which lasts 0.00. SO it expires instantly, but still waits till all other actions are made.

This is important, cause theroreicly a unit is damaged, after the event "is damaged" fires.
 
Level 19
Joined
Feb 4, 2009
Messages
1,313
timers are not fast enough in every case as well
this is what worked in every case I could imagine
I don't know much about JASS so there might be a few things to optimize
just multiply the dmg taken by 0.5 if source was an allied unit
if you got a spell or something like that in your map which can kill a unit with a single blow even if it had 300 more hp you will have to change the stats of the greater life bonus ability to a bigger value
JASS:
function Dmg_Reset takes nothing returns nothing
    call UnitRemoveAbility(udg_Dmg_Target, 'AIl2')//+300 Hp Greater Life Bonus
    call SetUnitState(udg_Dmg_Target, UNIT_STATE_LIFE, udg_Dmg_Life)
    set udg_Dmg_Taken = 0.00//Set Dmg Taken to 0 so the trigger knows that unit got healed already
endfunction

function DmgEvent_Actions takes nothing returns nothing
    if udg_Dmg_Taken != 0.00 then//If timer did not run yet the unit will be healed
        call UnitRemoveAbility(udg_Dmg_Target, 'AIl2')
        call SetUnitState(udg_Dmg_Target, UNIT_STATE_LIFE, udg_Dmg_Life)
    endif
    set udg_Dmg_Target = GetTriggerUnit()
    set udg_Dmg_Source = GetEventDamageSource()
    set udg_Dmg_Taken = GetEventDamage()
    set udg_Dmg_Life = GetUnitState(udg_Dmg_Target, UNIT_STATE_LIFE)
    call UnitAddAbility(udg_Dmg_Target, 'AIl2')
    call SetUnitState(udg_Dmg_Target, UNIT_STATE_LIFE, udg_Dmg_Life+300.00)
    call TimerStart(udg_Dmg_Timer, 0.00, false, function Dmg_Reset)//Start timer to heal
endfunction
//Might be even better with a condition to check if the timer and ability is really necessary
//And there might be a bug but I didn't test yet:
//1. Unit is healed before timer is over
//2. Unit takes damage again
//3. Unit is healed again
//If this is possible to happen it would only matter for x times damage absorption and could be prevented with another if anyway
//However the advantage of all this stuff is that one does not need a hashtable to check things

//Create events (only leaks once per unit, if you got enough units to notice the leak you got bigger problems)
function AddEnter_Actions takes nothing returns nothing
    call TriggerRegisterUnitEvent(gg_trg_DmgEvent, GetTriggerUnit(), EVENT_UNIT_DAMAGED)
endfunction
function DmgEvent_Add takes nothing returns nothing
    call TriggerRegisterUnitEvent(gg_trg_DmgEvent, GetEnumUnit(), EVENT_UNIT_DAMAGED)
endfunction
function InitTrig_DmgEvent takes nothing returns nothing
    local trigger AddEnter  = CreateTrigger()
    set gg_trg_DmgEvent     = CreateTrigger()
    call TriggerAddAction(AddEnter, function AddEnter_Actions)
    call TriggerAddAction(gg_trg_DmgEvent, function DmgEvent_Actions)
    call TriggerRegisterEnterRectSimple(AddEnter, bj_mapInitialPlayableArea)
    call GroupEnumUnitsInRect(udg_g, bj_mapInitialPlayableArea, null)
    call ForGroup(udg_g, function DmgEvent_Add)
endfunction
 
Level 7
Joined
Jun 14, 2009
Messages
235
Yes, I meant something like cboy123, but, that trigger will not work properly. If you have full hp and you receive damage, the healing part won't be done. Your life will never go full, if you get attacked. This is why you need a timer that will expire in 0.00 seconds.

wait... then how do they make things prevent death?

will it heal you fast enough, that even if something would take you from 100% to 0, it wont kill you?
 
Status
Not open for further replies.
Top