• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] How i can define all units wich got a damage from the forcked lightning?

Status
Not open for further replies.
Level 3
Joined
Dec 7, 2012
Messages
52
Hi!
If i cast "forcked lightning" i need else (with custom trigger) reduce mana for all target units, but in my case [call SetUnitState(Target, UNIT_STATE_MANA, (Mana - 35.00))] is wrong way, becouse factualy [Target] - is one unit and mana will decrease only for this unit, but not for all units wich got a damage from the lightning!
How i can define all units wich got a damage from the forcked lightning?
---
Need Help!
 
Level 1
Joined
Mar 7, 2016
Messages
5
if your trigger is AnyUnitSpellAbility,it only difine one targetunit.
you can do it like this.
trigger
AnyUnitDamgeEvent,i think you can get this trigger
condition
UnitHasBuffBJ(whichunit,buffcode)==true
action
call SetUnitState()
 
Level 3
Joined
Dec 7, 2012
Messages
52
The simplest solution would be to just remake Forked Lightning with triggers.

If I knew how - it will be simplest solution, of course! But how?..

I read post (not in HV) where author writte about some system that allows to add necessary parameters to custom ability "channel" (damage, mana, effects, etc.) by means of calling some functions wich take data in files *.slk in war3x.mpq... is this possible?
 
Level 24
Joined
Aug 1, 2013
Messages
4,658
You can make a dummy unit that casts the forked lightning.
If the damage taken (using a DDS) comes from such a dummy, the damage is from forked lightning.
Then you can use a unit indexer and arrays to link back to the original source to do whatever you want.

However, if you can trigger it, then it is always recommended to do so.
Triggering it is quite easy.
First you have to pick all units in a cone.
I wrote this script for many functions like these... and many bullshit functions as well :D
In any case, just drop this in the header script of your map.
JASS:
    //Returns the angle from xy1 to xy2 in radians(Rad)/degrees(Deg)
    //The returned value is between -180 and 180 for degrees and between -PI and PI for radians.
    function AngleBetweenCoordinatesRad takes real x1, real y1, real x2, real y2 returns real
        return Atan2(y2 - y1, x2 - x1)
    endfunction
    function AngleBetweenCoordinatesDeg takes real x1, real y1, real x2, real y2 returns real
        return AngleBetweenCoordinatesRad(x1, y1, x2, y2) * RADTODEG
    endfunction
    
    //Returns a normalized angle from the given angle.
    //Normalized angles are between 0 and 360 for degrees and 0 and TAU for radians.
    function NormalizeAngleRad takes real angle returns real
        local real modulus = angle - I2R(R2I(angle / TAU)) * TAU
        if modulus < 0 then
            set modulus = modulus + TAU
        endif
        return modulus
    endfunction
    function NormalizeAngleDeg takes real angle returns real
        local real modulus = angle - I2R(R2I(angle / 360)) * 360
        if modulus < 0 then
            set modulus = modulus + 360
        endif
        return modulus
    endfunction
    //Deprecated function pointing at "NormalizeAngleDeg()" for backwards compatibility.
    
    //Returns a denormalized angle from the given angle.
    //Denomalized angles are between -180 and 180 for degrees and -PI and PI for radians.
    function DenormalizeAngleRad takes real angle returns real
        return NormalizeAngleRad(angle) - PI
    endfunction
    function DenormalizeAngleDeg takes real angle returns real
        return NormalizeAngleDeg(angle) - 180
    endfunction

    //Groups all units in a cone facing "direction" degrees from position ("x", "y").
    //"radius" is the length of the cone. "size" is the maximum difference in angle in radians(Rad)/degrees(Deg) from ("x", "y") towards the unit.
    //Returns "whichGroup" for easy usage: "local group g = GroupEnumUnitsInCone(CreateGroup(), x, y, r, d, s)".
    function GroupEnumUnitsInConeRad takes group whichGroup, real x, real y, real radius, real direction, real size returns group
        local unit FoG
        local group g = CreateGroup()
        local real x2
        local real y2
        local real difference
        
        call GroupEnumUnitsInRange(g, x, y, radius, null)
        loop
            set FoG = FirstOfGroup(g)
            exitwhen FoG == null
            call GroupRemoveUnit(g,FoG)
            
            set difference = RAbsBJ(DenormalizeAngleRad(AngleBetweenCoordinatesRad(x, y, GetUnitX(FoG), GetUnitY(FoG)) - direction))
            if difference > -size and difference < size then
                call GroupAddUnit(whichGroup, FoG)
            endif
        endloop
        
        call DestroyGroup(g)
        set g = null
        return whichGroup
    endfunction
    function GroupEnumUnitsInConeDeg takes group whichGroup, real x, real y, real radius, real direction, real size returns group
        local unit FoG
        local group g = CreateGroup()
        local real x2
        local real y2
        local real difference
        
        call GroupEnumUnitsInRange(g, x, y, radius, null)
        loop
            set FoG = FirstOfGroup(g)
            exitwhen FoG == null
            call GroupRemoveUnit(g,FoG)
            
            set difference = DenormalizeAngleDeg(AngleBetweenCoordinatesDeg(x, y, GetUnitX(FoG), GetUnitY(FoG)) - direction)
            if difference > -size and difference < size then
                call GroupAddUnit(whichGroup, FoG)
            endif
        endloop
        
        call DestroyGroup(g)
        set g = null
        return whichGroup
    endfunction

The method is pretty simple and easy to use in GUI as well.
At least if you know how to use global variables in custom scripts.
  • Actions
    • Set TempReal[0] = 0.00
    • Set TempReal[1] = 0.00
    • Set TempReal[2] = 0.00
    • Set TempReal[3] = 0.00
    • Set TempReal[4] = 0.00
    • Custom script: set udg_TempGroup[0] = GroupEnumUnitsInConeDeg(CreateGroup(), udg_TempReal[0], udg_TempReal[1], udg_TempReal[2], udg_TempReal[3], udg_TempReal[4])
    • Unit Group - Pick every unit in TempGroup[0] and do (Actions)
      • Loop - Actions
    • Custom script: call DestroyGroup(udg_TempGroup[0])
You need two global variables:
unit group array TempGroup
real array TempReal

Then you only have to set the parameters.
TempGroup[0] is the group that will be filled with it.
TempReal[0] and TempReal[1] are the coordinates of the origin of the cone (x and y of the caster).
TempReal[2] is the maximum range of the cone. (max range of spell)
TempReal[3] is the direction of the cone. (angle between caster and target)
TempReal[4] is the size of the cone. (45 for a quarter of a circle, 90 for a half of a circle, etc)

In the loop, you have to check if the picked unit is an enemy of the caster, is alive and is not a structure... you can add more checks but those are the basic ones.
Then you can deal the damage you need.

To make a nice effect, you should be making a lightning effect between the source and the target.
You can use TimedLightnings (a system in the spell section by Maker) to make a 0.5 seconds lightning between two units that will automatically update the positions etc.

Then... you are pretty much done.
 
Level 3
Joined
Dec 7, 2012
Messages
52
TO: Wietlol
oh!.. nice solution!
Maybe you can help me also with this?:
--
how to appoint start point of launch the forked lightning? It launch from "origin" of my unit, but i want to launch it from weapon of unit!.. but i don't know how...
 
Level 24
Joined
Aug 1, 2013
Messages
4,658
Thats horrible.
And on top of that, it wont work 90% of the time.

You can make a dummy unit that casts the forked lightning.
If the damage taken (using a DDS) comes from such a dummy, the damage is from forked lightning.
Then you can use a unit indexer and arrays to link back to the original source to do whatever you want.

This is a much better option than to assume that your damage is not going to change from 0.01 to anything else...
 
Status
Not open for further replies.
Top