Spell Sacred Circle

Sim

Forum Administrator
Staff member
Reaction score
534
I did it :p

----------------------------------

Just updated the spell!

- No more leak in the Handle Vars.
- Local rect usage.
- Improved the code a bit.
- It is now a JESP standard spell.
- Added some more configuration functions in the header.

Enjoy!

EDIT: 3rd Update!

- No more Divine Revenant: He was useless and the maker removed it from the net: The model is no longer a model for everyone to use.
- Credits are given 3 times.
- Improved the code: rect cleaning, removed useless calls and useless variables. Changed a bit some of the local settings. The spell is even easier to implement now.
 

Sim

Forum Administrator
Staff member
Reaction score
534
0.o 4th Update!

Changelog:

- Improved the code alot*
- No more credits to the Divine Revenant.
- Preloaded stuff in the InitTrig function.
- No more rect usage.

-------------------------

*: Here's a list of the improvements.

- Use of OrderId now in order to stop the spell. No more trigger needed.
- IsUnitAlly --> IsUnitEnemy.
- WEAPON_TYPE_WHOKNOWS changed to null. No more constant to edit it.
- No more targetrect commented line.
- No more useless TriggerSleepAction and double nulling at the end of the Action function.
- Some optimization has been done.
- Removed the variables:

p
nl
u
l

They were useless.

- Using x,y coordinates now, instead of locations.
- No more timer leak.
- not IsUnitDeadBJ(targ) --> GetWidgetLife(targ) > 0
- local effect e - use - destroy --> DestroyEffect( AddSpecialEffect( (params) ) )

Enjoy!
 
R

Ranik

Guest
You guys are fucking crazy, I'm keeping my ass to ideas and testing o.0

Edit: Nice(fucking nice) spell btw!
 

MaaxeEvid

New Member
Reaction score
8
looks nice, i will download to get that model ^^

but i find maaybe a mistake

JASS:
constant function SacredCircle_StrikeInterval takes integer level returns real
    return 0.04 - 0.00 * level 
        // Time between each strike.
endfunction


why {- 0.00 * level?}
it would even return 0.04 ^^
 

Sim

Forum Administrator
Staff member
Reaction score
534
It is there for better editing.

The user will be able to change the interval based off the level by changing the 0.00, which will be multiplied with the level.

The way I did it, it is useless. It's only there for configuration purposes.
 

mightylink

New Member
Reaction score
1
this is probably the best area spell ive seen, it looks good and runs smooth, no hickuping at all but still hundreds of effects, love it
 

Sim

Forum Administrator
Staff member
Reaction score
534
can u give us a pic of the effect? or like a vid of it happening?

It seems like the imagehosting site deleted it...

Uploaded a new one! Thanks for mentionning.
 

Romek

Super Moderator
Reaction score
963
This is ancient. :p

Post the code?

> It uses Handle vars system, I explain in the implementation details how to implement them.
Ehh...

I guess the expectations were different back then.
 

Sim

Forum Administrator
Staff member
Reaction score
534
This is a little bit more than 1 year old. :)

Alright, I will post the code... (Close your eyes)

Actually, never open them :p
 

Azlier

Old World Ghost
Reaction score
461
MY EYESSS.

Handle vars are so ugly! Glad to have learnt Jass after those dark ages.
 

Kenny

Back for now.
Reaction score
202
Regarding the pm I sent you:

JASS:
scope SacredCircle2

    globals
        private constant integer    ABIL_ID    = 'A000'
        private constant integer    ORDER_ID   = 852183
        private constant real       INTERVAL   = 0.04
        private constant string     EFFECT     = "war3mapImported\\HolyStrike.mdx"
        private constant attacktype A_TYPE     = ATTACK_TYPE_CHAOS
        private constant damagetype D_TYPE     = DAMAGE_TYPE_UNIVERSAL
        private constant weapontype W_TYPE     = WEAPON_TYPE_WHOKNOWS
        private constant boolean    STOP_FIRST = false
    endglobals
    
    private function Damage_dealt takes integer lvl returns real
        return 100.00 * lvl
    endfunction
    
    private function Damage_radius takes integer lvl returns real
        return 175.00 + (0.00 * lvl)
    endfunction
    
    private function Filter_enemies takes unit filter, unit caster returns boolean
        return GetWidgetLife(filter) > 0.406 and IsUnitEnemy(filter,GetOwningPlayer(caster)) == true and IsUnitType(filter,UNIT_TYPE_MAGIC_IMMUNE) == false
    endfunction
    
    private struct Data
        
        unit    cast = null
        real    time = 0.00
        real    dist = 0.00
        real    ang  = 0.00
        integer lvl  = 0
        boolean stop = false
        
        static Data     array D
        static integer  D_total = 0
        static timer    Timer   = null
        static group    Group   = null
        static boolexpr Filt    = null
        
        static method filt takes nothing returns boolean
            return true
        endmethod
        
        method onDestroy takes nothing returns nothing
            set .cast = null
        endmethod
        
        method search takes nothing returns nothing
            local integer i = 1
            
            loop
                exitwhen i > Data.D_total
                if Data.D<i>.cast == .cast then
                    if STOP_FIRST then
                        set Data.D<i>.stop = true
                    else
                        set .stop = true
                    endif
                endif
                set i = i + 1
            endloop
        endmethod
        
        method periodic takes nothing returns boolean
            local real x = GetUnitX(.cast)
            local real y = GetUnitY(.cast)
            local unit u = null
            
            if GetUnitCurrentOrder(.cast) != ORDER_ID or .time &lt;= 0 then
                return true
            else
                set x = x + (50.00 + .dist * 10.00) * Cos(.ang * bj_DEGTORAD)
                set y = y + (50.00 + .dist * 10.00) * Sin(.ang * bj_DEGTORAD)
                
                call DestroyEffect(AddSpecialEffect(EFFECT,x,y))
                call GroupEnumUnitsInRange(Data.Group,x,y,Damage_radius(.lvl),Data.Filt)
                loop
                    set u = FirstOfGroup(Data.Group)
                    exitwhen u == null
                    call GroupRemoveUnit(Data.Group,u)
                    if Filter_enemies(u,.cast) then
                        call UnitDamageTarget(.cast,u,Damage_dealt(.lvl),false,false,A_TYPE,D_TYPE,W_TYPE)
                    endif
                endloop
                
                set .ang  = (.ang  + 24.00 - .dist / 6.00)
                set .dist = (.dist + 1.00)
                set .time = (.time - INTERVAL)
            endif
            
            set u = null
            
            return false
        endmethod            
        
        static method update takes nothing returns nothing
            local integer i = 1
            
            loop
                exitwhen i &gt; Data.D_total
                
                if Data.D<i>.stop or Data.D<i>.periodic() then
                    call Data.D<i>.destroy()
                    set Data.D<i> = Data.D[Data.D_total]
                    set Data.D_total = Data.D_total - 1
                    set i = i - 1
                endif
                
                set i = i + 1
            endloop
            
            if Data.D_total &lt;= 0 then
                call PauseTimer(Data.Timer)
                set Data.D_total = 0
            endif
        endmethod
        
        static method actions takes nothing returns boolean
            local Data d = Data.create()
            
            set d.cast = GetTriggerUnit()
            set d.lvl  = GetUnitAbilityLevel(d.cast,ABIL_ID)
            set d.time = 100.00 * INTERVAL
            call d.search()
            
            set Data.D_total = Data.D_total + 1
            set Data.D[Data.D_total] = d
            if Data.D_total == 1 then
                call TimerStart(Data.Timer,INTERVAL,true,function Data.update)
            endif
            
            return false
        endmethod
        
        static method conditions takes nothing returns boolean
            return GetSpellAbilityId() == ABIL_ID
        endmethod
            
        static method onInit takes nothing returns nothing
            local trigger trig = CreateTrigger()
            local integer i    = 0
            
            set Data.Timer = CreateTimer()
            set Data.Group = CreateGroup()
            set Data.Filt  = Filter(function Data.filt)
            
            loop
                call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Data.Filt)
                set i = i + 1
                exitwhen i == bj_MAX_PLAYER_SLOTS
            endloop
            
            call TriggerAddCondition(trig,Condition(function Data.conditions))
            call TriggerAddAction(trig,function Data.actions)
        endmethod
        
    endstruct

endscope

</i></i></i></i></i></i>


Awesome spell by the way :).
 

Sim

Forum Administrator
Staff member
Reaction score
534
Whoa.

Necro-update! :)

Thanks kenny for all the help.
 

Immolation

Member
Reaction score
20
Great spell. I don't usually like this kind of spells, but this one is really a masterpiece. Wonderful job :D
 

Pyroflame

New Member
Reaction score
4
How can I make this heal? I don't know much about jass but I think I have to edit this line somehow...

call GroupEnumUnitsInRange(Data.Group,x,y,Damage_radius(.lvl),Data.Filt)

I tried GroupAllyUnitsInRange and other varations, searched the function list for anything starting with Group but I didn't see nothing to do with choosing allies in range?

Anyways great spell.
 

cleeezzz

The Undead Ranger.
Reaction score
268
you would have to edit his filter to pick allied units

filter change would look like this
JASS:
private function Filter_enemies takes unit filter, unit caster returns boolean
        return GetWidgetLife(filter) &gt; 0.406 and IsUnitAlly(filter,GetOwningPlayer(caster)) == true and IsUnitType(filter,UNIT_TYPE_MAGIC_IMMUNE) == false
    endfunction

(im just gonna leave it called, Filter_enemies or else you have to change the filter name in the code as well.)


and change this...
JASS:
call UnitDamageTarget(.cast,u,Damage_dealt(.lvl),false,false,A_TYPE,D_TYPE,W_TYPE)

to.. something along the lines of .


for healamount, put in the number of hp you want to heal

just for future reference, Enum is like the equiv to Picked Unit, so you cant change it to ally, GroupEnumUnits (along with a ForGroup or FirstOfGroup loops)is like a Pick every unit loop in GUI

and nice spell.
 

Pyroflame

New Member
Reaction score
4
you would have to edit his filter to pick allied units

filter change would look like this
JASS:
private function Filter_enemies takes unit filter, unit caster returns boolean
        return GetWidgetLife(filter) &gt; 0.406 and IsUnitAlly(filter,GetOwningPlayer(caster)) == true and IsUnitType(filter,UNIT_TYPE_MAGIC_IMMUNE) == false
    endfunction

(im just gonna leave it called, Filter_enemies or else you have to change the filter name in the code as well.)


and change this...
JASS:
call UnitDamageTarget(.cast,u,Damage_dealt(.lvl),false,false,A_TYPE,D_TYPE,W_TYPE)

to.. something along the lines of .


for healamount, put in the number of hp you want to heal

just for future reference, Enum is like the equiv to Picked Unit, so you cant change it to ally, GroupEnumUnits (along with a ForGroup or FirstOfGroup loops)is like a Pick every unit loop in GUI

and nice spell.

Thanks a lot; one of these days I'll time to sit down and learn JASS...
+Reputation to both of you.

Edit:
Actually it doesn't seem to be working properly. No matter what I set HealthAmount to it only heals 3-6 damage it seems.. This is my code.

JASS:
//¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
//¤
//¤ ***************** 
//¤ - Sacred Circle - 
//¤ *****************
//¤ 
//¤ By: Daxtreme
//¤ 
//¤ --&gt; How to implement in your map:
//¤     
//¤     1. Copy the game cache variable named &quot;GameCache&quot; in your map.                         
//¤     2. Copy the spell &quot;Sacred Circle&quot; in your map.
//¤     3. Copy everything found in the &quot;Custom script code&quot; section. To do this, click
//¤        on the name of the map in the top-left corner in the trigger editor.
//¤     4. Make a variable called &quot;GameCache&quot;.
//¤     5. Copy this trigger into your map.
//¤     6. Import the HolyStrike.mdx model in your map.
//¤
//¤ --&gt; How to customize it:
//¤
//¤     You can configure the spell using the constant functions just below. Change their values.
//¤
//¤ CREDITS:
//¤
//¤     - JetFangInferno&#039;s Holy Strike.
//¤     - kenny! for testing, bug-finding, and updating!
//¤
//¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

scope SacredCircle2

    globals
        private constant integer    ABIL_ID    = &#039;A000&#039;       // Sacred Circle&#039;s ability Id
        private constant integer    ORDER_ID   = 852183
        private constant real       INTERVAL   = 0.04         // Period
        private constant string     EFFECT     = &quot;war3mapImported\\HolyStrike.mdx&quot;      // Spell model art
        private constant attacktype A_TYPE     = ATTACK_TYPE_CHAOS
        private constant damagetype D_TYPE     = DAMAGE_TYPE_UNIVERSAL
        private constant weapontype W_TYPE     = WEAPON_TYPE_WHOKNOWS
        private constant boolean    STOP_FIRST = false
    endglobals
    
    private function Damage_dealt takes integer lvl returns real
        return 100.00 * lvl
    endfunction
    
    private function HealAmount takes integer lvl returns real
        return 1000.00 * lvl
    endfunction
    
    private function Damage_radius takes integer lvl returns real
        return 175.00 + (0.00 * lvl)
    endfunction
    
    private function Filter_enemies takes unit filter, unit caster returns boolean
        return GetWidgetLife(filter) &gt; 0.406 and IsUnitAlly(filter,GetOwningPlayer(caster)) == true and IsUnitType(filter,UNIT_TYPE_MAGIC_IMMUNE) == false
    endfunction
    
    private struct Data
        
        unit    cast = null
        real    time = 0.00
        real    dist = 0.00
        real    ang  = 0.00
        integer lvl  = 0
        boolean stop = false
        
        static Data     array D
        static integer  D_total = 0
        static timer    Timer   = null
        static group    Group   = null
        static boolexpr Filt    = null
        
        static method filt takes nothing returns boolean
            return true
        endmethod
        
        method onDestroy takes nothing returns nothing
            set .cast = null
        endmethod
        
        method search takes nothing returns nothing
            local integer i = 1
            
            loop
                exitwhen i &gt; Data.D_total
                if Data.D<i>.cast == .cast then
                    if STOP_FIRST then
                        set Data.D<i>.stop = true
                    else
                        set .stop = true
                    endif
                endif
                set i = i + 1
            endloop
        endmethod
        
        method periodic takes nothing returns boolean
            local real x = GetUnitX(.cast)
            local real y = GetUnitY(.cast)
            local unit u = null
            
            if GetUnitCurrentOrder(.cast) != ORDER_ID or .time &lt;= 0 then
                return true
            else
                set x = x + (50.00 + .dist * 10.00) * Cos(.ang * bj_DEGTORAD)
                set y = y + (50.00 + .dist * 10.00) * Sin(.ang * bj_DEGTORAD)
                
                call DestroyEffect(AddSpecialEffect(EFFECT,x,y))
                call GroupEnumUnitsInRange(Data.Group,x,y,Damage_radius(.lvl),Data.Filt)
                loop
                    set u = FirstOfGroup(Data.Group)
                    exitwhen u == null
                    call GroupRemoveUnit(Data.Group,u)
                    if Filter_enemies(u,.cast) then
                        call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_LIFE) + HealAmount)
                    endif
                endloop
                
                set .ang  = (.ang  + 24.00 - .dist / 6.00)
                set .dist = (.dist + 1.00)
                set .time = (.time - INTERVAL)
            endif
            
            set u = null
            
            return false
        endmethod            
        
        static method update takes nothing returns nothing
            local integer i = 1
            
            loop
                exitwhen i &gt; Data.D_total
                
                if Data.D<i>.stop or Data.D<i>.periodic() then
                    call Data.D<i>.destroy()
                    set Data.D<i> = Data.D[Data.D_total]
                    set Data.D_total = Data.D_total - 1
                    set i = i - 1
                endif
                
                set i = i + 1
            endloop
            
            if Data.D_total &lt;= 0 then
                call PauseTimer(Data.Timer)
                set Data.D_total = 0
            endif
        endmethod
        
        static method actions takes nothing returns boolean
            local Data d = Data.create()
            
            set d.cast = GetTriggerUnit()
            set d.lvl  = GetUnitAbilityLevel(d.cast,ABIL_ID)
            set d.time = 100.00 * INTERVAL
            call d.search()
            
            set Data.D_total = Data.D_total + 1
            set Data.D[Data.D_total] = d
            if Data.D_total == 1 then
                call TimerStart(Data.Timer,INTERVAL,true,function Data.update)
            endif
            
            return false
        endmethod
        
        static method conditions takes nothing returns boolean
            return GetSpellAbilityId() == ABIL_ID
        endmethod
            
        static method onInit takes nothing returns nothing
            local trigger trig = CreateTrigger()
            local integer i    = 0
            
            set Data.Timer = CreateTimer()
            set Data.Group = CreateGroup()
            set Data.Filt  = Filter(function Data.filt)
            
            loop
                call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Data.Filt)
                set i = i + 1
                exitwhen i == bj_MAX_PLAYER_SLOTS
            endloop
            
            call TriggerAddCondition(trig,Condition(function Data.conditions))
            call TriggerAddAction(trig,function Data.actions)
        endmethod
        
    endstruct

endscope</i></i></i></i></i></i>


I changed everything you told me to? Why is it only healing 3-6 damage. I used the same exact test map.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top