• 🏆 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] Custom Summon Spell

Status
Not open for further replies.
Please, give comments.
JASS:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                              CUSTOM SUMMON SPELL (CSS)
//                                      eubz
//
//==============================================================
// 
//CSS Damages the target while summoning allies.
//
//Level 1 - 50 damage; summoned unit [Bandit]
//Level 2 - 100 damage; summoned unit  [Rogue]
//Level 3 - 150 damage; summoned unit [Bandit Lord]
//
//=========================================================
// Very easy to use. Just copy this code into your map and the custom ability, then decide the custom units to spawn.
//
//NOTES: 1. Give credits to me if you use this in your map.
//       2. You can control the summoned units and they don't expire unless they die.
//==============================================================
// 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
library CSS initializer Init

//================================================================
    globals
                //YOU CAN CONFIGURE THIS PART OF THE SPELL
        private constant string S1 = "origin"//the attachment point of unit
        private constant string SFX1 = "Environment\\LargeBuildingFire\\LargeBuildingFire1.mdl"//SFX attached to the caster
        private constant string SFX2 = "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"//SFX attached to the target
        private constant string SFX3 = "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl"//SFX attached to the summoned unit
        private constant real DAMAGE = 50.00 //the damage dealt
        private constant integer S_ID = 'A000'//the spell ID
        private constant integer U_ID1 = 'n000' //level 1 unit id (bandit)
        private constant integer U_ID2 = 'n001' //level 2 unit id (rogue)
        private constant integer U_ID3 = 'n002' //level 3 unit id (bandit lord)
        private constant damagetype DTYPE = DAMAGE_TYPE_NORMAL
        private constant attacktype ATYPE = ATTACK_TYPE_NORMAL
    endglobals
//================================================================
                        //END OF CONFIGURATION/*
    
    private function spell_id_func takes nothing returns boolean
        return GetSpellAbilityId() == 'A000'
    endfunction
    
    native UnitAlive takes unit id returns boolean

    private function filter takes unit c, unit tar returns boolean
        return UnitAlive(tar)/*
        */and IsUnitEnemy(tar, GetOwningPlayer(c))/*
        */and not IsUnitType(tar,UNIT_TYPE_STRUCTURE)/*
        */and not IsUnitType(tar,UNIT_TYPE_MAGIC_IMMUNE)
    endfunction
//setting her some important variables
    globals
        private integer array unit_id
        private unit c
        private unit tar
        private unit nu
        private real dam
        private integer level
        private integer TL
    endglobals
//this is the formula for getting the damage inflicted to target
    private function damage_enemy takes nothing returns real
        return DAMAGE*level
    endfunction
//this will tell which unit will spawn
    private function unit_count takes nothing returns integer
            local integer count
            local integer counter = 1
            set count = counter*level
        return count
    endfunction
//here, I have assigned the units to spawn
   private function spawned takes nothing returns integer array
            set TL = unit_count( )
            set  unit_id[1] = U_ID1
            set  unit_id[2] = U_ID2
            set  unit_id[3] = U_ID3
        return unit_id[TL]
    endfunction
//the spell action
    private function Trigger_Actions takes nothing returns nothing
        local real x
        local real y
        local real facing
        local player P
        set tar = GetSpellTargetUnit()
        set c = GetTriggerUnit()
        set level  = GetUnitAbilityLevel(c, S_ID)
        set dam = damage_enemy( )
        set x = GetUnitX(tar)
        set y = GetUnitY(tar)
        set P = GetOwningPlayer(c)
        set facing = GetUnitFacing(c)
        if filter(c, tar) then
            call UnitDamageTarget(c, tar, dam, true, false, ATYPE,DTYPE, null)
            call DestroyEffect(AddSpecialEffectTarget(SFX2,tar,S1))
            call DestroyEffect(AddSpecialEffectTarget(SFX1,c,S1))
            set nu = CreateUnit(P, spawned( ), x, y, facing)
            call DestroyEffect(AddSpecialEffectTarget(SFX3,nu,S1))
        endif
    endfunction

    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerAddAction( t, function Trigger_Actions )
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition (function spell_id_func))
    endfunction
    
endlibrary
//SPELL DONE//====================================================
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
  • You use a bunch of globals (tar, c, level etc) for no reason.
  • You make one-liner functions for no reason (like damage_enemy) and functions whose logic is completely pointless (unit_count could just returns level).
  • You start your array at 1 rather than 0.
  • You reinitialize your array every time you want to read from it, which is pointless.
  • Based on the header it seems that you intend to submit this as a spell, whereas it's much too simple for anyone to care.
  • "filter" should be included in the trigger conditions, and it should be slightly less exhaustive. Most of those checks should be taken care of by the spell targeting; you only want the filter to be a last-case scenario. I left in the Enemy check in my code below since I can't remember off the top of my head whether the targeting filter for Enemy actually works properly or not so I assumed it doesn't.

Here's a fixed version:

JASS:
library CSS initializer Init

//================================================================
    globals
        private integer array UnitIDs
                //YOU CAN CONFIGURE THIS PART OF THE SPELL
        private constant string S1 = "origin"//the attachment point of unit
        private constant string SFX1 = "Environment\\LargeBuildingFire\\LargeBuildingFire1.mdl"//SFX attached to the caster
        private constant string SFX2 = "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"//SFX attached to the target
        private constant string SFX3 = "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl"//SFX attached to the summoned unit
        private constant real DAMAGE = 50.00 //the damage dealt
        private constant integer S_ID = 'A000'//the spell ID
        private constant damagetype DTYPE = DAMAGE_TYPE_NORMAL
        private constant attacktype ATYPE = ATTACK_TYPE_NORMAL
    endglobals
    private function InitializeUnitIDs takes nothing returns nothing
        //The unit type summoned. [0] denotes level 1, [1] denotes level 2 etc.
        set UnitIDs[0] = 'n000' //bandit
        set UnitIDs[1] = 'n001' //rogue
        set UnitIDs[2] = 'n002' //bandit lord
    endfunction
//================================================================
                        //END OF CONFIGURATION/*
    
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == S_ID and IsUnitEnemy(GetSpellTargetUnit(), GetOwningPlayer(GetTriggerUnit()))
    endfunction

    private function Actions takes nothing returns nothing
        local unit t = GetSpellTargetUnit()
        local unit u = GetTriggerUnit()
        local integer level = GetUnitAbilityLevel(u, S_ID)
        call UnitDamageTarget(u, t, DAMAGE*level, true, false, ATYPE, DTYPE, null)
        call DestroyEffect(AddSpecialEffectTarget(SFX1,u,S1))
        call DestroyEffect(AddSpecialEffectTarget(SFX2,t,S1))
        set u = CreateUnit(GetOwningPlayer(u), UnitIDs[level-1], GetUnitX(t), GetUnitY(t), GetUnitFacing(u))
        call DestroyEffect(AddSpecialEffectTarget(SFX3,u,S1))
        set u = null
        set t = null
    endfunction

    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition (function Conditions))
        call TriggerAddAction(t, function Actions)
        call InitializeUnitIDs()
    endfunction
endlibrary
 
Last edited:
Status
Not open for further replies.
Top