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
964
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.
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top