• 🏆 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] Starfall

Status
Not open for further replies.
Level 6
Joined
Apr 16, 2011
Messages
158
[Resolved] Starfall

What I'm trying to do is create the magic starfall customizable.
I am having the following problems:
- there is no damage(the magic does not reach the filter)
- effect in "caster" is in the wrong place.
I no have much knowledge in "vjass" ,so can be a error beast

*i am editing the magic "epicenter" by Mag(s2 you)

JASS:
library Starfall initializer onInit requires Tt, SpellEffectEvent
    
    globals
    private constant integer    ABIL_CODE         = 'A003'
    private constant real       RADIUS            = 3000.
    private constant string     EFFECT_PATH       = "Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl"
    private constant string     EFFECT_CAST       = "Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl"
    private constant attacktype ATTACK_TYPE       = ATTACK_TYPE_NORMAL
    private constant damagetype DAMAGE_TYPE       = DAMAGE_TYPE_NORMAL
    private constant boolean    PRELOAD_EFFECT = true
    endglobals

    private function GetTimeout takes integer level returns real
        return 1.
    endfunction

    private function GetDamage takes integer heroInt returns real
        return 100. + heroInt
    endfunction
    
    private function TargetFilter takes unit caster, player owner, unit target returns boolean
        return not IsUnitType(target, UNIT_TYPE_STRUCTURE) and not IsUnitType(target, UNIT_TYPE_DEAD) and IsUnitEnemy(target, owner)
    endfunction
    
    private struct Spell extends array
        
        private static unit array    caster
        private static player array  owner
        private static integer array waves
        private static real array    radius
        private static real array    damage
        private static effect array  effectCaster
        
        implement CTM
            local real x
            local real y
            local unit u
        implement CTMExpire
            set x = GetUnitX(u)
            set y = GetUnitY(u)
            set bj_lastCreatedGroup = CreateGroup()
            call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, RADIUS, null)
            loop
                set u = FirstOfGroup(bj_lastCreatedGroup)
                exitwhen null == u
                call GroupRemoveUnit(bj_lastCreatedGroup, u)
                if TargetFilter(caster[this], owner[this], u) then
                    call DestroyEffect(AddSpecialEffectTarget(EFFECT_PATH,u,"origin"))
                    call UnitDamageTarget(caster[this], u, damage[this], false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
                endif
            endloop
            call DestroyGroup(bj_lastCreatedGroup)
            set waves[this] = waves[this] - 1
            if waves[this] == 0 then
                call DestroyEffect(effectCaster[this])
                call this.destroy()
                set caster[this] = null
                set owner[this] = null
            endif
        implement CTMEnd
        
        private static method run takes nothing returns nothing
         local integer  level   = GetUnitAbilityLevel(GetTriggerUnit(), ABIL_CODE)
         local thistype this    = create(GetTimeout(level))
         local integer  heroInt
         local real     x      
         local real     y
         
         set caster[this]       = GetTriggerUnit()
         set x                  = GetUnitX(caster[this])
         set y                  = GetUnitY(caster[this])
         set heroInt            = GetHeroInt(caster[this], true)
         set effectCaster[this] = AddSpecialEffect(EFFECT_CAST, x, y)
         set owner[this]        = GetTriggerPlayer()
         set damage[this]       = GetDamage(heroInt)
         set waves[this]        = level
        endmethod
        
        private static method onInit takes nothing returns nothing
            call RegisterSpellEffectEvent(ABIL_CODE, function thistype.run)
            static if PRELOAD_EFFECT then
                call Preload(EFFECT_PATH)
                call Preload(EFFECT_CAST)
            endif
        endmethod
    endstruct
    //Family Magtheridon96 ? PROBLEM ?
endlibrary
 
Last edited:
Level 5
Joined
Jun 16, 2004
Messages
108
Might need to initialize your group variable to a group beforehand, like so:
JASS:
set bj_lastCreatedGroup = CreateGroup()
call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, RADIUS, null)
loop
	set u = FirstOfGroup(bj_lastCreatedGroup)
	exitwhen null == u
	call GroupRemoveUnit(bj_lastCreatedGroup, u)
	if TargetFilter(caster[this], owner[this], u) then
		call DestroyEffect(AddSpecialEffectTarget(EFFECT_PATH,u,"origin"))
		call UnitDamageTarget(caster[this], u, damage[this], false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
	endif
endloop
call DestroyGroup(bj_lastCreatedGroup)

Looks like this might be an error:
JASS:
local integer  heroInt = GetHeroInt(caster[this], true)
Since you do it before setting the caster to the triggering unit.

As for the effect being in the wrong place, you mean this call?
JASS:
set effectCaster[this] = AddSpecialEffect(EFFECT_CAST, x, y)
If so, how exactly is it in the wrong place?

Also, I am not very familiar with vJASS's struct array syntax and usage, but are you supposed to use .create and .destroy on structs that extend array? Seems like your trigger goes against what I read in the vJASS manual, anyway. It does not really seem like you need this struct to extend array, why is it that you do so?
 
Level 6
Joined
Apr 16, 2011
Messages
158
1)I think it is unlikely,already wore as well and had never had problems.
2)You are right :) ty
3)Yes,The other effect no works.

204923-albums5155-picture59043.jpg

This effect should appear in the character that launched the magic.
ty for help bro
 
Level 5
Joined
Jun 16, 2004
Messages
108
set x = GetUnitX(caster[this])
set y = GetUnitX(caster[this])

You are using GetUnitX twice.

I still recommend against using bj_lastCreatedGroup, unless you specifically design your map around using it and you initialize it at the start of the map, and only use it as a quick temporary group for enumerations.
 
Level 5
Joined
Jun 16, 2004
Messages
108
The damage effect appears on enemy units, but the damage itself is not being applied? Is that what is happening?

Not sure what would be the cause of that in your code ... perhaps try changing around the UnitDamageCall to use a constant amount, like 100., just to see if perhaps the "this" variable is not set properly (the default value for a real is 0. I believe).

JASS:
all UnitDamageTarget(u, u, 100000., false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null)
If a call like this works then maybe the "this" value is wrong, or you should double check your damage/attack types.

If the damage effect is not displaying either, then maybe this is the cause:
JASS:
set owner[this]        = GetTriggerPlayer()

Try this instead:
JASS:
set owner[this]        = GetOwningPlayer(caster[this])
 
Level 6
Joined
Apr 16, 2011
Messages
158
I divided my code to see where they stopping this
He does not leave the second marking
JASS:
library Starfall initializer onInit requires Tt, SpellEffectEvent
    
    globals
    private constant integer    ABIL_CODE         = 'A003'
    private constant real       RADIUS            = 3000.
    private constant string     EFFECT_PATH       = "Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl"
    private constant string     EFFECT_CAST       = "Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl"
    private constant attacktype ATTACK_TYPE       = ATTACK_TYPE_NORMAL
    private constant damagetype DAMAGE_TYPE       = DAMAGE_TYPE_NORMAL
    private constant boolean    PRELOAD_EFFECT = true
    endglobals

    private function GetTimeout takes integer level returns real
        return 1.
    endfunction

    private function GetDamage takes integer heroInt returns real
        return 100. + heroInt
    endfunction
    
    private function TargetFilter takes unit caster, player owner, unit target returns boolean
        return not IsUnitType(target, UNIT_TYPE_STRUCTURE) and not IsUnitType(target, UNIT_TYPE_DEAD) and IsUnitEnemy(target, owner)
    endfunction
    
    private struct Spell extends array
        
        private static unit array    caster
        private static player array  owner
        private static integer array waves
        private static real array    radius
        private static real array    damage
        private static effect array  effectCaster
        
        implement CTM
            local real x
            local real y
            local unit u
        implement CTMExpire
            call BJDebugMsg("2")
            set x = GetUnitX(u)
            set y = GetUnitY(u)
            call BJDebugMsg("2.1")
            set bj_lastCreatedGroup = CreateGroup()
            call BJDebugMsg("2.2")
            call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, RADIUS, null)
            loop
                call BJDebugMsg("LOOP")
                set u = FirstOfGroup(bj_lastCreatedGroup)
                exitwhen null == u
                call GroupRemoveUnit(bj_lastCreatedGroup, u)
                if TargetFilter(caster[this], owner[this], u) then
                    call BJDebugMsg("3")
                    call DestroyEffect(AddSpecialEffectTarget(EFFECT_PATH,u,"origin"))
                    call UnitDamageTarget(caster[this], u, damage[this], false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
                endif
            endloop
            call DestroyGroup(bj_lastCreatedGroup)
            set waves[this] = waves[this] - 1
            if waves[this] == 0 then
                call BJDebugMsg("4")
                call DestroyEffect(effectCaster[this])
                call this.destroy()
                set caster[this] = null
                set owner[this] = null
            endif
            call BJDebugMsg("5")
        implement CTMEnd
        
        private static method run takes nothing returns nothing
         local integer  level   = GetUnitAbilityLevel(GetTriggerUnit(), ABIL_CODE)
         local thistype this    = create(GetTimeout(level))
         local integer  heroInt
         local real     x      
         local real     y
         
         set caster[this]       = GetTriggerUnit()
         set x                  = GetUnitX(caster[this])
         set y                  = GetUnitY(caster[this])
         set heroInt            = GetHeroInt(caster[this], true)
         set effectCaster[this] = AddSpecialEffect(EFFECT_CAST, x, y)
         set owner[this]        = GetOwningPlayer(caster[this])
         set damage[this]       = GetDamage(heroInt)
         set waves[this]        = level
         call BJDebugMsg("1")
        endmethod
        
        private static method onInit takes nothing returns nothing
            call RegisterSpellEffectEvent(ABIL_CODE, function thistype.run)
            static if PRELOAD_EFFECT then
                call Preload(EFFECT_PATH)
                call Preload(EFFECT_CAST)
            endif
        endmethod
    endstruct
    //Family Magtheridon96 ? PROBLEM ?
endlibrary
 
Level 5
Joined
Jun 16, 2004
Messages
108
JASS:
set x = GetUnitX(u)
set y = GetUnitY(u)
I did not notice these lines before. What are they supposed to be getting the x/y values from? It looks like the u variable is not set to any unit yet when you call these.

Maybe you need to store the x/y in the struct itself like this:
JASS:
private static real array x
private static real array y
And set them to the caster's position in the "run" function, then use them instead in your timer function.
 
Level 6
Joined
Apr 16, 2011
Messages
158
you say so?
JASS:
library Starfall initializer onInit requires Tt, SpellEffectEvent
    
    globals
    private constant integer    ABIL_CODE         = 'A003'
    private constant real       RADIUS            = 3000.
    private constant string     EFFECT_PATH       = "Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl"
    private constant string     EFFECT_CAST       = "Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl"
    private constant attacktype ATTACK_TYPE       = ATTACK_TYPE_NORMAL
    private constant damagetype DAMAGE_TYPE       = DAMAGE_TYPE_NORMAL
    private constant boolean    PRELOAD_EFFECT = true
    endglobals

    private function GetTimeout takes integer level returns real
        return 1.
    endfunction

    private function GetDamage takes integer heroInt returns real
        return 100. + heroInt
    endfunction
    
    private function TargetFilter takes unit caster, player owner, unit target returns boolean
        return not IsUnitType(target, UNIT_TYPE_STRUCTURE) and not IsUnitType(target, UNIT_TYPE_DEAD) and IsUnitEnemy(target, owner)
    endfunction
    
    private struct Spell extends array
        
        private static unit array    caster
        private static player array  owner
        private static integer array waves
        private static real array    radius
        private static real array    damage
        private static real array    x
        private static real array    y
        private static effect array  effectCaster
        
        implement CTM

            local unit u
        implement CTMExpire
            call BJDebugMsg("2")
            set x[this] = GetUnitX(u)
            set y[this] = GetUnitY(u)
            set bj_lastCreatedGroup = CreateGroup()
            call GroupEnumUnitsInRange(bj_lastCreatedGroup, x[this], y[this], RADIUS, null)
            loop
                call BJDebugMsg("LOOP")
                set u = FirstOfGroup(bj_lastCreatedGroup)
                exitwhen null == u
                call GroupRemoveUnit(bj_lastCreatedGroup, u)
                if TargetFilter(caster[this], owner[this], u) then
                    call BJDebugMsg("3")
                    call DestroyEffect(AddSpecialEffectTarget(EFFECT_PATH,u,"origin"))
                    call UnitDamageTarget(caster[this], u, damage[this], false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
                endif
            endloop
            call DestroyGroup(bj_lastCreatedGroup)
            set waves[this] = waves[this] - 1
            if waves[this] == 0 then
                call BJDebugMsg("4")
                call DestroyEffect(effectCaster[this])
                call this.destroy()
                set caster[this] = null
                set owner[this] = null
            endif
            call BJDebugMsg("5")
        implement CTMEnd
        
        private static method run takes nothing returns nothing
         local integer  level   = GetUnitAbilityLevel(GetTriggerUnit(), ABIL_CODE)
         local thistype this    = create(GetTimeout(level))
         local integer  heroInt

         set caster[this]       = GetTriggerUnit()
         set x[this]            = GetUnitX(caster[this])
         set y[this]            = GetUnitY(caster[this])
         set heroInt            = GetHeroInt(caster[this], true)
         set effectCaster[this] = AddSpecialEffect(EFFECT_CAST, x[this], y[this])
         set owner[this]        = GetOwningPlayer(caster[this])
         set damage[this]       = GetDamage(heroInt)
         set waves[this]        = level
         call BJDebugMsg("1")
        endmethod
        
        private static method onInit takes nothing returns nothing
            call RegisterSpellEffectEvent(ABIL_CODE, function thistype.run)
            static if PRELOAD_EFFECT then
                call Preload(EFFECT_PATH)
                call Preload(EFFECT_CAST)
            endif
        endmethod
    endstruct
    //Family Magtheridon96 ? PROBLEM ?
endlibrary
 
Level 5
Joined
Jun 16, 2004
Messages
108
The point was to avoid having these two lines:
JASS:
set x[this] = GetUnitX(u)
set y[this] = GetUnitY(u)

JASS:
library Starfall initializer onInit requires Tt, SpellEffectEvent
    
    globals
    private constant integer    ABIL_CODE         = 'A003'
    private constant real       RADIUS            = 3000.
    private constant string     EFFECT_PATH       = "Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl"
    private constant string     EFFECT_CAST       = "Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl"
    private constant attacktype ATTACK_TYPE       = ATTACK_TYPE_NORMAL
    private constant damagetype DAMAGE_TYPE       = DAMAGE_TYPE_NORMAL
    private constant boolean    PRELOAD_EFFECT = true
    endglobals

    private function GetTimeout takes integer level returns real
        return 1.
    endfunction

    private function GetDamage takes integer heroInt returns real
        return 100. + heroInt
    endfunction
    
    private function TargetFilter takes unit caster, player owner, unit target returns boolean
        return not IsUnitType(target, UNIT_TYPE_STRUCTURE) and not IsUnitType(target, UNIT_TYPE_DEAD) and IsUnitEnemy(target, owner)
    endfunction
    
    private struct Spell extends array
        
        private static unit array    caster
        private static player array  owner
        private static integer array waves
        private static real array    radius
        private static real array    damage
        private static real array    x
        private static real array    y
        private static effect array  effectCaster
        
        implement CTM

            local unit u
        implement CTMExpire
            call BJDebugMsg("2")
            //set x[this] = GetUnitX(u) // what is u set to?
            //set y[this] = GetUnitY(u)
            set bj_lastCreatedGroup = CreateGroup()
            call GroupEnumUnitsInRange(bj_lastCreatedGroup, x[this], y[this], RADIUS, null)
            loop
                call BJDebugMsg("LOOP")
                set u = FirstOfGroup(bj_lastCreatedGroup)
                exitwhen null == u
                call GroupRemoveUnit(bj_lastCreatedGroup, u)
                if TargetFilter(caster[this], owner[this], u) then
                    call BJDebugMsg("3")
                    call DestroyEffect(AddSpecialEffectTarget(EFFECT_PATH,u,"origin"))
                    call UnitDamageTarget(caster[this], u, damage[this], false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
                endif
            endloop
            call DestroyGroup(bj_lastCreatedGroup)
            set waves[this] = waves[this] - 1
            if waves[this] == 0 then
                call BJDebugMsg("4")
                call DestroyEffect(effectCaster[this])
                call this.destroy()
                set caster[this] = null
                set owner[this] = null
            endif
            call BJDebugMsg("5")
        implement CTMEnd
        
        private static method run takes nothing returns nothing
         local integer  level   = GetUnitAbilityLevel(GetTriggerUnit(), ABIL_CODE)
         local thistype this    = create(GetTimeout(level))
         local integer  heroInt

         set caster[this]       = GetTriggerUnit()
         set x[this]            = GetUnitX(caster[this])
         set y[this]            = GetUnitY(caster[this])
         set heroInt            = GetHeroInt(caster[this], true)
         set effectCaster[this] = AddSpecialEffect(EFFECT_CAST, x[this], y[this])
         set owner[this]        = GetOwningPlayer(caster[this])
         set damage[this]       = GetDamage(heroInt)
         set waves[this]        = level
         call BJDebugMsg("1")
        endmethod
        
        private static method onInit takes nothing returns nothing
            call RegisterSpellEffectEvent(ABIL_CODE, function thistype.run)
            static if PRELOAD_EFFECT then
                call Preload(EFFECT_PATH)
                call Preload(EFFECT_CAST)
            endif
        endmethod
    endstruct
    //Family Magtheridon96 ? PROBLEM ?
endlibrary

You want the star fall to stay in the same position even if the caster moves, right? In that case, you do not need to set the struct's x/y values in the timer function.
 
Status
Not open for further replies.
Top