• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[Spell] Help with spell

Status
Not open for further replies.
Level 2
Joined
Jun 10, 2013
Messages
8
I've made this spell based on Flame Phoenix tutorial: Making a spell in vJASS.
I need someone to check it for leaks/bugs or any way to make it more efficient so I can put it in my map.
Sorry if I'm breaking any rule, I'm new to HiveWorkShop forums. Thank you :thumbs_up:
JASS:
scope Spell initializer Spell
 
//==============================SETUP======================================
    globals
       private constant integer SPELL_ID = 'A001' //rawcode of the ability
       private constant string DAMAGE_EFFECT = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
    endglobals
    
    private function Range takes integer level returns real
    //returns the range the spell will affect
        return level * 150.
    endfunction
    
    private function Damage takes integer level returns integer
    //returns the damage enemies will take
        return level * (GetHeroInt(GetTriggerUnit(), true ))
    endfunction
    
    private function Targets takes unit target returns boolean
        //the units the spell will affect
        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
//==============================SETUP END===================================
    globals
        private group all 
        private boolexpr b 
    endglobals
//============================================================================
    private function Pick takes nothing returns boolean
        return Targets(GetFilterUnit())
    endfunction
//======================Conditions=================================================

    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == SPELL_ID
    endfunction

//=======================Actions====================================================

    private function Actions takes nothing returns nothing
        local location spellLoc = GetSpellTargetLoc()
        local real spellX = GetLocationX(spellLoc)
        local real spellY = GetLocationY(spellLoc)
        local unit caster = GetTriggerUnit()
        local integer level = GetUnitAbilityLevel(caster, SPELL_ID)
        local unit f
        
        call GroupEnumUnitsInRange(all, spellX, spellY, Range(level), b)
        
        loop
            set f = FirstOfGroup(all)
            exitwhen(f == null)
            call GroupRemoveUnit(all, f)
            if IsUnitEnemy(f, GetOwningPlayer(caster)) then
                call UnitDamageTarget(caster, f, Damage(level), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_DIVINE, null)
                call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, f, "origin"))
            endif
        endloop
            
        
        
        call RemoveLocation(spellLoc)
        set spellLoc = null
        set caster = null
    endfunction

//====================================================================================
    private function Spell takes nothing returns nothing
        local trigger SpellTrg = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(SpellTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition(SpellTrg, Condition( function Conditions ) )
        call TriggerAddAction( SpellTrg, function Actions )
     
        //setting globals
        set all = CreateGroup()
        set b = Condition (function Pick)
     
        //preloading effects
        call Preload(DAMAGE_EFFECT)
        //preloading Ability 
        set bj_lastCreatedUnit = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),'I000', 0, 0, 0)
        call UnitAddAbility(bj_lastCreatedUnit, 'A001')
        call KillUnit(bj_lastCreatedUnit)
    endfunction
endscope

//===========================================================================
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
This tutorial can be optimized for sure.
I learned vJASS there too ^^'
Old memories ;)

Anyway some optimizations :
Use native UnitAlive takes unit id returns boolean at the begginning of your code so you'll be able to use this awesome native.
Then in your filter function :
JASS:
private function Targets takes unit target returns boolean
    //the units the spell will affect
    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
->
JASS:
private function Targets takes unit target returns boolean
        //the units the spell will affect
        return UnitAlive(target) and not (IsUnitType(target, UNIT_TYPE_STRUCTURE)) and not (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)) and not (IsUnitType(target, UNIT_TYPE_MECHANICAL))
endfunction


JASS:
local location spellLoc = GetSpellTargetLoc()
        local real spellX = GetLocationX(spellLoc)
        local real spellY = GetLocationY(spellLoc)
->
JASS:
local real spellX = GetSpellTargetX()
local real spellY = GetSpellTargetY()


I suggest merging your conditions and actions into your condition like this :
JASS:
private function Conditions takes nothing returns boolean
    //Declare locals (no initialization of those vars)
    if GetSpellAbilityId() == SPELL_ID then
        //Initialize your locals
        //Do your spell
    endif
    return false
endfunction
 
Status
Not open for further replies.
Top