Spell Sacred Circle

Sim

Forum Administrator
Staff member
Reaction score
531
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
531
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
531
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
531
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
Staff member
Reaction score
960
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
531
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
531
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
267
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's Holy Strike.
//¤     - kenny! for testing, bug-finding, and updating!
//¤
//¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

scope SacredCircle2

    globals
        private constant integer    ABIL_ID    = 'A000'       // Sacred Circle'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.
  • jonas jonas:
    That sounds like fun!
    +1
  • The Helper The Helper:
    it was a blast!
  • The Helper The Helper:
    I am going to post the Youtube of the investigation in the forums when it is ready
    +1
  • jonas jonas:
    cool!
  • vypur85 vypur85:
    Sounds cool TH.
  • tom_mai78101 tom_mai78101:
    I was on a Legend of Zelda marathon...
  • tom_mai78101 tom_mai78101:
    Am still doing it now
    +1
  • jonas jonas:
    which one(s) are you playing?
  • jonas jonas:
    I played a little bit of the switch title two weeks ago and found it quite boring
  • The Helper The Helper:
    just got back from San Antonio this weekend had the best Buffalo Chicken Cheesesteak sandwhich in Universal City, TX - place was called Yous Guys freaking awesome! Hope everyone had a fantastic weekend!
    +1
  • The Helper The Helper:
    Happy Tuesday!
  • The Helper The Helper:
    We have been getting crazy numbers reported by the forum of people online the bots are going crazy on us I think it is AI training bots going at it at least that is what it looks like to me.
  • The Helper The Helper:
    Most legit traffic is tracked on multiple Analytics and we have Cloud Flare setup to block a ton of stuff but still there is large amount of bots that seem to escape detection and show up in the user list of the forum. I have been watching this bullshit for a year and still cannot figure it out it is drving me crazy lol.
    +1
  • Ghan Ghan:
    Beep boop
    +1
  • The Helper The Helper:
    hears robot sounds while 250 bots are on the forum lol
  • The Helper The Helper:
    Happy Saturday!
    +1
  • The Helper The Helper:
    and then it was Thursday...
    +2
  • tom_mai78101 tom_mai78101:
    And then Monday
    +1
  • The Helper The Helper:
    I got the day off today!
    +1
  • tom_mai78101 tom_mai78101:
    How...? (T-T)
  • The Helper The Helper:
    I took the day off. I work for myself so I can do that.
    +1
  • Varine Varine:
    Well I'm already over summer
  • jonas jonas:
    varine! good to see you
  • jonas jonas:
    what's going on, what's got you going
  • The Helper The Helper:
    good to see you varine hope you are well my friend

    The Helper Discord

    Members online

    No members online now.

    Affiliates

    Hive Workshop NUON Dome World Editor Tutorials

    Network Sponsors

    Apex Steel Pipe - Buys and sells Steel Pipe.
    Top