• 🏆 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] Sinkhole Spell - Not Working

Status
Not open for further replies.
Level 6
Joined
Jan 15, 2005
Messages
188
I have a sinkhole spell which works somewhat and somewhat doesn't. Here's the jass:

JASS:
//This is the initiator for the spell, using the Caster System:
function InitTrig_MultiSpells takes nothing returns nothing
    call OnAbilityEffect('A065',"Sinkhole_Actions")
    //Since this OnAbilityEffect function initalizes by created a new trig to
    //    actually do the spell, you can remove this trig after this trig is
    //    initialized.
    call QueuedTriggerRemoveBJ( GetTriggeringTrigger() )
endfunction

//These functions are all in a library, and I'm almost 100% sure they both work flawlessly:
function my_DistanceBetweenPoints takes real x1, real y1, real x2, real y2 returns real
  local real x = x2 - x1
  local real y = y2 - y1
    return SquareRoot( x*x + y*y )
endfunction
function my_DistanceBetweenUnitAndLocation takes unit u1, location loc returns real
    return my_DistanceBetweenPoints( GetUnitX(u1), GetUnitY(u1), GetLocationX(loc), GetLocationY(loc) )
endfunction
function my_AngleBetweenPoints takes real x1, real y1, real x2, real y2 returns real
    return bj_RADTODEG * Atan2( y2 - y1, x2 - x1 )
endfunction
function my_AngleBetweenUnitAndLocation takes unit u, location loc returns real
    return my_AngleBetweenPoints( GetUnitX(u), GetUnitY(u), GetLocationX(loc), GetLocationY(loc) )
endfunction

//Finally, these are the actions for the spell:
function Sinkhole_Movement takes unit u, location loc, unit caster returns nothing
  local real angle = 0.0
  local real distance = 0.0
    
    set angle = my_AngleBetweenUnitAndLocation(u, loc)
    set distance = my_DistanceBetweenUnitAndLocation(u, loc)
    if ((angle >= 270.0)  or  (angle <= 90.0)) then
        call SetUnitX(u, GetUnitX(u) + distance/(distance*5))
    else
        call SetUnitX(u, GetUnitX(u) - distance/(distance*5))
    endif
    if ((angle >= 180.0)  and  (angle <= 360.0)) then
        call SetUnitY(u, GetUnitY(u) - distance/3)
    else
        call SetUnitY(u, GetUnitY(u) + distance/3)
    endif
    if ((IsUnitEnemy(u, GetOwningPlayer(caster)) == true)  and  (distance <= 300.0)) then
        call UnitDamageTarget(caster, u, GetHeroAgi(caster, true), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS)
    endif
    
  //Clean up
  set u=null
  set loc=null
  set caster=null
endfunction
function Sinkhole_Actions takes nothing returns nothing
  local unit u = GetTriggerUnit()
  local unit temp = null
  local location loc = GetSpellTargetLoc()
  local group g = CreateGroup()
  local integer count = 10
  local integer int2 = 10
    
    call TerrainDeformCrater(GetLocationX(loc), GetLocationY(loc), 500.0, 150.0, 4000, true)
    loop
        loop
            call GroupEnumUnitsInRangeOfLoc(g, loc, 500.0, null)
            loop
                set temp = FirstOfGroup(g)
                call GroupRemoveUnit(g, temp)
                if (temp != null) then
                    call Sinkhole_Movement(temp, loc, u)
                endif
                exitwhen temp == null
            endloop
            call PolledWait(0.04)
            set int2 = int2 - 1
            exitwhen int2 <= 0
        endloop
        set int2 = 10
        set count = count - 1
        exitwhen count <= 0
    endloop
    call TerrainDeformCrater(GetLocationX(loc), GetLocationY(loc), 500.0, -150.0, 1000, true)
    
  call DestroyGroup(g)
  //Clean up
  set u=null
  set loc=null
endfunction

EDIT: Realized too late that I should include what it does. It pulls all enemies within 500 range of the epicenter towards the middle - getting stronger the closer they are. Then, if they're within 300 of the epicenter, they take damage. It uses SetUnitX/SetUnitY to make sure the unit is able to move during the pull.

What doesn't work:

- The pull doesn't work at all - it doesn't move any units around the sinkhole.
- Instead of lasting for 4 seconds like I hoped it would (10(outer loops)*10(inner loops)*0.04(PolledWait periods), the terrain deformation AND trigger lasts longer.


What cannot be compromised:

- The victims must be able to move! Otherwise, the spell is completely overpowered!

Anyone willing to help and/or give advice is greatly appreciated, and I will give rep!
 
Last edited:
Level 6
Joined
Jan 15, 2005
Messages
188
We just have a collection of functions and we don't see all the functions you use, the event, etc.

What do you mean? The event is registered and the spell goes through (using the Caster System)... just as it was commented. A few things don't work, though. I put a description of what the spell does up there if you're looking for that. I'm mainly looking at the Sinkhole_Movement part of the spell...
 
Level 6
Joined
Jan 15, 2005
Messages
188
What if I added set g=null to the end of the loop it's in to allow it to be re-made again? Like this (it's commented just in case):

JASS:
    loop
        loop
            call GroupEnumUnitsInRangeOfLoc(g, loc, 500.0, null)
            loop
                set temp = FirstOfGroup(g)
                call GroupRemoveUnit(g, temp)
                if (temp != null) then
                    call Sinkhole_Movement(temp, loc, u)
                endif
                exitwhen temp == null
            endloop
            call PolledWait(0.04)
            set int2 = int2 - 1
            //set g = null
            exitwhen int2 <= 0
        endloop
        set int2 = 10
        set count = count - 1
        exitwhen count <= 0
    endloop

It needs to be able to do this because otherwise even when units get out of the hole, they will still be sucked in. And anyone who enters would be unaffected.
 
Last edited:
Level 23
Joined
Nov 29, 2006
Messages
2,482
Polled waits or Trigger Sleep action has a thresholf of ~0.27 seconds. Thus meaning the spell will last way longer than it should. (0.27*10outer*10inner). This can be solved by implenting a timer instead.
 
Status
Not open for further replies.
Top