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

[Spell] Heal everybody in a line between Blink start and destination?

Status
Not open for further replies.
Level 5
Joined
Mar 19, 2004
Messages
33
Hello,

for a healer-type hero I have imagined a Blink ability that heals all friendly units between the starting point and destination of the Blink. I'd like the healing to occur immediately upon the Blink. How would I go about doing this? I am very weak with mathematics, and WorldEdit seems to be lacking a few variables in comparison to the SC2 editor.

Sorry if this is a silly question, I am quite the noob with WorldEdit as I haven't touched it in a good half decade. The existing threads regarding "damage in a line" I have found were all about a line that moves from start to finish, like Carrion Swarm or Shockwave. I'd like my healing to be immediate, however, so this probably requires SUPER ADVANCED MATH rather than a dummy unit sent from point 1 to point 2. I hope you can help me out.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
nah it doesn't (if the healing amount is a constant)

Create a dummy abil based on shockwave or carrion swarm. Set max dmg to 0. Hold shift and set damage dealt to (minus sign)(whatever your damage is) that will set it to a negative amount, thus healing

Now swap targets allowed field so that enemies arent targets but allies are.

Than do stuff like casting time to 0, mana cost to 0, etc. missle speed to 0 (will cause it to be instant) than give it to a dummy unit and cast it from the start of the blink to the position of the end of the blink
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Hello,

for a healer-type hero I have imagined a Blink ability that heals all friendly units between the starting point and destination of the Blink. I'd like the healing to occur immediately upon the Blink. How would I go about doing this? I am very weak with mathematics, and WorldEdit seems to be lacking a few variables in comparison to the SC2 editor.

Sorry if this is a silly question, I am quite the noob with WorldEdit as I haven't touched it in a good half decade. The existing threads regarding "damage in a line" I have found were all about a line that moves from start to finish, like Carrion Swarm or Shockwave. I'd like my healing to be immediate, however, so this probably requires SUPER ADVANCED MATH rather than a dummy unit sent from point 1 to point 2. I hope you can help me out.

Illidan got right but if u want make without negative value then u must pick all unit in range more times till u reach the target, so something like this, u pick every ally in 60 range and but each time closer to target with 50 range till you reach the target point

in gui have point with polar offset what do same, just the angle must be "angle beetween 2 point" when u use point with polar offset

JASS:
function Trig_Heal_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A009'
endfunction

function HealTimer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local integer cv
    local unit u = LoadUnitHandle(udg_Spell_Table, id, 1)
    local unit pu
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real ang = LoadReal(udg_Spell_Table, id, 2)
    local real nx = LoadReal(udg_Spell_Table, id, 5) + 50 * Cos(ang * bj_DEGTORAD)
    local real ny = LoadReal(udg_Spell_Table, id, 6) + 50 * Sin(ang * bj_DEGTORAD)
    local real distance = LoadReal(udg_Spell_Table, id, 3) - 50
    local integer cliff = LoadInteger(udg_Spell_Table, id, 4)

    if distance > 0 and cliff==GetTerrainCliffLevel(nx, ny) then
        call SaveReal(udg_Spell_Table, id, 3, distance)
        call SaveReal(udg_Spell_Table, id, 5, nx)
        call SaveReal(udg_Spell_Table, id, 6, ny)
        call GroupEnumUnitsInRange(udg_UG, nx, ny, 60, null)
        loop
            set pu = FirstOfGroup(udg_UG)
            exitwhen (pu==null)
            if not IsUnitEnemy(pu, GetOwningPlayer(u)) then
                set cv = GetHandleId(pu)
                if LoadInteger(udg_Misc_Table, id, cv) == 0 then
                     SetWidgetLife(pu, GetWidgetLife(pu) + LoadReal(udg_Spell_Table, id, 7))
                endif
                call SaveInteger(udg_Misc_Table, id, cv, 1)
            endif
            call GroupRemoveUnit(udg_UG, pu)
        endloop
        call DestroyEffect(AddSpecialEffect ("Abilities\\Spells\\Orc\\Shockwave\\ShockwaveMissile.mdl", nx , ny))
        call TimerStart(t, 0.03, false, function HealTimer)

    else
        call SetUnitVertexColor(u, 255, 255, 255, 255)
        if GetLocalPlayer() == GetOwningPlayer(u) then
            call ClearSelection()
            call SelectUnit(u, true)
        endif
        call SetUnitPosition(u, nx, ny)
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(udg_Spell_Table, id)
        call FlushChildHashtable(udg_Misc_Table, id)
    endif

    set t = null
    set u = null
    set pu = null
endfunction

function Trig_Heal_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local real ang = GetUnitFacing(u)
    local integer cliff = GetTerrainCliffLevel(GetUnitX(u), GetUnitY(u))
    local timer t = CreateTimer()
    local integer alv = GetUnitAbilityLevel(u, 'A009')    
    local integer id = GetHandleId(t)
    local real distance = 350+alv*50
    local real heal = 100

    call SetUnitVertexColor(u, 255, 255, 255, 0)

    call SaveUnitHandle(udg_Spell_Table, id, 1, u)
    call SaveReal(udg_Spell_Table, id, 2, ang)
    call SaveReal(udg_Spell_Table, id, 3, distance)
    call SaveInteger(udg_Spell_Table, id, 4, cliff)
    call SaveReal(udg_Spell_Table, id, 5, GetUnitX(u))
    call SaveReal(udg_Spell_Table, id, 6, GetUnitY(u))
    call SaveReal(udg_Spell_Table, id, 7, heal)
    call TimerStart(t, 0.03, false, function HealTimer)

    set u = null
    set t = null
endfunction

//===========================================================================
function InitTrig_Heal takes nothing returns nothing
    set gg_trg_Heal = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Heal, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Heal, Condition( function Trig_Heal_Conditions ) )
    call TriggerAddAction( gg_trg_Heal, function Trig_Heal_Actions )
endfunction
 
Last edited:
Level 5
Joined
Mar 19, 2004
Messages
33
nah it doesn't (if the healing amount is a constant)

Create a dummy abil based on shockwave or carrion swarm. Set max dmg to 0. Hold shift and set damage dealt to (minus sign)(whatever your damage is) that will set it to a negative amount, thus healing

Now swap targets allowed field so that enemies arent targets but allies are.

Than do stuff like casting time to 0, mana cost to 0, etc. missle speed to 0 (will cause it to be instant) than give it to a dummy unit and cast it from the start of the blink to the position of the end of the blink

This sounds really nice, however... Aren't Shockwave and Carrion Swarm abilities with fixed distances? Wouldn't that mean that they'd always heal the full maximum Blink length even if the hero blinks a shorter distance?

Also, I can't seem to set the damage value to something negative. Holding shift does nothing. Do I need to use some extended custom editor?
 
Level 3
Joined
Jan 31, 2012
Messages
42
It works, I hope.
JASS:
//! zinc
library HealBlink {
    constant integer ABILITY = 'A000';
    constant real SQUARE_WIDTH = 5625.;//75^2
    constant real HEAL = 150.;
    constant group G = CreateGroup();

    function onInit() {
        trigger trig = CreateTrigger();
        integer i = 0;
        do {
            TriggerRegisterPlayerUnitEvent(trig, Player(i),
                EVENT_PLAYER_UNIT_SPELL_EFFECT, null);
            i += 1;
        } while (i < 16);
        TriggerAddCondition(trig,
            function() -> boolean {
                return GetSpellAbilityId() == ABILITY;
            }
        );
        TriggerAddAction(trig,
            function() {
                unit u = GetTriggerUnit(), u2;
                player p = GetOwningPlayer(u);
                real x = GetWidgetX(u), y = GetWidgetY(u),
                    tx = GetSpellTargetX(), ty = GetSpellTargetY(),
                    k = (y - ty) / (x - tx), b = y - k * x,
                    k1 = -1. / k, b1;
                GroupEnumUnitsInRange(G, (x + tx) * .5, (y + ty) * .5,
                    SquareRoot((x - tx) * (x - tx) + (y - ty) * (y - ty)) * .5, null);
                while (true) {
                    u2 = FirstOfGroup(G);
                    if (u2 == null) { break; }
                    GroupRemoveUnit(G, u2);
                    if (IsUnitAlly(u2, p)) {
                        tx = GetWidgetX(u2);
                        ty = GetWidgetY(u2);
                        b1 = ty - k1 * tx;
                        x = (b1 - b) / (k - k1);
                        y = k * x + b;
                        if ((x - tx) * (x - tx) + (y - ty) * (y - ty) <= SQUARE_WIDTH) {
                            SetWidgetLife(u2, GetWidgetLife(u2) + HEAL);
                        }
                    }
                }
                u = null; p = null;
            }
        );
        trig = null;
    }
}
//! endzinc
 
Level 5
Joined
Mar 19, 2004
Messages
33
This looks promising! I'd like to find out if it works, but I'm not sure how to add it to the Editor and what I have to change to make it work with my map (for example, how to get my Blink ability's id). Do I paste this into a "custom code" trigger? Again, sorry for these newbish questions, but I can't seem to find any tutorials on how to embed code snippets into maps.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
SirNicolas what wrote it is vjass, idk that

mine need make a trigger with Heal trigger name, convert to text and delete everything what is inside and replace it to mine jass with copy paste but still dont work because u also must create few variable like:
UG = unit group variable
Misc_Table = hashtable (hashtables u can create at map init then ex. Misc_Table = last created hashtable)
Spell_Table = hashtable

if u want i can add to your map
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
create a trigger

click it in the trigger menu

go to edit

hit "convert to custom text"

and paste that

e/ sirnicloas wrote ZINC, which is a form of jass that closely resembles C# and C++
 
Level 5
Joined
Mar 19, 2004
Messages
33
Ohh! It seems to work. Thank you very much, everyone!

I'll try expanding the code to add visual heal effects to each affected unit and to make it so that the hero leaves an illusion at his initial location if he blinks while a certain buff is active. I hope I can pull it off with tutorials! Thanks again. <3
 
Status
Not open for further replies.
Top