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

Frost Orb v1.2

Another spell made by me with vJass

===================================================================
Frost Orb

Creates an orb which surrounds the target. Each unit hit by the orb will be damaged and frozen for 2 seconds. Each unit can only frozen for one time.
Level 1 - The orb deals 90 damage. Max. 10 units can be hit by the orb.
Level 2 - The orb deals 140 damage. Max. 18 units can be hit by the orb.
Level 3 - The orb deals 190 damage. Max. 26 units can be hit by the orb.
===================================================================

The Spell Requires:

JNGP

changes
==========================================
v1.0
- release
==========================================
v1.1
- Cleaned the script
- Removed unnecessary script lines
- Now there is a better overview
- Removed the interface-system by Hankey, Replaced it with the timer stacking method
- Added a Group Recycler (For more information check the GroupRecycler Trigger
- Changed + Removed some constants
- Reduced the range of the Orb-Missile to 85
- Removed DUMMY_DURATION constant
==========================================
v.1.2
- Fixed a bug with the missile pathing
==========================================

JASS:
library GroupRecycler
//*********************************************************************
//* Group Recycler 1.0 by xD.Schurke
//* ------------------
//*  
//* To implement just create a custom text trigger and paste the script
//* there.
//*
//* This script requires vJass (JassNewGenPack)
//*   
//* Usage of the scriot:  
//*   - Recycle Groups
//*   
//* set group g = NewGroup()  : Get a group (alternative to CreateGroup)
//* call ReleaseGroup(g)      : Releases a group (alternative to  
//*                                                 DestroyGroup)
//*   
//********************************************************************* 
    globals
        private constant integer MAX_GROUPS = 8191
    
        private group array rG
        private integer rN = 0
    endglobals
    
    function NewGroup takes nothing returns group
        if (rN == 0) then
            set rG[0] = CreateGroup()
        else
            set rN = rN - 1
        endif
     return rG[rN]
    endfunction

    function ReleaseGroup takes group g returns nothing
        if(g == null) then
            debug call BJDebugMsg("Warning: Try to release a null group")
            return
        endif
        if (rN == MAX_GROUPS) then
            debug call BJDebugMsg("Warning: Limit reached, Destroying Group")
            call DestroyGroup(g)
        else
            call GroupClear(g)
            set rG[rN] = g
            set rN = rN + 1
        endif    
    endfunction
endlibrary
JASS:
//*********************************************************************************************************************
//* Frost Orb v.1.2 by xD.Schurke
//* ------------------------------
//*
//* Requirements:
//* --------------
//* * vJass (JassNewGenPack)
//* * GroupRecycler
//*
//*
//*
//* Changes in version 1.1:
//* ----------
//* * Cleaned the script
//*   * Removed unnecessary script lines
//*   * Now there is a better overview
//*   * Removed the interface-system by Hankey, Replaced it with the timer stacking method
//*   * Added a Group Recycler (For more information check the GroupRecycler Trigger
//* * Changed + Removed some constants  
//*   * Reduced the range of the Orb-Missile to 85
//*   * Removed DUMMY_DURATION constant
//* 
//* Changes in version 1.2:
//* ----------
//* * Fixed a bug with the missile pathing
//*
//*
//*
//* 1. Copy the GroupRecycler to your map
//* 2. Copy the Frost Orb Trigger to your map
//* 3. Copy the Spells and Buffs (Obejct Editor) to your map => You maybe need to change the raw codes in Frost Orb
//* 4. Change nessesery things in the Frost Orb constants
//*   4.1 Check Dummy Raw-Code (If needed copy dummy-unit (Object Editor) and dummy model (Import Manager) dummy.mdx)
//*   4.2 Check Spell Raw-Codes
//*
//*********************************************************************************************************************

library FrostOrb initializer frostInt requires GroupRecycler
globals
    
    private constant integer        DUMMY                       = 'h000' //the dummy raw-code => Change to your map specific one
    private constant integer        SPELL_RAW                   = 'A000' //the spell raw-code => Change to your map specific one
    private constant integer        DUMMY_SPELL                 = 'A001' //the dummy-spell raw-code => Change to your map specific one
    private constant integer        DUMMY_SPELL_DEBUFF          = 'B000' //the dummy-spell-debuff raw-code => Change to your map specific one
    private constant integer        TIMED_LIFE                  = 'BTLF' //the timed life buff raw code => DO NOT CHANGE
    
    private constant string         MISSILE_SFX                 = "Abilities\\Weapons\\ZigguratFrostMissile\\ZigguratFrostMissile.mdl" //the orb modell
    
    private constant real           MISSILE_DISTANCE            = 85. //the distance between target and orb
    private constant real           MISSILE_SPEED               = 12.  //the orb speed increase/decrease for change speed
    private constant real           MISSILE_DURATION            = 15.  //the duration of the orb in seconds
    private constant real           MISSILE_DURATION_INCREASE   = 6.   //how many seconds are added per level
    private constant real           MISSILE_MOTION_UPDATE       = 0.03 //for duration reason => DO NOT CHANGE
    private constant real           MISSILE_DAMAGE              = 90.  //the damage delt to the units hit by the orb
    private constant real           MISSILE_DAMAGE_INCREASE     = 50.  //the damage added per lvl
    private constant real           MISSILE_RADIUS              = 80.  //the radius where the orb deals damage to units
    
    private constant integer        MAX_HITS                    = 10   //how many units can be hit by the spell
    private constant integer        MAX_HITS_INCREASE           = 8    //units added to spell per lvl who can be hit
    
    //attatchement point
    private constant string         chest = "chest"
    
    //Group Reason stuff => DO NOT CHANGE
                     group          tmpG = CreateGroup()
                     player         tmpP
                     boolexpr       Cond
    
    private          timer          Tim = CreateTimer()
    private          integer array  Data
    private          integer        Total = 0
endglobals

//Constant functions for damage/duration/hit formular
private constant function Hits takes integer lvl returns integer
    return MAX_HITS+((lvl-1)*MAX_HITS_INCREASE)
endfunction

private constant function Damage takes integer lvl returns real
    return MISSILE_DAMAGE+((lvl-1)*MISSILE_DAMAGE_INCREASE)
endfunction

private constant function Duration takes integer lvl returns real
    return MISSILE_DURATION+((lvl-1)*MISSILE_DURATION_INCREASE)
endfunction

//group filter function
private function filter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(),tmpP) and (GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE)>0) and IsUnitType(GetFilterUnit(),UNIT_TYPE_GROUND) and (GetUnitTypeId(GetFilterUnit())!=DUMMY)
endfunction

//the struct for the orb
private struct FrostStruct
    unit    caster        //the caster who casts the spell
    unit    target        //the target of the Frost Orb
    unit    missile       //the Frost Orb
    effect  sfx           //Frost Orb Effect
    real    x        = 0. //x of target
    real    y        = 0. //y of target
    real    ang      = 0  //angle for orb movement
    real    dur      = 0  //duration counted
    integer hit      = 0  //how many units were hit by the orb
    group   g             //to prevent multiple damaging in one surrounding
    
    static method move takes nothing returns nothing
        local FrostStruct dat
        local integer i = 0
        local unit u
        local unit dummy
        local real x = 0.
        local real y = 0.
        loop
            exitwhen i >= Total
            set dat = Data[i]
            set dat.dur = dat.dur + MISSILE_MOTION_UPDATE
            set dat.x = GetUnitX(dat.target)
            set dat.y = GetUnitY(dat.target)
            set x = dat.x + MISSILE_DISTANCE * Cos(dat.ang * bj_DEGTORAD)
            set y = dat.y + MISSILE_DISTANCE * Sin(dat.ang * bj_DEGTORAD)
            set tmpP = GetOwningPlayer(dat.caster)
            call GroupEnumUnitsInRange(tmpG,x,y,MISSILE_RADIUS,Cond)
            loop
                set u = FirstOfGroup(tmpG)
                exitwhen u == null
                if IsUnitInGroup(u,dat.g) or GetUnitAbilityLevel(u,DUMMY_SPELL_DEBUFF) > 0 then
                    call GroupRemoveUnit(tmpG,u)
                else                    
                    call UnitDamageTarget(dat.caster,u,Damage(GetUnitAbilityLevel(dat.caster,SPELL_RAW)),false,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_MAGIC,WEAPON_TYPE_WHOKNOWS)
                    set dummy = CreateUnit(GetOwningPlayer(dat.caster),DUMMY,GetUnitX(u),GetUnitY(u),0)
                    call UnitAddAbility(dummy,DUMMY_SPELL)
                    call IssueTargetOrder(dummy,"thunderbolt",u)
                    call UnitApplyTimedLife(dummy,TIMED_LIFE,1.)
                    set dat.hit = dat.hit + 1
                    call GroupAddUnit(dat.g,u)
                    call GroupRemoveUnit(tmpG,u)
                endif                
            endloop
            call SetUnitPosition(dat.missile,x,y)
            set dat.ang = dat.ang + MISSILE_SPEED
            if dat.dur >= Duration(GetUnitAbilityLevel(dat.caster,SPELL_RAW)) or GetUnitState(dat.target,UNIT_STATE_LIFE) <= 0 or dat.hit >= Hits(GetUnitAbilityLevel(dat.caster,SPELL_RAW)) then
                set Total = Total - 1
                set Data[i] = Data[Total]
                set i = i - 1
                call FrostStruct.destroy(dat)
            endif
            set i = i + 1
        endloop
        set dummy = null
        set u = null
    endmethod
    
    static method create takes nothing returns FrostStruct
        local FrostStruct dat = FrostStruct.allocate()
        if Total == 0 then
            call TimerStart(Tim,MISSILE_MOTION_UPDATE,true,function FrostStruct.move)
        endif
        set Data[Total] = dat
        set Total = Total + 1
        return dat
    endmethod
    
    method onDestroy takes nothing returns nothing
        call KillUnit(.missile)
        call ReleaseGroup(.g)
        set .g = null
        set .caster = null
        set .missile = null
        set .target = null
        set .sfx = null   
    endmethod
endstruct

//Condition
private function frostCond takes nothing returns boolean
    return GetSpellAbilityId() == SPELL_RAW
endfunction

//Actions creates struct and sets values
private function frostAction takes nothing returns nothing
    local FrostStruct F
    local real x
    local real y
    set F = FrostStruct.create()
    set F.g = NewGroup()
    set F.caster = GetTriggerUnit()
    set F.target = GetSpellTargetUnit()
    set F.x = GetUnitX(F.target)
    set F.y = GetUnitY(F.target)
    set x = F.x + MISSILE_DISTANCE * Cos(F.ang * bj_DEGTORAD)
    set y = F.y + MISSILE_DISTANCE * Sin(F.ang * bj_DEGTORAD)
    set F.missile = CreateUnit(GetOwningPlayer(F.target),DUMMY,F.x,F.y,0)
    set F.sfx = AddSpecialEffectTarget(MISSILE_SFX,F.missile,chest)
    call SetUnitPathing(F.missile,false)
    set F.ang = F.ang + MISSILE_SPEED
endfunction

//Event etc.
private function frostInt takes nothing returns nothing
    local trigger int = CreateTrigger()
    local integer index = 0
    local unit u
    loop
        call TriggerRegisterPlayerUnitEvent(int, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition(int,Condition(function frostCond))
    call TriggerAddAction(int,function frostAction)
    set int = null
    set Cond=Condition(function filter)
    //Preload
    set u = CreateUnit(Player(14),DUMMY,999999,999999,0)
    call UnitAddAbility(u,DUMMY_SPELL)
    call RemoveUnit(u)
    set u = null
    call Preload(MISSILE_SFX)
    call PreloadStart()
endfunction
endlibrary

Keywords:
vJASS,Frost,Orb,Jass,xD.Schurke,Spell
Contents

Frost Orb v1.0 (Map)

Reviews
20:23, 3rd Dec 2008 Hanky: A really good spell, I like the idea very much. The scripting is good just very small improvements could be done there, also the spell is leakfree and MUI, so far I can see it. The visual effects are well done and the...

Moderator

M

Moderator

20:23, 3rd Dec 2008
Hanky:
A really good spell, I like the idea very much. The scripting is good just very small improvements could be done there, also the spell is leakfree and MUI, so far I can see it. The visual effects are well done and the documentation and tooltips are ok too.

Well, you done again a good job. I just can highly recommend to use this spell if this is what you are searching for.
 
Level 8
Joined
Jul 14, 2010
Messages
235
I get a compile error with the GroupRecycler
Does this sentence: "function NewGroup takes nothing returns group" need to be unique? There is another system I got (GroupUtils) that also has the "function NewGroup takes nothing returns group" sentence.
If the problem is that they crash, what to do?
 
Top