I can copy you one of my spells, i know it isn't very simple but he has everything you may want to know about vJASS :
JASS:
scope Shreding initializer Init
//==========================================================================
//=============================SETUP========================================
//==========================================================================
globals
private constant integer SPELL_ID = 'B000'
private constant real perte = 0.9 //La vie sera multipliée par ce nombre
private constant string model = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl"
endglobals
private function Targ takes unit targ returns boolean
return (GetWidgetLife( targ ) > 0.405 ) and ( IsUnitType( targ, UNIT_TYPE_MAGIC_IMMUNE ) == false ) and ( IsUnitAlly( targ, GetOwningPlayer( GetSpellAbilityUnit() ) ) == false )
endfunction
private function Range takes integer level returns integer
return 400 + 10 * level
endfunction
private function Damage takes integer level returns integer
return 75 * level
endfunction
private function Armor takes integer level returns integer
return 3*level
endfunction
private function MoveSpeed takes integer level returns real
return I2R( 10 + 5 * level )
endfunction
private function AttackSpeed takes integer level returns integer
return 10 + 5 * level
endfunction
//==========================================================================
//=============================END SETUP====================================
//==========================================================================
globals
group g
boolexpr b
endglobals
private function Pick takes nothing returns boolean
return Targ( GetFilterUnit() )
endfunction
private function Cond takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer level
local real x
local real y
local unit f
if ( GetSpellAbilityId() == SPELL_ID ) then
set level = GetUnitAbilityUnit( u, SPELL_ID )
set x = GetUnitX( u )
set y = GetUnitY( u )
call GroupEnumUnitsInRange( g, x, y, Range( level ), b )
loop
set f = FirstOfGroup( g )
exitwhen ( f == null )
call GroupRemoveUnit( g, f )
call UnitDamageTarget( u, f, Damage( level ), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null )
call Debuff.UnitAddDoubleSlowReducArmor( f, 6, MoveSpeed( level ), AttackSpeed( level ), Armor( level ) )
endloop
call SetWidgetLife( u, GetWidgetLife( u ) * perte )
call DestroyEffect( AddSpecialEffect( model, x, y ) )
endif
set u = null
return false
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger Shreding = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( Shreding, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( Shreding, Condition( function Cond ) )
//Set globals
set g = CreateGroup()
set b = Condition( function Pick )
//Preloading effect
call Preload( model )
//Preloading ability
set bj_lastCreatedUnit = CreateUnit( Player(15), dummy, 0, 0, 0 )
call UnitAddAbility( bj_lastCreatedUnit, SPELL_ID )
call KillUnit( bj_lastCreatedUnit )
set Shreding = null
endfunction
endscope
This spell is like a Thunder Clap that reduces armor added to the slows. Beside the caster got his life multiplier by the variable "perte" meaning ~ "lost" in english.
Ok first it's JESP because i made a setup at the begginning, that means i can change the values of the spell without going further in the code.
In this setup there is two parts : the globals and the functions.
The globals are the spell id inside the object editor, a life multiplier factor ( french inside sorry xD ), and the path of the model i will use.
Then i set the area of effect around the caster, the damage the ennemies will take, the armor they will loose, the movement speed they will loose ( in percentage ), the attack speed they will loose ( in percentage ).
It's a bit difficult because i made a custom debuff system that handles those debuff that's why it is a bit disturbing.
Just take a look at the other globals block after the setup, those globals won't be change by the user. They're a part of the code.
Ok now let's take a look about the last part XD !
The Init Part, i create a local trigger var that i use for everything. I add the event, the condition. Oh yes another disturbing thing, I'm trying to not use action block since you can do everything in one single block ( and there is another technical reason i forgot ^^ ).
I set the globals g and b.
I preload the effect and the abilities to prevent lags.
Now let's take a look at the condition function. First i declare some locals, I need the caster, his coordinates, the level of the ability for the unit and a tampon unit for the FirstOfGroup method.
Then i check the Spell_ID of the spell being casted.
Then i set some vars. I pick every units that are in range with the boolexpr condition.
Then i create loop with the FirstOfGroup method to damage everyone and to apply the debuff to everyone.
At the end of the loop I set the life of the caster to his life * the multiplier and at last I create the beautiful effect
At last don't forget to clean leaks
Ok I made this quite fast so if you have any questions go ahead.