• 🏆 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!

[vJASS] Problems converting GUI to vJASS – What's the problem

Status
Not open for further replies.
Level 10
Joined
Mar 21, 2008
Messages
84
Hi, im moving GUI MUI to vJASS and this is my 2nd spell, some functions are complety different and im a little confused doing that spell, i need other eyes for see the problem of this trigger.

* Point of spell : The hero cast spell on spell point (base spell : silence) in 400y AoE then all enemies inside on it gets entangling roots.

Can't make it works...

JASS:
scope EternalGrasp initializer Init

//CONFIG
    globals
        private constant integer SPELL_ID = 'A004'
        private constant integer DUMMY_SPELL_ID = 'A005'
        private constant integer DUMMY_ID = 'h001'
        private boolexpr b
    endglobals
    
    private function Range takes integer level returns real
        return 400.
    endfunction
//=====================================================
    private function Targets takes unit target returns boolean
        return (GetWidgetLife(target) > 0.405) and (IsUnitType(target, UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(target, UNIT_TYPE_MECHANICAL) == false)
    endfunction
//=====================================================
    private function Pick takes nothing returns boolean
        return Targets(GetFilterUnit())
    endfunction
//=====================================================
    private function Conditions takes nothing returns boolean
            return GetSpellAbilityId() == SPELL_ID
    endfunction
//=====================================================
    private function Trig_EternalGrasp_Actions takes nothing returns nothing
        local unit caster = GetTriggerUnit()
        local location spellLoc = GetSpellTargetLoc()
        local real spellX = GetLocationX(spellLoc)
        local real spellY = GetLocationY(spellLoc)
        local group gg = CreateGroup()
        local unit f
        //Unidad
        set bj_lastCreatedUnit = CreateUnitAtLoc(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_ID, spellLoc, 0)
        //Grupo
        call GroupEnumUnitsInRange(gg, spellX, spellY, Range, b)
        loop
            set f = FirstOfGroup(gg)
            exitwhen (f == null)
            if IsUnitEnemy(f, GetOwningPlayer(caster)) then
                call IssueTargetOrder(bj_lastCreatedUnit, "entanglingroots", f)
            endif
        endloop
        //Remove Leaks
        call RemoveLocation(spellLoc)
        set caster = null
        set spellLoc = null
    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger EternalGraspTrg = CreateTrigger( )
        call TriggerRegisterAnyUnitEventBJ(EternalGraspTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition(EternalGraspTrg, Condition( function Conditions ) )
        call TriggerAddAction( EternalGraspTrg, function Trig_EternalGrasp_Actions )
        
        //Setting global
        set b = Condition(function Pick)
    endfunction
endscope


And for finish anyone can say to me if this trigger its well codded? (Thats my first spell , mythic Blink Strike. It works good)

JASS:
scope BlinkSlash initializer Init

//CONFIG
    globals
        private constant integer SPELL_ID = 'A001'
        private constant real DAMAGE_FORMULA = 50.
        private constant string DAMAGE_EFFECT = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
        private constant string CASTER_EFFECT = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"

    endglobals
    
//=====================================================
    private function Conditions takes nothing returns boolean
            return GetSpellAbilityId() == SPELL_ID
    endfunction
//=====================================================
    private function Trig_BlinkSlash_Actions takes nothing returns nothing
        local unit caster = GetTriggerUnit()
        local unit target = GetSpellTargetUnit()
        local location blinkLoc = GetSpellTargetLoc()
        local location casterLoc = GetUnitLoc(caster)
        local real DAMAGE =  (GetUnitLevel(caster) * 2) + DAMAGE_FORMULA
        call DestroyEffect(AddSpecialEffectLoc(CASTER_EFFECT, casterLoc))
        call SetUnitPositionLoc(caster, blinkLoc)
        call SetUnitAnimation(caster, "attack" )
        call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, target, "origin"))
        call UnitDamageTarget(caster, target, DAMAGE, true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL, null)
        //Remove Leaks
        call RemoveLocation(casterLoc)
        call RemoveLocation(blinkLoc)
        set blinkLoc = null
        set casterLoc = null
        set caster = null
        set target = null 
    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger BlinkSlashTrg = CreateTrigger( )
        call TriggerRegisterAnyUnitEventBJ(BlinkSlashTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition(BlinkSlashTrg, Condition( function Conditions ) )
        call TriggerAddAction( BlinkSlashTrg, function Trig_BlinkSlash_Actions )
    endfunction
endscope

Thanks :9 :goblin_yeah:
 
I haven't done JASS in a while, but try this.

JASS:
scope EternalGrasp initializer Init

    //CONFIG
    
    globals
        private constant integer SPELL_ID = 'A004'
        private constant integer DUMMY_SPELL_ID = 'A005'
        private constant integer DUMMY_ID = 'h001'
        private boolexpr b
    endglobals
    
    private function Range takes integer level returns real
        return 400.
    endfunction
    
    //=====================================================

    private function Targets takes unit target returns boolean
        return (GetWidgetLife(target) > 0.405) and (IsUnitType(target, UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(target, UNIT_TYPE_MECHANICAL) == false)
    endfunction

    private function Pick takes nothing returns boolean
        return Targets(GetFilterUnit())
    endfunction

    private function Actions takes nothing returns nothing
        local unit caster
        local real spellX
        local real spellY
        local group gg
        local unit f
        local player p
        
        if (GetSpellAbilityId() == SPELL_ID) then
            set caster = GetTriggerUnit()
            set spellX = GetSpellTargetX()
            set spellY = GetSpellTargetY()
            set gg     = CreateGroup()
            set p      = GetOwningPlayer(caster)
            
            set bj_lastCreatedUnit = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_ID, spellX, spellY, 0)

            call GroupEnumUnitsInRange(gg, spellX, spellY, Range, b)
            loop
                set f = FirstOfGroup(gg)
                exitwhen (f == null)
                if IsUnitEnemy(f, p) then
                    call IssueTargetOrder(bj_lastCreatedUnit, "entanglingroots", f)
                endif
            endloop
            
            //Remove Leaks
            call DestroyGroup(gg)
            
            set gg       = null
            set caster   = null
            set spellLoc = null
        endif
        
    endfunction
    
    //===========================================================================
    private function Init takes nothing returns nothing
        local trigger EternalGraspTrg = CreateTrigger( )
        call TriggerRegisterAnyUnitEventBJ(EternalGraspTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition(t, Condition(function Actions))
        
        //Setting global
        set b = Condition(function Pick)
    endfunction
endscope

If that doesn't work, are you sure the units meet all the conditions in the Targets function?
 
JASS:
scope EternalGrasp initializer Init

    //CONFIG
    
    globals
        private constant integer SPELL_ID = 'A004'
        private constant integer DUMMY_SPELL_ID = 'A005'
        private constant integer DUMMY_ID = 'h001'
    endglobals
    
    private function Range takes integer level returns real
        return 400.
    endfunction
    
    //=====================================================

    private function Targets takes unit target returns boolean
        return (GetWidgetLife(target) > 0.405) and (IsUnitType(target, UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(target, UNIT_TYPE_MECHANICAL) == false)
    endfunction

    private function Pick takes nothing returns boolean
        return Targets(GetFilterUnit())
    endfunction

    private function Actions takes nothing returns boolean
        local unit caster
        local real spellX
        local real spellY
        local group gg
        local unit f
        local player p
        
        if (GetSpellAbilityId() == SPELL_ID) then
            set caster = GetTriggerUnit()
            set spellX = GetSpellTargetX()
            set spellY = GetSpellTargetY()
            set gg     = CreateGroup()
            set p      = GetOwningPlayer(caster)
            
            set bj_lastCreatedUnit = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_ID, spellX, spellY, 0)

            call GroupEnumUnitsInRange(gg, spellX, spellY, Range, function Pick)
            loop
                set f = FirstOfGroup(gg)
                exitwhen (f == null)
                if IsUnitEnemy(f, p) then
                    call IssueTargetOrder(bj_lastCreatedUnit, "entanglingroots", f)
                endif
            endloop
            
            //Remove Leaks
            call DestroyGroup(gg)
            
            set gg       = null
            set caster   = null
        endif
        
        return false
    endfunction
    
    //===========================================================================
    private function Init takes nothing returns nothing
        local trigger EternalGraspTrg = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(EternalGraspTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition(EternalGraspTrg, Condition(function Actions))
    endfunction
endscope

EDIT: okay, it compiles.
 
Level 10
Joined
Mar 21, 2008
Messages
84
I can't find the problem, but I do know that function Pick isn't being called, therefore no units are being added to the group.

And without conditions on pick can work?

JASS:
call GroupEnumUnitsInRange(gg, spellX, spellY, Range, function Pick)

To

JASS:
call GroupEnumUnitsInRange(gg, spellX, spellY, Range, null)

EDIT: Writting null still dind't work.
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
Why this?
JASS:
local location spellLoc = GetSpellTargetLoc()
local real spellX = GetLocationX(spellLoc)
local real spellY = GetLocationY(spellLoc)

Must be:
JASS:
local real spellX = GetSpellTargetX()
local real spellY = GetSpellTargetY()

and in your problem, maybe the dummy unit doesn't have entangling roots ability, you must add it via triggers or object editor. I don't see any problem in the trigger, and also you can merge the condition in action merge them. Use global group not local group. It is like the spell from InstantJustice vJASS Tutorial so you must read it carefully xD. Keep Practicing!
 
Level 10
Joined
Mar 21, 2008
Messages
84
Why this?
JASS:
local location spellLoc = GetSpellTargetLoc()
local real spellX = GetLocationX(spellLoc)
local real spellY = GetLocationY(spellLoc)

Must be:
JASS:
local real spellX = GetSpellTargetX()
local real spellY = GetSpellTargetY()

and in your problem, maybe the dummy unit doesn't have entangling roots ability, you must add it via triggers or object editor. I don't see any problem in the trigger, and also you can merge the condition in action merge them. Use global group not local group. It is like the spell from InstantJustice vJASS Tutorial so you must read it carefully xD. Keep Practicing!


Yes, im reading a lot of manuals, and his manual open my eyes for start understand good vJASS.

Dummy have roots and still didn't work.
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
Can you attach the map?
And Also you didn't remove the picked units like this: call GroupRemoveUnit(gg,f)

EDIT:

How did you do this?: call GroupEnumUnitsInRange(gg, spellX, spellY, Range, b)
The function range needs an integer argument like a LVL must be like this:call GroupEnumUnitsInRange(gg, spellX, spellY, Range(MYLEVEL), b)
 
Level 10
Joined
Mar 21, 2008
Messages
84
Can you attach the map?
And Also you didn't remove the picked units like this: call GroupRemoveUnit(gg,f)

EDIT:

How did you do this?: call GroupEnumUnitsInRange(gg, spellX, spellY, Range, b)
The function range needs an integer argument like a LVL must be like this:call GroupEnumUnitsInRange(gg, spellX, spellY, Range(MYLEVEL), b)

This is the map with last corrections.

View attachment hive-fixed.w3x
 
Last edited:
Level 20
Joined
Aug 13, 2013
Messages
1,696
Sorry for waiting you too long because my current status is: "Busy in School :D"

Here is the magic map that you waiting for.
I attached it.
It is now fixed and your problem is now Solved

EDIT:

" Practice JASS makes your JASS perfect! :D "

EDIT2:

Changes Made:

- It is now creating the dummy in the loop so that the dummy will cast entangle ability once and it can't be disrupt by another picked unit.

- Removed the EnumUnit () in order line. EnumUnit is already a variable "f".

- The bj_lastCreatedUnit changed to local dummy.

- Nulled a local group and local unit f

Suggestions:

- Store the Player into a variable and used it in your created dummy.

- Don't Use this: (GetWidgetLife(target) > 0.405)
Must use this: GetUnitTypeId(target) != 0 and IsUnitType ( target, UNIT_TYPE_DEAD ) == false

- Make the local group to be global group like what you did in global boolexpr. CreateGroup () in Init.

- You can merge condition and action into one function ;).
 

Attachments

  • hive-fixed.w3x
    21.9 KB · Views: 38
Last edited:
Level 37
Joined
Mar 6, 2006
Messages
9,240
- Don't Use this: (GetWidgetLife(target) > 0.405)
Must use this: GetUnitTypeId(target) != 0 and IsUnitType ( target, UNIT_TYPE_DEAD ) == false

How does GroupEnumUnitsInRange pick units that have type id of 0?

Here are some fixes, like using only one dummy per cast. I edited the dummy a lot.

JASS:
scope EternalGrasp initializer Init

//CONFIG
    globals
        private constant integer SPELL_ID = 'A004'
        private constant integer DUMMY_SPELL_ID = 'A005'
        private constant integer DUMMY_ID = 'h001'
        private boolexpr b
        private group grp = CreateGroup()
    endglobals
    
    private function Range takes integer level returns real
        return level * 150.
    endfunction
//=====================================================
    private function Targets takes unit target returns boolean
        return not IsUnitType(target, UNIT_TYPE_DEAD) and (IsUnitType(target, UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(target, UNIT_TYPE_MECHANICAL) == false)
    endfunction
//=====================================================
    private function Pick takes nothing returns boolean
        return Targets(GetFilterUnit())
    endfunction
//=====================================================
    private function Conditions takes nothing returns boolean
            return GetSpellAbilityId() == SPELL_ID
    endfunction
//=====================================================
    private function Trig_EternalGrasp_Actions takes nothing returns nothing
        local unit caster = GetTriggerUnit()
        local real spellX = GetSpellTargetX()
        local real spellY = GetSpellTargetY()
        local integer level = GetUnitAbilityLevel(caster, SPELL_ID)
        local unit dummy
        local unit f
        
        //Grupo
        call GroupEnumUnitsInRange(grp, spellX, spellY, Range(level), function Pick)
        set f = FirstOfGroup(grp)
        if f != null then
            set dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_ID, spellX, spellY, 0)
            call UnitApplyTimedLife( dummy, 'BTLF', 1.00 )
            loop
                // Remove Unit
                if IsUnitEnemy(f, GetOwningPlayer(caster)) then
                    call IssueTargetOrder(dummy, "entanglingroots", f)
                endif
                call GroupRemoveUnit(grp,f)
                set f = FirstOfGroup(grp)
                exitwhen (f == null)
            endloop
            set dummy = null
        endif
        //Remove Leaks
        set caster = null
    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger EternalGraspTrg = CreateTrigger( )
        call TriggerRegisterAnyUnitEventBJ(EternalGraspTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition(EternalGraspTrg, Condition( function Conditions ) )
        call TriggerAddAction( EternalGraspTrg, function Trig_EternalGrasp_Actions )
    endfunction
endscope
This could still be improved.
 

Attachments

  • hive-fixed.w3x
    21.8 KB · Views: 50
Level 20
Joined
Aug 13, 2013
Messages
1,696
^ but it is not equal to true !=. It works properly:
JASS:
return GetUnitTypeId(target) != 0 and not IsUnitType ( target, UNIT_TYPE_DEAD ) and (IsUnitType(target, UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(target, UNIT_TYPE_MECHANICAL) == false)
and I tested it :(.
 
Level 10
Joined
Mar 21, 2008
Messages
84
Thanks to all to help me on the trigger, i recently started coding in vJASS.

So, the problem of this trigger was the dummy or the local var dummy refering to the dummy?

Whats the diference of

JASS:
local location spellLoc = GetSpellTargetLoc()
local real spellX = GetLocationX(spellLoc)
local real spellY = GetLocationY(spellLoc)

AND

JASS:
local real spellX = GetSpellTargetX()
local real spellY = GetSpellTargetY()

Its more faster and use less locals?

**********

EDIT: Didn't see last comments of Maker and jake hehe, resolved some doubts.

Thanks for help me in doubts.
 
Status
Not open for further replies.
Top