• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[vJASS] Spell problem

Status
Not open for further replies.
Level 9
Joined
Apr 23, 2011
Messages
460
Hello everyone! I'm back from my short lived vacation to Michigan and on the way up and there I was working on a spell for a hero in my map and I'm not a spell creator :vw_wtf: so I would like some constructive feedback (what the hell is wrong with this) and suggestions for future spell creation (what did I do wrong, how can I fix it, whats the bottom line for practicing spell creation). All comments are welcome (no martians though...) so please feel free to critique what you wish. Please note that it's probably terrible, sorry.

JASS:
library ArcDrain initializer init    
    globals
        private real array duration
        private real array drain
        private unit caster
        private unit target
        private constant string effectString = ""
        private constant integer SPELL = 'Arcd'
        private constant integer BUFF = 'Arcs'
    endglobals
    
    scope BuffTick
        private function FilterUnits takes nothing returns boolean
            return (GetUnitAbilityLevel(GetFilterUnit(), BUFF) > 0)
        endfunction
        
        private function BuffTick takes nothing returns nothing
            local group g = CreateGroup()
            local unit u
            local integer i
            call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, Filter(function FilterUnits))
            loop
                set u = FirstOfGroup(g)
                exitwhen u == null
                set i = GetUnitTypeId(u)
                call GroupRemoveUnit(g, u)
                call SetUnitState(u, UNIT_STATE_MANA, (GetUnitState(u, UNIT_STATE_MANA) - drain[i]))
                set duration[i] = duration[i] - 1
                if duration[i] == 0 then
                    call UnitRemoveAbility(u, BUFF)
                endif
                set u = null
            endloop
            call DestroyGroup(g)
            set g = null
        endfunction
        function Ticker takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterTimerEvent(t, 1., true)
            call TriggerAddAction(t, function BuffTick)
            set t = null
        endfunction
    endscope            
    
    private struct spell extends array                
        
        private static method buffApply takes nothing returns nothing
            local unit dummy = CreateUnit(Player(12), 'dumy', GetUnitX(target), GetUnitY(target), 270.)
            call UnitAddAbility(dummy, BUFF)
            call IssueTargetOrder(dummy, "frostnova", target)
            call RemoveUnit(dummy)
            set dummy = null
        endmethod
        
       static method allocate takes nothing returns nothing
            local integer sLevel
            set caster = GetSpellAbilityUnit()
            set sLevel = GetUnitAbilityLevel(caster, SPELL)
            set target = GetSpellTargetUnit()
            set drain[GetUnitTypeId(target)] = ((sLevel * 2) + 5)
            set duration[GetUnitTypeId(target)] = ((sLevel * 2) + 5)
            call .buffApply()
        endmethod
       
    endstruct
    
    globals
        spell array Cast
    endglobals
    
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        call Ticker()
        loop
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
            set i = i + 1
            exitwhen i > 11
        endloop
        call TriggerAddAction(t, function spell.allocate)
        set t = null
    endfunction
endlibrary

Edit: Before anyone says anything, I'm aware that the effect is "". This is on purpose.
 
Last edited:
1)you don't overwrite the allocate method... what you overwrite is the create method then add local thistype this = .allocate() as the first line and use "this" as the variable name for that instance

2)I don't see the point of making that scope inside the library

3)learn how to use structs (read the tut on the tut section and see spells which uses structs)

4)just make one globals block

Right now this isn't MUI even if it will work because caster is a single global variable, target is also a single global variable... so make sure you do number 3...

actually, I think .buffApply will work if he did number 1 because I think not adding a struct identifier before the dot turns it into this.something y default or so I read... but its very implicit and not a good practice to do so...

this spell should be reworked from scratch... seriously...
 
You never created a struct instance

JASS:
static method create takes nothing returns thistype
    local thistype this = .allocate() //something like this
    return this //just so it won't return a compile error if you ever tried to CnP this method
endmethod

//can also be
call struct.create()

//but we prefer to overwrite the create method (first method above) for faster execution

if you don't even know how to create struct instances I seriously suggest that you read tutorials or look at vJASS spells here using structs
 
Level 16
Joined
Mar 3, 2006
Messages
1,564
Explain the first one, and because it is static is acts as a function I believe.

Methods are always function the difference between static and non-static is that non-static don't take the integer argument this. Explain:

JASS:
method testMethod takes unit u returns nothing
endmethod

will be written in the j file as

JASS:
function s_structName__testMethod @takes integer this@, unit u returns nothing
endfunction
while static is the same but without the integer this.
 
Methods are always function the difference between static and non-static is that non-static don't take the integer argument this

-->which leads to very different usage between the two

basically, we use non-static (or instanced methods) if we need the function to be related to its specific struct instance (like the destroy method) while we use static for general methods (like the create method)...

JASS:
struct A

    method B takes nothing returns nothing
    endmethod
   
    static method C takes nothing returns nothing
    endmethod

    static method D takes nothing returns nothing
        local thistype this = .allocate()
        call this.B() //the variable this will tell method B which instance it's called for
        call this.C() //this will probably return a compile error since C is static
        call A.C()
    endmethod

endstruct
 
Status
Not open for further replies.
Top