HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Problem With Dash Spell

07-20-2007, 06:51 AM#1
Spiky
Hello everybody. I'm new here on wc3campaigns but not new to WE or JASS. But I'm having a slight problem with my dash spell. First let me upload my script:

Collapse JASS:
//*************************************************************
//* Constant Functions (Only edit things under this section.) *
//*************************************************************

constant function FW_Raw_Code takes nothing returns integer
  return 'A003'
endfunction

constant function FW_Move_Distance takes nothing returns real
  return 75.00
endfunction

constant function FW_Timer_Interval takes nothing returns real
  return 0.035
endfunction

//**************
//* Conditions *
//**************

function FW_Spell_Check takes nothing returns boolean
  return GetSpellAbilityId() == FW_Raw_Code()
endfunction

function FW_Filter_Check takes nothing returns boolean
  local timer dashtimer = GetExpiredTimer() //Can this local be used as linkage from my "FW_Dash" function Yes/No?
  local unit caster     = GetHandleUnit(dashtimer, "caster")
  
  return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(caster)) == true and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0
endfunction
  

//*************
//* Functions *
//*************

function FW_Dash takes nothing returns nothing
  //Local Variables & Handles
    local timer dashtimer    = GetExpiredTimer()
    local unit caster        = GetHandleUnit(dashtimer, "caster")
    local real X             = GetUnitX(caster)
    local real Y             = GetUnitY(caster)
    local real angle         = GetHandleReal(dashtimer, "angle")
    local real PolarX        = X + FW_Move_Distance() * Cos(angle * bj_DEGTORAD) 
    local real PolarY        = Y + FW_Move_Distance() * Sin(angle * bj_DEGTORAD)
    local unit enemy
    local group filtergroup  = CreateGroup()
    local boolexpr filter    = Condition(function FW_Filter_Check)
        
  //Group Adding
    call GroupEnumUnitsInRange(filtergroup, X, Y, 200.0, filter)
    
  //Functions
    if GetHandleReal(dashtimer, "dist") >= 0.0 then
      call SetHandleReal(dashtimer, "dist", GetHandleReal(dashtimer, "dist") - FW_Move_Distance())
      call SetUnitPosition(caster, PolarX, PolarY)
      loop
        set enemy = FirstOfGroup(filtergroup)
        exitwhen enemy==null
        if not IsUnitInGroup(enemy, GetHandleHandle(dashtimer, "dmgedgroup")) then
          call UnitDamageTarget(caster, enemy, 100.0, false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
          call GroupAddUnit(GetHandleHandle(dashtimer, "dmgedgroup"), enemy)
        endif
        call GroupRemoveUnit(filtergroup, enemy)
      endloop 
        
    else
      call PauseUnit(caster, false)
      call SetUnitPathing(caster, true)
      call PauseTimer(dashtimer)
      call DestroyTimer(dashtimer)
      set dashtimer = null
      call FlushHandleLocals(dashtimer)
      call DestroyGroup(GetHandleHandle(dashtimer, "dmgedgroup"))
      set GetHandleHandle(dashtimer, "dmgedgroup") = null
    endif
  
  //Null Variables
    set caster = null
    call DestroyGroup(filtergroup)
    set filtergroup = null
    set enemy = null 
endfunction

function FW_Spell takes nothing returns nothing
  //Local Variables
    local timer dashtimer      = CreateTimer()
    local unit caster          = GetTriggerUnit()
    local location casterpos   = GetUnitLoc(caster)
    local location targetpoint = GetSpellTargetLoc()
    local real dist            = DistanceBetweenPoints(casterpos,targetpoint)
    local real angle           = AngleBetweenPoints(casterpos, targetpoint)
    local group dmgedgroup     = CreateGroup()
    
  //Handle Settings
    call SetHandleHandle(dashtimer, "caster", caster)
    call SetHandleReal(dashtimer, "dist", dist)
    call SetHandleReal(dashtimer, "angle", angle)
    call SetHandleHandle(dashtimer, "dmgedgroup", dmgedgroup)
    
  //Functions
    call PauseUnit(caster, true)
    call SetUnitPathing(caster, false)
    call TimerStart(dashtimer, FW_Timer_Interval(), true, function FW_Dash)
    call PolledWait(2.0)
      
  //Null Variables & Remove Locations
    set caster      = null
    call RemoveLocation(casterpos)
    call RemoveLocation(targetpoint)
    set casterpos   = null
    set targetpoint = null   
endfunction

//===========================================================================
function InitTrig_Flame_Walk takes nothing returns nothing
local integer i
    set i = 0
    set gg_trg_Flame_Walk = CreateTrigger(  )
    loop
      exitwhen i>12
      call TriggerRegisterPlayerUnitEventSimple( gg_trg_Flame_Walk, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT)
      set i = i + 1
    endloop
    call TriggerAddCondition( gg_trg_Flame_Walk, Condition(function FW_Spell_Check))
    call TriggerAddAction( gg_trg_Flame_Walk, function FW_Spell )
endfunction

The problem is, when I dash by units, they take multiple jolts (I can't find the word to use) of damage. So like they would 300 damage when the spell is only supposed to deal 100. (That's just an example) How would I go about doing damage like this only once to a unit?

I have used a unit group but there's no way I can store a group onto a handle so I can add the units that have already been damaged to that group so they won't take damage next time.

How will I do this? I don't want NewGen because I want people that don't have NewGen to be able to edit and use my script.

Thanks in advanced.

~Spiky
07-20-2007, 07:50 AM#2
Pyrogasm
What do you mean you can't attach a group? You most definitely can. Simply add units to the group after they're damaged and check to see if they're in it before you damage them.
07-20-2007, 08:22 AM#3
Spiky
I am getting: "Invalid Argument Type (Handle)" and I'm pretty sure I'm using the right linkage so it has to be the group. Please look at my script, I attached it but it's still giving me an error.
07-20-2007, 03:34 PM#4
Castlemaster
I had the displeasure of building my own dash spell from scratch.
I did not read through your code closely, but I'm going to guess that you have the problem of "overlap" in your damage commands, which would be fixed by using unit groups to damage a unit only once.

I circumventing this problem by adding the units to a group then damaging them at the END of the trigger after the dash is done. This of course works well only if the dash is fast enough for the delay to not be noticed.

This might not be the most efficient method but it eliminated the "double damage" problems and simplified the trigger.
07-20-2007, 09:34 PM#5
Spiky
I still wouldn't be able to keep track of that group because I can't store the group into a handle. Was a great idea but I don't know how I'll go through with it.
07-20-2007, 09:53 PM#6
ClichesAreSt00pid
Maybe you can use a unit var with arrays, and an integer indexing how big the array is, so if you've hit 4 units it will set the array integer to 4, and set the index to each unit (so if the integer is 4, it would set the striked unit to the 5th array and set the integer to 5), then go through a loop checking if that unit is not in any of the arrays.
07-20-2007, 11:13 PM#7
Av3n
Thts y we use the FirstOfGroup function loop ... anyways I c you are using it but i think its better tht u don't use a filter. instead sort things out within the loop using if/then/else. I think its better because I think it is. Well your filter is leaking anyway (unit and timer vars) use bj_ghoul instead (array bj variable(Pyro taught me tht)). Also don't be an tard because RegisterAnyUnitBJ(whatever it is called) is a bj function, imagine what would happen if it wasn't there. We make the code longer and more complicated.

-Av3n
07-21-2007, 03:21 AM#8
Spiky
The Dash Spell problem has been resolved.