• 🏆 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] Voodoo Curse (AoE Periodic Timer)

Status
Not open for further replies.
Level 13
Joined
Jul 26, 2008
Messages
1,009
Alright, what this spell is suppose to do is curse one random unit in a 650 range every 0.75 for 5.75 seconds. Meaning it happens 7 times. The curse can be one of five things. Curse, Sleep, Impale, Attack an Ally, or Move to a random spot. The latter two elicit the idea of body manipulation thru Voodoo.

Unfortunately I'm not sure how to finish the trigger that I've started, nor does the trigger work at all. I'm also not sure what base spell to use, as I don't want to use Thunderclap, FanofKnives, or Warstomp because other skills use those as well. Right now I'm trying out Avatar.

JASS:
function VoodooCurseConditions takes nothing returns boolean
//Checks to see if the spell being cast is Voodoo Curse
    if GetSpellAbilityId() == 'VdCu' then
        return true
    endif
    return false
endfunction

function CurseConditions takes nothing returns boolean
//Checks to see if the candidates for curse are enemies
    return ( IsUnitAlly(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == false )
endfunction

function CurseActions takes nothing returns nothing
    local integer random = GetRandomInt(1,5)
    local integer i = 1
    if random == 1 then
//The Attack-Ally curse
    call IssueTargetOrder( GroupPickRandomUnit(GetLastCreatedGroup()), "attack", GroupPickRandomUnit(GetLastCreatedGroup()) )
    elseif random == 2 then
//The Move to Random spot curse.
    call IssuePointOrderLoc( GroupPickRandomUnit(GetLastCreatedGroup()), "move", OffsetLocation(GetUnitLoc(GetTriggerUnit()), GetRandomReal(900.00, 900.00), 0) )
    elseif random == 3 then
//Curse, curse . . .
    call CreateNUnitsAtLoc( 1,'e008', GetOwningPlayer(GetTriggerUnit()), GetUnitLoc(GroupPickRandomUnit(GetLastCreatedGroup())), 0.00 )
    call UnitApplyTimedLifeBJ( 2.00, 'BTLF', GetLastCreatedUnit() )
    call UnitAddAbilityBJ( 'Acrs', GetLastCreatedUnit() )
    call UnitAddAbilityBJ( 'Aloc', GetLastCreatedUnit() )
    call UnitAddAbilityBJ( 'Avul', GetLastCreatedUnit() )
    call IssueTargetOrder( GetLastCreatedUnit(), "curse", GroupPickRandomUnit(GetLastCreatedGroup()) )
    elseif random == 4 then
//Sleep curse
        call CreateNUnitsAtLoc( 1,'e008', GetOwningPlayer(GetTriggerUnit()), GetUnitLoc(GroupPickRandomUnit(GetLastCreatedGroup())), 0.00 )
    call UnitApplyTimedLifeBJ( 2.00, 'BTLF', GetLastCreatedUnit() )
    call UnitAddAbilityBJ( 'AUsl', GetLastCreatedUnit() )
    call UnitAddAbilityBJ( 'Aloc', GetLastCreatedUnit() )
    call UnitAddAbilityBJ( 'Avul', GetLastCreatedUnit() )
    call IssueTargetOrder( GetLastCreatedUnit(), "sleep", GroupPickRandomUnit(GetLastCreatedGroup()) )
    elseif random == 5 then
//Impale Curse
    call UnitApplyTimedLifeBJ( 2.00, 'BTLF', GetLastCreatedUnit() )
    call UnitAddAbilityBJ( 'AUim', GetLastCreatedUnit() )
    call UnitAddAbilityBJ( 'Aloc', GetLastCreatedUnit() )
    call UnitAddAbilityBJ( 'Avul', GetLastCreatedUnit() )
    call IssueTargetOrder( GetLastCreatedUnit(), "impale", GroupPickRandomUnit(GetLastCreatedGroup()) )
    endif
    set i = i + 1
    if i >= 7 then
//Here is where I'm not sure how to stop the Periodic Timer so the cursing stops.
    endif
endfunction

function callback takes nothing returns nothing
//Here the timer begins, picking every enemy unit in the area for the curse
call ForGroupBJ( GetUnitsInRangeOfLocMatching(650.00, GetUnitLoc(GetTriggerUnit()), Condition(function CurseConditions)), function CurseActions )
endfunction

function VoodooCurseActions takes nothing returns nothing
    local timer t = CreateTimer()
//Here, we call and destroy the timer
    call TimerStart(t,0.75,true,function callback)
    call DestroyTimer(t)
    set t = null
endfunction

//===========================================================================
function InitTrig_Voodoo_Curse takes nothing returns nothing
    set gg_trg_Voodoo_Curse = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Voodoo_Curse, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Voodoo_Curse, Condition( function VoodooCurseConditions ) )
    call TriggerAddAction( gg_trg_Voodoo_Curse, function VoodooCurseActions )
endfunction

I rarely use periodic timers, and I always have trouble with pick units in range. So I'm at quite a loss here. Any help is appreciated.
 
Level 14
Joined
Nov 23, 2008
Messages
187
Well, you need global (not local) counter. When timer action runs, just increase its value by 1 and check, if this value is greater than 7:

JASS:
function callback takes nothing returns nothing
  // call ForGroup(blabla)
  set udg_count = udg_count + 1
  if udg_count >= 7 then
    call DestroyTimer(GetExpiredTimer())
  endif
endfunction

But spell would be single applicable (not MUI). Use attaching systems like TT, ABC, XAT, and attach count value to timer.

And why are you destroying timer right after starting it? It looks abnormal.
 
Level 14
Joined
Nov 23, 2008
Messages
187
tt, abc are located at wc3camp, which is currently in down, so I can't do that.

Well, this simple system does almost the same thing:
JASS:
// Shadow Storage :)
library SS

globals
  private constant integer OFFSET = 0x100000
  private constant integer MAX_ID = 0x001FFF
  private integer array s
endglobals

private function H2I takes handle h returns integer
  return h
  return 0
endfunction

// function for attaching integer value to handle
function SetInt takes handle h, integer i returns nothing
  local integer x = H2I(h) - OFFSET
  if x < MAX_ID then
    set s[x] = i
  endif
endfunction

// function for getting attached value
function GetInt takes handle h returns integer
  local integer x = H2I(h) - OFFSET
  if x < MAX_ID then
    return s[x]
  endif
  return 0
endfunction

endlibrary
 
Level 13
Joined
Jul 26, 2008
Messages
1,009
If I can't make it MUI then there would be absolutely no point in implementing it into the map. I know this spell can be done MUI. No reason why it shouldn't be able to be done MUI. While JASS isn't the greatest of programming languages, itdoes allow a wide range of ability ideas.

Could someone who does know please respond?

And I will look into the timer being destroyed right after being created, see if that doesn't fix a few issues.

And why would I do udg_count = udg_count + 1 when I can just use a local variable integer?
 
Status
Not open for further replies.
Top