System Casting time spell system

W!†A_cRaft

Ultra Cool Member
Reaction score
28
A LITTLE BIT OF HISTORY:
I have been searching for a similar system everywhere for quite some time, maybe I just FAIL at searching but I could't find one, there were many systems
that handle channeling abilities and even have casting bars (which i personally don't like since they look ugly) but still haven't seen a single one that covers the CASTING of spells with a delayed effect, but making it so that it can be
stopped like any channeling spell can (stun, move, death etc).

Basically because it cannot be done in a non-Jass version (or at least i don't know how to do it) since the editor cannot get the "Target" of the ability on the even "Unit finishes casting an ability", since the ability is already finished and it's effect should now be triggered but the target is lost so you have to use global variables to store everything, and that makes it a non-MUI, and well we want to avoid that.

==========================================================================================

What to expect?
Expect castable spells that are affected by the things mentioned below.

What do I mean when I say castable spells?

Spells that have a certain casting time, but not a classic casting time that the world editor allows us to set. Rather a more complex casting.

World editor allows us to make a "casting" that delays the execution of the ability in both cooldown and mana, and if stunned during the "casting" they can be recast again with no lose whatsoever, these spells however cannot.


==========================================================================================

They can be:

interrupted - can be interrupted by moving, getting stunned, dying, etc.

line of sight avoided - can avoided if the caster loses the target out of his sight during the casting of the ability, either by really fast movement, or jump/blink triggers behind the caster, or even sideways. Yes, caster is slowly following the target's movement by his facing.

invisibility avoided - If the target turns invisible the spell is interrupted.

out of range avoided - If the target moves away from the ability range, the spell is interrupted. It is also possible to configure how much out of range is allowed to still make the cast.

delayed by direct damage - if you are either attacked or damaged directly (by a spell or physical ability) your casting progress is reduced, in other words it will take longer for a spell to go into the effect. Requires pre-configuring for every spell.

casting progress hastened and slowed by buffs - Allows the buffs that increase/decrease the speed at which abilities are being cast, for example bloodlust that increases casting speed, or slow that decreases it.

========================================
KEEP IN MIND
========================================
The whole system is unit target based, if you want a point targeted spell you can either modify the code to be point oriented, or use only some part of the trigger because the "point target" cannot run away (so out of range is needless), cannot go behind your back (line of sight is needless), cannot go invisible (so visibility is needless), so all the these things should be canceled in that specific trigger, which leaves us with only hasting/slowing of cast progress (which is not target oriented) and spellcast delaying which is again not target oriented.

In other words deleting the parts of the code and making the spell point castable will make the code work.

==========================================================================================

ABOUT THE CODE

The whole system was made by me assisted greatly by my brother.
Code itself is a little bit of complex, I would recommend that you know at least the basic of any programming language if you want to make it work.

Whole code however is in a single trigger, except the delayed attack, but they work on their own so it is still MUI.

Also I would like to say that this is the first thing we've done in JASS so you shouldn't expect it to be really great, however there is no similar system currently anywhere so I thought we could share it with the community of TheHelper.net

Used Vexorian's Handle Variables Functions which i edited in order for them to be compatible with 1.24 (god i hate that patch)

Special thanks to
Exide - for helping me be able to start my WC3 again...
Ivach - for help around Order strings
Rainther - for pointing out what my wc3 problem is, and for helping me understand how do Game - Text Messages work in Jass (testing would be impossible without these)
Komaqtion - for effort :p (he tried understanding my angle problem, I apparently didnt describe it well enough)


Here is the code for trigger #1

One thing you should know before going further, as explained below, the system works by giving you a base trigger code for your spell that you should put in your trigger,
since you cannot have 2 triggers of the same name you will be forced to change certain parts of the code (function names to be PRECISE) in order for it to work on different spells, beacuse there can only be 1 function with a same name.

I have solved my problem by adding a tag such as _001, _002, _003 to every function in the trigger

Also dont forget to change the fields of the 2 lowest functions in order to match your trigger:
the
JASS:
function Trig_spell_Conditions takes nothing returns boolean

change the name here.(check the
Code:
)

and 
[jass]function InitTrig_Casting_Spell takes nothing returns nothing
    set gg_trg_Casting_Spell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Casting_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Casting_Spell, Condition( function Trig_spell_Conditions ) )
    call TriggerAddAction( gg_trg_Casting_Spell, function Casting )
endfunction[/jass]

I dont know does this happen on its own when pasting the code, when copy-pasting the trigger these changes are done automatically
[code]
in this part you must change "Casting_Spell" to your trigger name
and Trig-spell_Conditions to the name you set in the previous part, your condition function


JASS:
//*                 The map itself contains a detailed description of every single function
//*                 every constant and everything that you should/could change.
//*                 -----------------------------------------------------------------------
//*                         =================================================
//*                                     >>>>>>KEEP IN MIND<<<<<<
//*                         =================================================
//*                         For every castable spell you make, you must make 
//*                         a new trigger that is an exact copy of this one
//*                         (casting spell) and than in the field desinged 
//*                         for it make your actual spell, think of this as a
//*                         background mechanic for your spell, there is a 
//*                         place where you should make your spell and all of
//*                         it's effect, described lower
//*
//*                         ALSO, do not forget, you spell should be based 
//*                         on channel, and have follow throught time set to
//*                         99999 to make it infinite, also it must not prevent
//*                         other abilities from beign used. if you make a NON
//*                         unti target spell make sure to change the trigger,
//*                         in order to not get errors.
//*                         =================================================
//*                         =================================================
//*
//* How to implement:
//*     1. Copy-Paste the code from the map header (spell system.w3x) to your map header
//*     2. Create an empty trigger named Casting Spell, select it, and do Edit - > Convert to Custom Text
//*     3. Copy the Code from below into the trigger
//*     4. Create another empty trigger named Attack Delay, select it, and do Edit - > Convert to Custom Text
//*     5. Copy the code from the next 
	
	


<div class="bbCodeBlock bbCodeBlock--screenLimited bbCodeBlock--code">
	<div class="bbCodeBlock-title">
		Code:
	</div>
	<div class="bbCodeBlock-content" dir="ltr">
		<pre class="bbCodeCode" dir="ltr" data-xf-init="code-block" data-lang=""><code> bracket in this thread.
//*     6. Enjoy your castable spells
//*
//*
//*
//*
//*==========================
//* Changeable Data Functions:
//*==========================
//*
//*          function sightrange takes nothing returns real
//*range of an angle which the Line of Sight will use (recommended: 60)
//*
//*          function rawcode takes nothing returns integer
//*Replace Bblo with the Rawcode of your buff, in my case it is suppose to increase casting speed by 100%
//*
//*          function castrateset takes nothing returns real
//*Rate at which the casting progress builds up, rate is 1 for every 0.1 seconds, this is used in order to allow multiplication of the casting speed
//*
//*          function extendedrange takes nothing returns real
//*Extended range after which the casting will be interrupted, modifi in order to determin to what extreme will the casting be allowed
//*
//*          function castduration takes nothing returns real
//*Casting duration, or in other words how many tics will be needed in order for spel lto be completed, default rate is 1 per 0.1 second cast
//*
//*          function castinterrupting takes nothing returns real
//*When a target casting an ability is hit by this spell his casting progress will be reduced by 20 points, or 2 seconds (@rate 1 per 0.1 sec)
//*
//*         function spellid takes nothing returns integer
//*Replace the A000 with the Rawcode of your spell.
//*
//*         function orderchecker takes nothing returns string
//*Used to determin what Spell Order Id is the game using, replace the &quot;curse&quot; with the Spell Id order your spell uses
//*
//===========================================================================


//#######################################
//---------------------------------------
//&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; TRIGGER CODE&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
//---------------------------------------
//#######################################

function sightrange takes nothing returns real
    return 60.00                                                 
endfunction

function rawcode takes nothing returns integer
    return &#039;Bblo&#039;                                               
endfunction

function spellid takes nothing returns integer
    return &#039;A000&#039;
endfunction

function orderchecker takes nothing returns string
    return &quot;curse&quot;
endfunction

function castrateset takes nothing returns real
    return 1.00                                                 
endfunction

function extendedrange takes nothing returns real
    return 900.00                                               
endfunction

function castduration takes nothing returns real
    return 25.00                                                
endfunction

function castinterrupting takes nothing returns real
    return 20.00                                                
endfunction

function CheckOrderCast takes unit u returns boolean
    if ( not ( GetUnitCurrentOrder(u) == String2OrderIdBJ(orderchecker()) ) ) then     
        return false
    endif
    return true
endfunction

function LoS takes unit u, real angbp, real ang returns nothing
    local real a
    local real b
    set a = ang + sightrange()
    set b = ang - sightrange()
    if(GetBooleanAnd((ang&gt;=sightrange()),(ang&lt;=(360-sightrange()))))then
        if(GetBooleanAnd((angbp&gt;=b),(angbp&lt;=a)))then
        else
            call IssueImmediateOrder(u, &quot;stop&quot;)
        endif
    else
        if(a &gt; 360)then
            set a = a - 360
            if(GetBooleanOr(GetBooleanAnd((angbp&lt;=a),(angbp&gt;=0)),GetBooleanAnd((angbp&gt;=b),(angbp&lt;=360))))then
            else
                call IssueImmediateOrder(u, &quot;stop&quot;)
            endif
        else
        endif

        if(b &lt; 0) then
            set b = b + 360
            if(GetBooleanOr(GetBooleanAnd((angbp&gt;=b),(angbp&lt;=360)),GetBooleanAnd((angbp&gt;=0),(angbp&lt;=a))))then
            else
                call IssueImmediateOrder(u, &quot;stop&quot;)
            endif
        else    
        endif
    endif
endfunction

function BuffCheck takes unit u returns boolean
    if ( not ( UnitHasBuffBJ(u, rawcode) == true ) ) then                        
        return false
    endif
    return true
endfunction

function visibility takes unit u, unit t returns boolean
    if ( not ( IsUnitInvisible(t, GetOwningPlayer(u)) == true ) ) then
        return false
    endif
    return true
endfunction
    
function CastingCheck takes nothing returns nothing
local timer cast = GetExpiredTimer()
local unit u = H2U(GetHandleHandle(cast, &quot;u&quot;))      
local unit t = H2U(GetHandleHandle(cast, &quot;t&quot;))
                                                    
local real r = GetHandleReal(u, &quot;r&quot;)                
local real tr = GetHandleReal(t, &quot;r&quot;)               
local effect fx
local real castrate
local real distance = DistanceBetweenPoints(GetUnitLoc(u),GetUnitLoc(t))
local real angle = GetUnitFacing(u)                 
local real angbp = AngleBetweenPoints(GetUnitLoc(u),GetUnitLoc(t))
set castrate = castrateset()
if (angbp &lt; 0) then
    set angbp = angbp + 360
else
endif


call SetUnitFacingToFaceUnitTimed(u,t, 0.19)        

if ( r &lt; 0 ) then                                   
    set r = 0
else
endif

call LoS(u, angbp, angle)


if (distance &gt;= extendedrange())then                 
    call IssueImmediateOrderBJ(u, &quot;stop&quot;)           
else
endif

if (visibility(u,t))then                            
    call IssueImmediateOrderBJ(u, &quot;stop&quot;)           
else
endif
//------------------------------------------------------------------------------------------------------------------------
//For every specific buff that interferes with casting speed you must make a seperate if/then/else check           
//----------            if (BuffCheck(u))then                           
//----------                set castrate = castrate * 2                                                                           
//----------            else
//----------            endif
//------------------------------------------------------------------------------------------------------------------------

if ( CheckOrderCast(u) ) then                       
    if (BuffCheck(u))then                           
        set castrate = castrate * 2                 
                                                    
    else
    endif
    set r = r + castrate                            

    call SetHandleReal(u, &quot;r&quot;, r)                   
        if ( r &gt;= castduration()) then              
            set fx = AddSpecialEffectTargetUnitBJ( &quot;overhead&quot;, t, &quot;Abilities\\Spells\\Human\\DispelMagic\\DispelMagicTarget.mdl&quot; )

            //-------------------------------------------------------------------
            //You can here add the next few lines of code in order to make this spell reduce the cast of spell casted by it&#039;s target.
            //-------------------------------------------------------------------
            if (tr == 0) then  
            else
                set tr = tr - castinterrupting()                                    
                call SetHandleReal(t,&quot;r&quot;, tr)
            endif
            
            //=======================================================
            //           THIS IS WHERE YOUR SPELLCODE GOES          //
            //=======================================================
            // keep in mind that in this spellsystem I only passed
            // the target and the caster throught the timer/cache
            // if you (and i know you do) need any other data, such
            // as spell level, damage, mana, hp, or anything else
            // you must modify the passing function below
            //========================================================
            
            call IssueImmediateOrderBJ(u, &quot;stop&quot;)
            call DestroyEffect(fx)
            call PauseTimer(cast)
            call FlushHandleLocals(cast)
            call FlushHandleLocals(u)
            call DestroyTimer(cast)
            set u = null
        else
        endif
else
    call PauseTimer(cast)
    call FlushHandleLocals(cast)
    call FlushHandleLocals(u)
    call DestroyTimer(cast)
    set u = null
endif
endfunction

function Casting takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local unit t = GetSpellTargetUnit()
local timer cast = CreateTimer()

//==========================================//
// PASSING FUNCTION, or rather par of it    //
// pass everything you need for your spell  //
// in the similar way the I passed the units//
//==========================================//

call SetHandleHandle(cast, &quot;u&quot;, u)
call SetHandleHandle(cast, &quot;t&quot;, t)
call SetUnitFacingToFaceUnitTimed(u,t, 0.1)
call TimerStart(cast, 0.1, true, function CastingCheck)
endfunction

//---------------------------------------------------------------------------

function Trig_spell_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == spellid() ) ) then
        return false
    endif
    return true
endfunction

//===========================================================================
function InitTrig_codepasting takes nothing returns nothing
    set gg_trg_codepasting = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_codepasting, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_codepasting, Condition( function Trig_spell_Conditions ) )
    call TriggerAddAction( gg_trg_codepasting, function Casting )
endfunction

[/JASS][/spoiler]

[B][SIZE=&quot;4&quot;]Here is the code for trigger #2:[/SIZE][/B]

[spoiler][JASS]function AttackDelay takes nothing returns nothing
    local unit u = GetAttackedUnitBJ()
    local real r = GetHandleReal(u, &quot;r&quot;)
    if (not(r == 0)) then                           //checks if the target is CURRENTLY casting a spell
        set r = r - 5                               //reduces the casting progress by 0.5 seconds (rate is 1 for every 0.1 sec)
        call SetHandleReal(u, &quot;r&quot;, r)               //stores the modified value of the progress real
    else
    endif
endfunction

//Keep in mind that you can also make the abilities reduce the casting progress in the same way
//===========================================================================
function InitTrig_Attack_delay takes nothing returns nothing
    set gg_trg_Attack_delay = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Attack_delay, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddAction( gg_trg_Attack_delay, function AttackDelay )
endfunction
[/JASS][/spoiler]

[B][SIZE=&quot;4&quot;]Map Header[/SIZE][/B]
Vexorian&#039;s Variables Handles, modified by me in order to be compatible with 1.24 patch
[spoiler][JASS]//************************************************************************************************** 
//* 
//* Handle Variables Functions by Vexorian (http://jass.sourceforge.net/doc/) 
//* 
//* ------------------------------- 
//* Enables usage of game cache for 
//* transphering local variables 
//* beetveen functions. 
//* ------------------------------- 
//* 
//* Requires: 
//* ¯¯¯¯¯¯¯¯¯ 
//* A global variable with name &quot;cache&quot; and type &quot;GameCache&quot; as an exact match 
//* note that the &quot;LocalVars&quot; function must be placed before anything in this 
//* map header expect this kind of comments 
//************************************************************************************************** 
//
//* --------------------------------
//*
//* Edited by W!tA_cRaft &amp; Noemis in order to be compatiable with 1.24 patch
//*
//* Thanks to the community of TheHelper.net for help on how to edit the code
//*
//* --------------------------------


function LocalVars takes nothing returns gamecache
 if udg_cache==null then
  set udg_cache=InitGameCache(&quot;cache&quot;)
 endif
 return udg_cache
endfunction

function H2I takes handle h returns integer
 return GetHandleId(h)
endfunction

function H2U takes handle h returns unit
 return h
 call DoNothing()
 return null
endfunction

function SetHandleInt takes handle subject, string name, integer value returns nothing
 if value==0 then
  call FlushStoredInteger(LocalVars(),I2S(GetHandleId(subject)),name)
 else
  call StoreInteger(LocalVars(), I2S(GetHandleId(subject)), name, value)
 endif
endfunction

function SetHandleReal takes handle subject, string name, real value returns nothing
 if value==0 then
  call FlushStoredReal(LocalVars(), I2S(GetHandleId(subject)), name)
 else
  call StoreReal(LocalVars(), I2S(GetHandleId(subject)), name, value)
 endif
endfunction

function SetHandleHandle takes handle subject, string name, handle value returns nothing
 call SetHandleInt( subject, name, GetHandleId(value) )
endfunction

function GetHandleInt takes handle subject, string name returns integer
 return GetStoredInteger(LocalVars(), I2S(GetHandleId(subject)), name)
endfunction

function GetHandleReal takes handle subject, string name returns real
 return GetStoredReal(LocalVars(), I2S(GetHandleId(subject)), name)
endfunction

function GetHandleHandle takes handle subject, string name returns handle
 return GetStoredInteger(LocalVars(), I2S(GetHandleId(subject)), name)
 call DoNothing()
 return null
endfunction

function FlushHandleLocals takes handle subject returns nothing
 call FlushStoredMission(LocalVars(), I2S(GetHandleId(subject)) )
endfunction[/JASS][/spoiler]


If people want me to I can modify the map so that it covers the AOE spells as well (but it is just going to come down to deleting few functions and that is it)

==============
[I][B]Changelog[/B][/I]
==============
[B]Map Corrections made and map reuploaded 19th August, 2009 @ 11:37 AM (GMT+1)[/B]
[B]Fixed a minor bug with buff not being detected thus not hasting casting, reuploaded 19th August, 2009 @6:38 PM (GMT+1)[/B]
[B]Optimized the code a little bit and fixed a bug that prevents you next if it cancled the casting, reuploaded 20th August, 2009 @11:25 AM (GMT+1)[/B]</code></pre>
	</div>
</div>
 

Attachments

  • spell system.w3x
    39.7 KB · Views: 238

W!†A_cRaft

Ultra Cool Member
Reaction score
28
might someone explain what should the "code" contain?
Only the copy paste from my trigger or something else?
(my first posting here, and well...there aren't any rules, guidelines that say anything about that, or at least i haven't found any)
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Omg, gamecache + unsafe type casting + unoptimized code..

Wish you good luck...
 

W!†A_cRaft

Ultra Cool Member
Reaction score
28
Omg my 1st thing ever in jass....
+ i dont know what is unsafe?

EDIT: unless someone actually tells me what is wrong and what should i fix, this will basically get forgotten, sooo...
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
i suggest get some better jass knoledge before you release any thing in jass.
 

Azlier

Old World Ghost
Reaction score
461
First, KaTTaNa(sp?) made the local handle variables. Vexorian made the 1.24 compatible one, found at WC3C. Your version will not work with patch 1.24.

The DoNothing trick won't work anymore, last I heard.

You shouldn't use LHV anyways.

Second, learn vJass. You need to name the system trigger "codepasting" for it to work, and that's just annoying. Otherwise, you're asking the user to modify the code. Not a good idea. Also, you don't need two different triggers.

There are so many optimizations that can be done here...

JASS:
function castrateset takes nothing returns real

...Err...
 

Jesus4Lyf

Good Idea™
Reaction score
397
Basically because it cannot be done in a non-Jass version (or at least i don't know how to do it) since the editor cannot get the "Target" of the ability on the even "Unit finishes casting an ability", since the ability is already finished and it's effect should now be triggered but the target is lost so you have to use global variables to store everything, and that makes it a non-MUI, and well we want to avoid that.
I disagree.
JASS:
struct Casting extends array
    unit target
    private static method AIDS_onInit takes nothing returns nothing
        local trigger t=CreateTrigger()
        call TriggerAddCondition(t,Condition(function thistype.onCast))
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        set t=null // So sue me.
    endmethod
    //! runtextmacro AIDS()
    private static method onCast takes nothing returns boolean
        set Casting[GetSpellAbilityUnit()].target=GetSpellTargetUnit()
        return false
    endmethod
endstruct
function GetTargettedUnit takes nothing returns unit
    return Casting[GetSpellAbilityUnit()].target
endfunction

Hey look, I used a global array and one trigger to accomplish a get target function that can be used in finished casting events... (Fully MUI, efficient, lagless, leakless, whatever other crappy terms you have to mean "actually works" and is also H2I free, works patch 1.23, 1.24, whatever.)

Requires AIDS.
compatible with 1.24 (god i hate that patch)
So sue me twice. :p
 

Romek

Super Moderator
Reaction score
964
> I used a global array and one trigger...
...And a system which basically does all that for you! :p
 

W!†A_cRaft

Ultra Cool Member
Reaction score
28
Triple Post!

First, KaTTaNa(sp?) made the local handle variables. Vexorian made the 1.24 compatible one, found at WC3C. Your version will not work with patch 1.24.

The DoNothing trick won't work anymore, last I heard.

You shouldn't use LHV anyways.

Second, learn vJass. You need to name the system trigger "codepasting" for it to work, and that's just annoying. Otherwise, you're asking the user to modify the code. Not a good idea. Also, you don't need two different triggers.

There are so many optimizations that can be done here...

JASS:
function castrateset takes nothing returns real

...Err...


Vexorian's Variables that I had didn't work for 1.24....
I had to remake certain things as said in the tutorial HERE

And yes they DO WORK....how come you say they won't work when I hereby have them in my map and they are working?

about modifying the code....it is not possible to detect the ability stats such as Follow Through Time (from the channel), thus every ability has to have it's own trigger in order for it to have separate "casting duration" or they can all be registered within a single trigger, with their code and duration, but that would mean that the user has to modify the code anyway, in order to make them work separatlly

problem is there is just too much data that is related to the ability, even when the ability itself does NOTHING there are still a lot of parametars such as:

casting time, casting progress, line of sight (made from 2 separate parametars), visibility checker, interruption checker, range checker

and ability still doesn't do ANYTHING.

This whole code provides a background for the ability to function like a castable spell, and since all these parameters can differ for every ability the mapmaker makes they have to be separated.

Now since you have to make multiple triggers for multiple abilities anyway, you don't go putting all abilities you are making in your map into a single trigger, you make a trigger separatlly for each one, picture this code as YOUR trigger foundation (the background of your spell) and begin making your spell effect just as you would if the spell was to be instant cast in the sector meant for it.

Since you are making a trigger for every spell you make, simply copy the trigger that i made and make your spell in it:

BUT wait, you cant have 2 functions of the same name, which is WHY you must modify the code,
there is no way to go around the function names, and since you must copy the trigger multiple times you must modify the code anyhow, i clearly stated it in the writting I've done in the "trigger #1 section"

I wish that people would actually read what I wrote before posting a comment. And actually try the map before saying it doesn't work....

About optimizations you are totally correct, but I do not know how/what should I do.....I am a freaking beginner and 90% of the things people say is like an alien language to me, seriously how do you expect me to optimize something when i don't know what should be optimized, or how for that matter...

I am willing to do it, but i do not know what should I do....
As I said I made this thing for ME, because I needed it and it is working perfectly and is MUI, maybe it is not optimized, but anyone who knows what needs to be optimized here surely knows how to do it, and if he wants to go around being all "OHHH IM SOO BETTER, and go l2jass before coming here", well I guess he doesn't need this code anyways,

I wanted to help people that have little understanding in JASS, but still need to make their spells behave like I described earlier, not to show off some amazing JASS skill, I just wanted to share it with the community here...

About
JASS:
function castrateset takes nothing returns real


I do not know what those ... mean since the function is working as it should...

Just try the map before flaming me for something not working

Posting a brief explenation on how people should picture this

I disagree.
JASS:
struct Casting extends array
    unit target
    private static method AIDS_onInit takes nothing returns nothing
        local trigger t=CreateTrigger()
        call TriggerAddCondition(t,Condition(function thistype.onCast))
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        set t=null // So sue me.
    endmethod
    //! runtextmacro AIDS()
    private static method onCast takes nothing returns boolean
        set Casting[GetSpellAbilityUnit()].target=GetSpellTargetUnit()
        return false
    endmethod
endstruct
function GetTargettedUnit takes nothing returns unit
    return Casting[GetSpellAbilityUnit()].target
endfunction

Hey look, I used a global array and one trigger to accomplish a get target function that can be used in finished casting events... (Fully MUI, efficient, lagless, leakless, whatever other crappy terms you have to mean "actually works" and is also H2I free, works patch 1.23, 1.24, whatever.)

Requires AIDS.
So sue me twice. :p

Basically because it cannot be done in a non-Jass version (or at least i don't know how to do it)

Maybe so, but I've added line of sight/out of range extending/visibility ending/time increasing on taking damage to the system....

Brief Explenation
on how people should picture this system

Since people either haven't read what I wrote or they didn't understand my point here is a brief explenation of few things I should point out.

1. First of all this isn't a classical system so to say, systems usually consist of 1 trigger which you paste into your map and it modifies the whole aspect of how certain things function in it.
Implementing this code however doesn't consists of just pasting it once.

I was not sure if "system" is a right way to call this but it was more appropriate than any other category....

2. How is it meant to work?

It was designed with a different idea than most systems....
It was designed to provide a base, a structural foundation a frame for a spell you want to make.

For example, if you want to make a certain JASS spell usually you would
make it an instant cast spell and start working on your code instantly,
when using this system you DON'T do that....

When using this system you are required to base your spell of channel,
which you would have done anyway, since you want a casting spell
with a delayed effect so you have to make a dummy spell to do the effect
or make the effect VIA triggers
So
When using this system you copy-paste the trigger I've given you,
it provides the wc3 with a spellcasting system that is able to detect
the line of sight, extended range, visibility and even increase your casting
time when you are hit by direct damage (either attack, or with a spell
(if that spell is defined to do so via triggers ofc)
Now once you pasted the BASE trigger code for your spell you can begin
your work in the SECTION of the CODE I have made for your spell's effect,
same as you would work in ANY empty trigger, not paying attention to any
functions I've made.
If I knew a way to make them invisible I would, than you would have to
modify only the sector you would have done ANYWAY if you were to make a JASS instant cast spell....

I don't know how much sense this makes but i will try to set an example:

1. Jass Instant cast spell
Fireball, mana cost, cooldown, range, deals damage to all units it passes through while traveling to the target unit,
Basically done with a unit that is driven by a slide trigger to the target until they meet resulting in an explosion that deals dmg. The unit has permanent immolation or something and you are done.

2. Castable Jass spell
Fireball, mana cost, cooldown(or not, since it is castable your abilities can also be without cooldown and there wont be spamming), range, deals damage to all unit it passes through while traveling towards the target unit, same as the spell above.

so what is the difference?

Basically you need to set few parameters within the code I've given you
such as Casting Time, Spell ID, Spell Order ID, and Spell Extended Range
(if you want it to be limited, otherwise set it to 99999 in all triggers of this
type)
. These 4 parameters are different for each ability you make, while
the others MAY or MAY not be different, depends on what you wish to do,
I've intentionally left them out of the Map Header to make the system more
customizable...

now when you have made these 4 changes you can begin to make your ability, in the section of the code I marked, SAME way you would have made it without my code being there at all.....
Since the code does ALL of it's doing before the ability goes into the effect, and you are there to handle the stuff that happens AFTER the ability goes into the effect, code doesn't cover that part, it is a CASTING CODE, not the effect code.

So basically after editing those 4 parameters you are just suppose to make a standard fireball that you would have done as an instant cast in the previous example and you are done.

Fully enhanced castable fireball with all the benifits of the system.

I also want to explain what I mean by extended range, since people apparently do not understand that part.

When you make an ability in wc3, and under the ability properties you set "Casting Time" to be a certain period, that is ABSOLUTELY not the same to what I am doing here.....

Casting time as we all know doesn't actually cast the ability until it is done, thus it doesn't spend mana and doesn't start the cooldown, also if the gets out of range you will start chasing him in order to cast the ability again.

What I mean by extended range is this:
When you start casting an ability with this system in your map, you WILL cast it, you WILL spend mana, and start the cooldown, but by standard wc3 options lets say your casting time is 5 seconds, the enemy can be FAR FAR away by the time you finish, by standard wc3 mechanic you will still stand still and "channel" your ability, extended range stops that from happening and will interrupt you once the target leaves it.


Now:
Since the system provides a FRAME/FOUNDATION/BASE of every castable ability trigger you are JASS-ing it impossible to make it a Non-modification required system, why? because of the function names, they cannot be the same and since you must make a new copy of the trigger each and every time you make a new JASS-ed Castable Spell that means you must have multiple copies of this code and that means you must edit the function names in it.
I am doing it with name tags as I said before, and it is not really hard, specially since it doesn't require much work to edit cupple of lines of text and in return i get a fully enhanced spell system

EDIT: sorry for double post, took me long to write this and i didnt realise i was writting a replay rather than an EDIT
 

Jesus4Lyf

Good Idea™
Reaction score
397
T-T-Triple Post!

You need to get familiar with JASS as we know it. That means learning structs (essential) and hence, vJass (structs are a part of it).

You are unlikely to produce any reasonably efficient code without it.

It is probably best if you post in JASS help, rather than resource submission, until your familiarity with modern JASS increases. :)
 

W!†A_cRaft

Ultra Cool Member
Reaction score
28
rofl,

well said sorry, not sure is there a way to merge them?

they were posted within a different period of time since it takes me some time to write that amounts of text

EDIT:

I agree, moderators may move the thread, but JASS help section is for someone who needs help with something, the system works, i dont need help with it, sure it isnt very modern, sure it may be done in different ways, well that is the joy of programming, more ways to do a single thing and they are all correct, only some are better and more effective, I am sorry i cannot do better than this, not with this knowledge i have, and with the attitude people have here it is really hard to learn/improve what you know, since everyone is flaming about how something isn't good without correcting the mistake, and it can get really hard on the people trying to understand the very basics....

keep in mind for someone who doesn't know ANY programming language, understanding JASS is not quite the fairytale and specially understanding the complexity of it all when mixed with so much preasure put by the people that just keep saying
"it is bad"
"not good"
"fail"
etc...

without actually trying to point what should be fixed....
 

W!†A_cRaft

Ultra Cool Member
Reaction score
28
I am using New Gen.... maybe I am not using it's functions but that is mostly because I don't know any difference or which functions it offers me for that matter, i use what i can :p

thanks for the other link though, going to read it now
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • 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

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top