• 🏆 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] JASS More Precise Timer

Status
Not open for further replies.
Level 5
Joined
Jul 18, 2007
Messages
110
Well I have a spell like:
  • Enhancemenf GUI
    • Events
      • Unit - A unit enters Enhancement <gen>
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to (==) |cffffcc00Slave
      • ((Owner of (Triggering unit)) Current gold) Greater than or equal to (>=) 6000
    • Actions
      • Player - Set (Owner of (Triggering unit)) Current gold to (((Owner of (Triggering unit)) Current gold) - 6000)
      • Game - Display to (Owner of (Triggering unit)), at offset (0.00, 0.00) the text: |c00d9d9ffYou cast ...
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Triggering unit) is owned by Player 1 (Red)) Equal to (==) True
          • Then - Actions
            • Set temp_group = (Units in (Playable map area) matching (((Matching unit) is owned by Player 1 (Red)) Equal to (==) True))
            • Unit Group - Pick every unit in temp_group and do (Actions)
              • Loop - Actions
                • Special Effect - Create a special effect attached to the overhead of (Picked unit) using Abilities\Spells\Human\Resurrect\ResurrectCaster.mdl
                • Unit - Add Enchantment (Damage) to (Picked unit)
                • Unit - Add Enchantment (Armor) to (Picked unit)
            • Wait 3.00 seconds
            • Unit Group - Pick every unit in temp_group and do (Actions)
              • Loop - Actions
                • Unit - Remove Enchantment (Damage) from (Picked unit)
                • Unit - Remove Enchantment (Armor) from (Picked unit)
                • Special Effect - Destroy (Last created special effect)
            • Custom script: call DestroyGroup (udg_temp_group)
          • Else - Actions
            • Do nothing
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Triggering unit) is owned by Player 4 (Purple)) Equal to (==) True
          • Then - Actions
            • Set temp_group = (Units in (Playable map area) matching (((Picked unit) is owned by Player 4 (Purple)) Equal to (==) True))
            • Special Effect - Create a special effect at (Position of (Picked unit)) using Abilities\Spells\Human\DivineShield\DivineShieldTarget.mdl
            • Unit Group - Pick every unit in temp_group and do (Actions)
              • Loop - Actions
                • Special Effect - Create a special effect attached to the overhead of (Picked unit) using Abilities\Spells\Human\Resurrect\ResurrectCaster.mdl
                • Unit - Add Enchantment (Damage) to (Picked unit)
                • Unit - Add Enchantment (Armor) to (Picked unit)
                • Wait 15.00 seconds
                • Unit - Remove Enchantment (Damage) from (Picked unit)
                • Unit - Remove Enchantment (Armor) from (Picked unit)
                • Special Effect - Destroy (Last created special effect)
            • Custom script: call DestroyGroup (udg_temp_group)
          • Else - Actions
            • Do nothing
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Triggering unit) is owned by Player 12 (Brown)) Equal to (==) True
          • Then - Actions
            • Set temp_group = (Units in (Playable map area) matching (((Picked unit) is owned by Player 12 (Brown)) Equal to (==) True))
            • Unit Group - Pick every unit in temp_group and do (Actions)
              • Loop - Actions
                • Special Effect - Create a special effect attached to the overhead of (Picked unit) using Abilities\Spells\Human\Resurrect\ResurrectCaster.mdl
                • Unit - Add Enchantment (Damage) to (Picked unit)
                • Unit - Add Enchantment (Armor) to (Picked unit)
                • Wait 15.00 seconds
                • Unit - Remove Enchantment (Damage) from (Picked unit)
                • Unit - Remove Enchantment (Armor) from (Picked unit)
                • Special Effect - Destroy (Last created special effect)
            • Custom script: call DestroyGroup (udg_temp_group)
          • Else - Actions
            • Do nothing
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Triggering unit) is owned by Player 2 (Blue)) Equal to (==) True
          • Then - Actions
            • Set temp_group = (Units in (Playable map area) matching (((Picked unit) is owned by Player 2 (Blue)) Equal to (==) True))
            • Unit Group - Pick every unit in temp_group and do (Actions)
              • Loop - Actions
                • Special Effect - Create a special effect attached to the overhead of (Picked unit) using Abilities\Spells\Human\Resurrect\ResurrectCaster.mdl
                • Unit - Add Enchantment (Damage) to (Picked unit)
                • Unit - Add Enchantment (Armor) to (Picked unit)
                • Wait 15.00 seconds
                • Unit - Remove Enchantment (Damage) from (Picked unit)
                • Unit - Remove Enchantment (Armor) from (Picked unit)
                • Special Effect - Destroy (Last created special effect)
            • Custom script: call DestroyGroup (udg_temp_group)
          • Else - Actions
            • Do nothing
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Triggering unit) is owned by Player 9 (Gray)) Equal to (==) True
          • Then - Actions
            • Set temp_group = (Units in (Playable map area) matching (((Picked unit) is owned by Player 9 (Gray)) Equal to (==) True))
            • Unit Group - Pick every unit in temp_group and do (Actions)
              • Loop - Actions
                • Special Effect - Create a special effect attached to the overhead of (Picked unit) using Abilities\Spells\Human\Resurrect\ResurrectCaster.mdl
                • Unit - Add Enchantment (Damage) to (Picked unit)
                • Unit - Add Enchantment (Armor) to (Picked unit)
                • Wait 15.00 seconds
                • Unit - Remove Enchantment (Damage) from (Picked unit)
                • Unit - Remove Enchantment (Armor) from (Picked unit)
                • Special Effect - Destroy (Last created special effect)
            • Custom script: call DestroyGroup (udg_temp_group)
          • Else - Actions
            • Do nothing
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Triggering unit) is owned by Player 7 (Green)) Equal to (==) True
          • Then - Actions
            • Set temp_group = (Units in (Playable map area) matching (((Picked unit) is owned by Player 7 (Green)) Equal to (==) True))
            • Unit Group - Pick every unit in temp_group and do (Actions)
              • Loop - Actions
                • Special Effect - Create a special effect attached to the overhead of (Picked unit) using Abilities\Spells\Human\Resurrect\ResurrectCaster.mdl
                • Unit - Add Enchantment (Damage) to (Picked unit)
                • Unit - Add Enchantment (Armor) to (Picked unit)
                • Wait 15.00 seconds
                • Unit - Remove Enchantment (Damage) from (Picked unit)
                • Unit - Remove Enchantment (Armor) from (Picked unit)
                • Special Effect - Destroy (Last created special effect)
            • Custom script: call DestroyGroup (udg_temp_group)
          • Else - Actions
            • Do nothing
      • Set temp_point = (Center of Enhancement Finish <gen>)
      • Unit - Move (Triggering unit) instantly to temp_point
      • Custom script: call RemoveLocation (udg_temp_point)
And I need a JASS timer for it I think to work, since it doesn't remove the abilities. So was wondering how/what would I implement..? My friend helped me with the code in JASS as well, so I have that in case I can't just throw it in the raw script. The JASS code is:
JASS:
function EnhancementC takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit())=='u005' and GetPlayerState(GetOwningPlayer(GetTriggerUnit()),PLAYER_STATE_RESOURCE_GOLD)>=6000
endfunction

function EnhancementA takes nothing returns nothing
    local unit triggerU = GetTriggerUnit()
    local group inRect=CreateGroup()
    local integer currentGold=GetPlayerState(GetOwningPlayer(GetTriggerUnit()),PLAYER_STATE_RESOURCE_GOLD)
    local unit firstUnit
    set udg_temp_point=Location(GetRectCenterX(gg_rct_Enhancement_Finish),GetRectCenterY(gg_rct_Enhancement_Finish))
    call SetUnitPosition(GetTriggerUnit(),GetRectCenterX(gg_rct_Enhancement_Finish),GetRectCenterY(gg_rct_Enhancement_Finish))
    call SetPlayerState(GetOwningPlayer(GetTriggerUnit()),PLAYER_STATE_RESOURCE_GOLD,currentGold-6000)
    call DisplayTextToPlayer(GetOwningPlayer(GetTriggerUnit()),0,0,"|cffd9d9ffYou cast Enhancement...|r")
    call GroupEnumUnitsInRect(inRect,bj_mapInitialPlayableArea,null)
    set udg_temp_group=inRect
    loop
        exitwhen FirstOfGroup(udg_temp_group)==null
        set firstUnit=FirstOfGroup(udg_temp_group)
        if GetOwningPlayer(firstUnit)==GetOwningPlayer(GetTriggerUnit()) then
            set bj_lastCreatedEffect=AddSpecialEffectTarget("Abilities\\Spells\\Human\\Resurrect\\ResurrectCaster.mdl",firstUnit,"overhead")
            call UnitAddAbility(firstUnit,'A06S')
            call UnitAddAbility(firstUnit,'A06T')
        endif
        call GroupRemoveUnit(udg_temp_group,firstUnit)
    endloop
    call TriggerSleepAction(15)
    set udg_temp_group=inRect
    loop
        exitwhen FirstOfGroup(udg_temp_group)==null
        set firstUnit=FirstOfGroup(udg_temp_group)
        if GetOwningPlayer(firstUnit)==GetOwningPlayer(GetTriggerUnit()) then
            call DestroyEffect(bj_lastCreatedEffect)
            call UnitRemoveAbility(firstUnit,'A06S')
            call UnitRemoveAbility(firstUnit,'A06T')
        endif
        call GroupRemoveUnit(udg_temp_group,firstUnit)
    endloop
    call DestroyGroup(inRect)
    call DestroyGroup(udg_temp_group)
endfunction

function InitTrig_Enhancement takes nothing returns nothing
    set gg_trg_Enhancement=CreateTrigger()
    call TriggerRegisterEnterRectSimple(gg_trg_Enhancement,gg_rct_Enhancement)
    call TriggerAddCondition(gg_trg_Enhancement,Condition(function EnhancementC))
    call TriggerAddAction(gg_trg_Enhancement,function EnhancementA)
endfunction
 
Level 5
Joined
Jul 18, 2007
Messages
110
Your problem in this case is that you dump the contents of the group. You need to backup the group as you remove all the units from it the first time you loop.
I do back them up, don't I? The initial temp group goes into inRect, which is again transferred over after udg_temp_group is removed.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
I do back them up, don't I? The initial temp group goes into inRect, which is again transferred over after udg_temp_group is removed.
That is just handing over the reference, not a new copy. It's just like if you do

JASS:
local unit u = GetTriggerUnit()
local unit d = u

A new unit does not spontaneously appear.

Anyhow, use ForGroup() as hvo-busterkomo suggested. I assumed you were passing locals somewhere, but since you aren't there's no reason not to.
 

Cokemonkey11

Spell Reviewer
Level 29
Joined
May 9, 2006
Messages
3,534
I'm the one that helped him with the jass, and the trigger works. The problem here is that he cannot remove the effects placed on the units without knowing the effect id's. There are many ways he could do this:

:save a local integer and an effect array referring to the number of units and loop through like:

1 to integer, remove effect[integer]

:Use hidden abilities which give the effect, and then remove them in the second loop

:Convert to a struct stack with a timer to get exactly 15 seconds (in this case that doesn't matter though)

The reason temp group is saved as inRect is because the FirstOfGroup loop is using temp group, but you need the original units again (look at the 2 loop sections and you'll understand)
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
The reason temp group is saved as inRect is because the FirstOfGroup loop is using temp group, but you need the original units again (look at the 2 loop sections and you'll understand)
...

People really need to understand what pointers are. I'd think it would be obvious after handling unit variables.

Read my above posts.
 

Cokemonkey11

Spell Reviewer
Level 29
Joined
May 9, 2006
Messages
3,534
I know what pointers are; I learned CPP before I learned jass, I've got a pretty good understanding of them.

I think you need to reread the code he posted and understand the problem.

Edit: here is a new code, I hope this fixes the problem.

JASS:
function EnhancementC takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit())=='u005' and GetPlayerState(GetOwningPlayer(GetTriggerUnit()),PLAYER_STATE_RESOURCE_GOLD)>=6000
endfunction

function EnhancementA takes nothing returns nothing
    local unit triggerU = GetTriggerUnit()
    local group inRect=CreateGroup()
    local integer currentGold=GetPlayerState(GetOwningPlayer(GetTriggerUnit()),PLAYER_STATE_RESOURCE_GOLD)
    local unit firstUnit
    local integer counter=0
    local integer counterTemp=0
    local effect array fxArr
    set udg_temp_point=Location(GetRectCenterX(gg_rct_Enhancement_Finish),GetRectCenterY(gg_rct_Enhancement_Finish))
    call SetUnitPosition(GetTriggerUnit(),GetRectCenterX(gg_rct_Enhancement_Finish),GetRectCenterY(gg_rct_Enhancement_Finish))
    call SetPlayerState(GetOwningPlayer(GetTriggerUnit()),PLAYER_STATE_RESOURCE_GOLD,currentGold-6000)
    call DisplayTextToPlayer(GetOwningPlayer(GetTriggerUnit()),0,0,"|cffd9d9ffYou cast Enhancement...|r")
    call GroupEnumUnitsInRect(inRect,bj_mapInitialPlayableArea,null)
    set udg_temp_group=inRect
    loop
        exitwhen FirstOfGroup(udg_temp_group)==null
        set firstUnit=FirstOfGroup(udg_temp_group)
        if GetOwningPlayer(firstUnit)==GetOwningPlayer(GetTriggerUnit()) then
            set fxArr[counter]=AddSpecialEffectTarget("Abilities\\Spells\\Human\\Resurrect\\ResurrectCaster.mdl",firstUnit,"overhead")
            call UnitAddAbility(firstUnit,'A06S')
            call UnitAddAbility(firstUnit,'A06T')
            set counter=counter+1
        endif
        call GroupRemoveUnit(udg_temp_group,firstUnit)
    endloop
    call TriggerSleepAction(15)
    set udg_temp_group=inRect
    loop
        exitwhen FirstOfGroup(udg_temp_group)==null
        set firstUnit=FirstOfGroup(udg_temp_group)
        if GetOwningPlayer(firstUnit)==GetOwningPlayer(GetTriggerUnit()) then
            call DestroyEffect(bj_lastCreatedEffect)
            call UnitRemoveAbility(firstUnit,'A06S')
            call UnitRemoveAbility(firstUnit,'A06T')
        endif
        call GroupRemoveUnit(udg_temp_group,firstUnit)
    endloop
    loop
        exitwhen counterTemp>counter
        call DestroyEffect(fxArr[counterTemp])
        set counterTemp=counterTemp+1
    endloop
    call DestroyGroup(inRect)
    call DestroyGroup(udg_temp_group)
endfunction

function InitTrig_Enhancement takes nothing returns nothing
    set gg_trg_Enhancement=CreateTrigger()
    call TriggerRegisterEnterRectSimple(gg_trg_Enhancement,gg_rct_Enhancement)
    call TriggerAddCondition(gg_trg_Enhancement,Condition(function EnhancementC))
    call TriggerAddAction(gg_trg_Enhancement,function EnhancementA)
endfunction
 
Last edited:
Level 13
Joined
Mar 16, 2008
Messages
941
...

People really need to understand what pointers are. I'd think it would be obvious after handling unit variables.

Read my above posts.

#
There is still only a single group...
This loop doesn't use the units from the "global group", but the ones from inRect. Both pointers point at the SAME group, and when you remove units from udg_temp_group, you're removing them from inRect aswell because they are the SAME.

EDIT: I misread the post above.
Either you copy the group with "GroupAddGroup", or you loop throug the same again with "ForGroup" what is much faster
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
You are assigning many things you are not even using, what's the point?

I wrote this in Notepad so there [are] might be syntax errors.

JASS:
function EnhancementC takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit())=='u005' and GetPlayerState(GetOwningPlayer(GetTriggerUnit()),PLAYER_STATE_RESOURCE_GOLD)>=6000
endfunction

function EnhancementAdd takes nothing returns nothing
    local unit u = GetEnumUnit()
    call UnitAddAbility(u,'A06S')
    call UnitAddAbility(u,'A06T')
    set u = null
endfunction

function EnhancementRemove takes nothing returns nothing
    local unit u = GetEnumUnit()
    call UnitRemoveAbility(u,'A06S')
    call UnitRemoveAbility(u,'A06T')
    set u = null
endfunction

function EnhancementA takes nothing returns nothing

    local unit u = GetTriggerUnit()
    local group g = CreateGroup()
    local player p = GetOwningPlayer(u)
    local real x = GetRectCenterX(gg_rct_Enhancement_Finish)
    local real y = GetRectCenterY(gg_rct_Enhancement_Finish)
    local integer currentGold = GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)

    call SetUnitPosition(u,x,y)
    call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,currentGold-6000)
    call DisplayTextToPlayer(p,0,0,"|cffd9d9ffYou cast Enhancement...|r")
    
    call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,null)
    
    call ForGroupBJ(g,function EnhancementAdd)
    call TriggerSleepAction(15)
    call ForGroupBJ(g,function EnhancementRemove)
    
    call DestroyGroup(g)
    set g = null
    set u = null
    
endfunction

function InitTrig_Enhancement takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterEnterRectSimple(t,gg_rct_Enhancement)
    call TriggerAddCondition(t,Condition(function EnhancementC))
    call TriggerAddAction(t,function EnhancementA)
endfunction
 
Level 5
Joined
Jul 18, 2007
Messages
110
Wow, you're amazing. It removed both abilities and worked fine! AND no syntax errors on notepad, lol. Thanks a lot dude you're awesome. Thanks to all as well for the help.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Or explained even simpler:
set udg_temp_group=inRect

Does not copy the group. It just makes udg_temp_group point the same group(handle, object) as inRect.
 
Level 29
Joined
Jul 29, 2007
Messages
5,174

Null filters leak. They are fine in events, though.

And why's that?

TSA's have so many problems...

Just use a timer instead.

since when is ForGorup() slower??

It's slower in checking bigger groups of about 8 or more units.

Using the FirstOfGroup method would then be faster.
 
Status
Not open for further replies.
Top