• 🏆 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] spell help

Status
Not open for further replies.
Level 9
Joined
Jun 7, 2008
Messages
440
Hello friend Hivers.

I am having some difficulty with this minor ability i am making. What the inteded purpose is, attacked unit moves instantly behind attacking unit.

This is what I have:
JASS:
function Trig_TrigStep_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local unit c = GetAttacker()
    local real dist = 500
    local real angle = Atan2(GetUnitY(u) - GetUnitY(c), GetUnitX(u) - GetUnitX(c))
    local real x = (Cos(angle) * dist)
    local real y = (Sin(angle) * dist)
    local real a = GetUnitState(c, UNIT_STATE_LIFE) - 100
    local integer temp = GetRandomInt(1, 100)
    if temp > 15 then
        set u = null
        set c = null
        return
    endif
    call AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl", u, "chest")
    call DestroyEffect( bj_lastCreatedEffect )
    call SetUnitPosition(u, x, y)
    call SetUnitState(c, UNIT_STATE_LIFE, a)
    set u = null
    set c = null
endfunction

Now, the trigger fires. But Im sent to a spot way accross the map, nowhere near the opponent. Any Ideas ( I think the " local real angle = Atan2(GetUnitY(u) - GetUnitY(c), GetUnitX(u) - GetUnitX(c))" Is what is messing my script.)?
 
Level 3
Joined
Apr 17, 2008
Messages
41
The AngleBetweenPoints function is:
JASS:
function AngleBetweenPoints takes location locA, location locB returns real
    return bj_RADTODEG * Atan2(GetLocationY(locB) - GetLocationY(locA), GetLocationX(locB) - GetLocationX(locA))
endfunction

The way you have it set up right now takes the angle from the attacker to the attacked unit, which would move your attacked unit a distance of 500 in the opposite direction you want to move him.

Some other things:
It seems like this could be added in a condition,
JASS:
local integer temp = GetRandomInt(1, 100)
if temp > 15 then
    set u = null
    set c = null
    return
endif
JASS:
function Conditions takes nothing returns boolean
    return GetRandomInt(1,100)<=15
endfunction
Instead of GetUnitState/SetUnitState for getting and setting life, you should use the function GetWidgetLife/SetWidgetLife.
JASS:
local real a = GetUnitState(c, UNIT_STATE_LIFE) - 100
call SetUnitState(c, UNIT_STATE_LIFE, a)
to...
JASS:
local real a=GetWidgetLife(c)-100
call SetWidgetLife(c,a)
I imagine that you want the caster to damage the enemy. Setting the unit life isn't damaging it, so the caster will not receive the kill for the unit if the unit dies. You should use UnitDamageTarget instead:
JASS:
call SetWidgetLife(c,a)// change this to call UnitDamageTarget(u,c,100.,true,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_NORMAL,null)
local real a=GetWidgetLife(c)-100//Remove this line
and,
JASS:
    call AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl", u, "chest")
    call DestroyEffect( bj_lastCreatedEffect )
should be
JASS:
    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl", u, "chest"))

Edit: After looking at it again, I noticed this.
JASS:
    local real x = (Cos(angle) * dist)
    local real y = (Sin(angle) * dist)
    call SetUnitPosition(u, x, y)

That's the other reason why it's not moving where you want.
 
Last edited:
Level 37
Joined
Mar 6, 2006
Messages
9,240
JASS:
    local unit u1 = GetTriggerUnit()
    local unit u2 = GetAttacker()
    local real r1 = GetUnitFacing(u1)
    local real r2 = GetUnitX(u1)
    local real r3 = GetUnitY(u1)
    local real r4 = (r1 - 180) * bj_DEGTORAD
    set r2 = r2 + 128 * Cos(r4)
    set r3 = r3 + 128 * Sin(r4)

    call SetUnitX(u2 , r2)
    call SetUnitY(u2 , r3)

    call SetUnitPosition(u2 , r2 , r3)

    call SetUnitFacing(u2 , r1)

This moves the attacking unit to the back of the attacked unit, offset by 128, based on the facing of the attacked unit.

Use either those SetUnitX/Y or SetUnitPosition. SetUnitPosition checks for collision, SetUnitX/Y does not.

I didn't remove leaks.
 
Level 1
Joined
May 1, 2010
Messages
3
SetUnitX and SetUnitY don't pause the unit (so don't interrupt the units orders), right?
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Well SetUnitPosition interrupts its current orders; even if you were moving the unit repeatedly to its own coordinates it would still maintain a "paused" state. I believe that is what was meant when xzeth commented on how SetUnitX and SetUnitY do not have any sort of pause or interruption stringed to the execution of the native.
 
Level 1
Joined
May 1, 2010
Messages
3
^ Yeah, that's what I meant.

Thanks for the information about SetUnitPosition. I thought the function pause the unit like PauseUnit. :)
 
Status
Not open for further replies.
Top