Warcraft III :: Weuhzor

Warcraft III

Sort poison avec GC (Jass)

Introduction

Cet article va vous expliquer comment raliser un simple sort de poison en utilisant le "rustinage" au Gamecache. Dans cet article vous apprendrez manipuler le gamecache au travers d'un compteur temps, ce qui se fait trs souvent.
Le sort sera un sort actif contre une unique cible ennemie, l'unit subira X points de dgts par seconde pendant Y secondes. Les dgts varieront selon le niveau du sort.

I- Pr-requis:

Lisez tout d'abord l'excellent tutorial de Bantas qui explique l'utilisation du GC.
Rustinage au Game cache par Bantas
Et cette liste de fonction copier dans le script personnalis de votre map si ce n'est pas dj fait.
Liste des fonctions du rustinage au GC (pas encore en ligne, version rtf tlcharger)

II- Le sort:

Utilisez un sort de base avec cible requise: prenez canaliser si vous savez utiliser ce sort sinon prenez le sort Bouclier de foudre. Retirez tout les effets de votre sort, par exemple si vous avez pris Bouclier de foudre retirez les dgts infligs aux units proches et modifiez l'effet d'clair par un effet de poison.
Il ne faut garder qu'un sort basique n'ayant aucun effet, appelez ce sort "Poison".

III- Le dclencheur GUI de base:

IV- Le dclencheur Jass:

A-Fonction Trig_Sort_Poison_Actions:

1) Les variables

Cette fonction est le point de dpart de notre sort. C'est ici que nous allons crer un compteur temps (timer) et y attach les donnes ncessaires pour le sort (cible, dgts, dure etc..)

Tout d'abord nous rcuprons les informations essentielles relatives au sort qui vient d'tre lanc:

local unit caster = GetSpellAbilityUnit()		// L'unit qui lance le sort
local unit target = GetSpellTargetUnit()		// L'unit ennemie cible par le sort
local integer lvl = GetUnitAbilityLevel( GetSpellAbilityUnit(), GetSpellAbilityId())	// Niveau du sort

Puis les informations complmentaires au sort que nous choisissons:

local real dmg = lvl * 15	// Points de dgts infligs par le sort chaque seconde
local real duree = 10.0		// Dure du sort en secondes

Enfin les informations ncessaires pour le droulement du sort et le stockage des donnes:

local timer t = CreateTimer()		// Le compteur temps pour le droulement du sort
local string m = I2S(H2I( t ))	// L'adresse de la variable du compteur temps pour le stockage des donnes

Premier aperu de ce vous devriez avoir pour cette fonction:

function Trig_Sort_Poison_Actions takes nothing returns nothing
local unit caster = GetSpellAbilityUnit()		// L'unit qui lance le sort
local unit target = GetSpellTargetUnit()		// L'unit ennemie cible par le sort
local integer lvl = GetUnitAbilityLevel( GetSpellAbilityUnit(), GetSpellAbilityId())	// Niveau du sort
local real dmg = lvl * 15	// Points de dgts infligs par le sort chaque seconde
local real duree = 10.0		// Dure du sort en secondes
local timer t = CreateTimer()		// Le compteur temps pour le droulement du sort
local string m = I2S(H2I( t ))	// L'adresse de la variable du compteur temps pour le stockage des donnes
endfunction

2) Le stockage des donnes dans le GC

Nous avons prcdemment rcuprer l'adresse du compteur temps dans la variable "m", cela va nous permettre de stocker les donnes dans le GC sous ce nom de dossier.

call StoreInteger( udg_GC, m, "caster", H2I(caster) )	// Le lanceur de sort, conversion d'unit  entier
call StoreInteger( udg_GC, m, "caster", H2I(target) )	// La cible du sort, conversion d'unit  entier
call StoreReal( udg_CG, m, "damage", dmg )		// Les dommages du sorts, stockage d'un rel
call StoreReal( udg_GC, m, "duree", duree )		// Dure du sort, cette dure sera dcrment  chaque itration (chaque seconde)

A partir de l il ne reste plus qu' lancer le compteur temps qui excutera une fonction chaque seconde, c'est dans cette fonction que seront inflig les dgts.

3) Lancement du compteur temps

La fonction pour lancer un compteur s'appelle TimerStart, elle se compose ainsi:

natives TimerStart takes timer whichTimer, real timeout, boolean periodic, code handlerFunc returns nothing
Paramtres d'entres: Dans notre cas:
call TimerStart( t, 1.0, true, function Poison )

Lance le compteur "t" qui expire au bout d'1 seconde et qui excute la fonction Poison. Le compteur se relance aprs expiration.

Au final, pour la fonction Trig_Sort_Poison_Action, vous obtenez ceci:

function Trig_Sort_Poison_Actions takes nothing returns nothing
local unit caster = GetSpellAbilityUnit()		// L'unit qui lance le sort
local unit target = GetSpellTargetUnit()		// L'unit ennemie cible par le sort
local integer lvl = GetUnitAbilityLevel( GetSpellAbilityUnit(), GetSpellAbilityId())	// Niveau du sort
local real dmg = lvl * 15	// Points de dgts infligs par le sort chaque seconde
local real duree = 10.0		// Dure du sort en secondes
local timer t = CreateTimer()		// Le compteur temps pour le droulement du sort
local string m = I2S(H2I( t ))	// L'adresse de la variable du compteur temps pour le stockage des donnes

call StoreInteger( udg_GC, m, "caster", H2I(caster) )	// Le lanceur de sort, conversion d'unit  entier
call StoreInteger( udg_GC, m, "caster", H2I(target) )	// La cible du sort, conversion d'unit  entier
call StoreReal( udg_CG, m, "damage", dmg )		// Les dommages du sorts, stockage d'un rel
call StoreReal( udg_GC, m, "duree", duree )		// Dure du sort, cette dure sera dcrment  chaque itration (chaque seconde)

call TimerStart( t, 1.0, true, function Poison )
endfunction

B- Fonction Poison:

1) Cration de la fonction

Cette fonction n'est pas initialement prsente dans le dclencheur, c'est l'intrieur de cette fonction que nous allons infliger les points de dgts l'unit cible chaque seconde.
Insrez la fonction Poison juste avant la fonction Trig_Sort_Poison_Actions, voil l'en-tte:

function Poison takes nothing returns nothing

endfunction

2) Variables

Dans un premier temps nous allons rcuprer toutes les valeurs qui sont stockes dans le gamecache sous l'identifiant du compteur temps.

local timer t = GetExpiredTimer()	//On rcupre le compteur qui a lanc la fonction
local string m = I2S(H2I(t))		// Identifiant unique du compteur
local unit caster = H2U( GetStoredInteger( udg_GC, m, "caster") )	// Rcupration du lanceur de sort
local unit target = H2U( GetStoredInteger( udg_GC, m, "target") )	// Rcupration de la cible du sort
local real dmg = GetStoredReal( udg_GC, m, "dmg") )			// Rcupration des dommages  infliger
local real duree = GetStoredReal( udg_GC, m, "duree") )		// Rcupration de la dure restante
Dsormais nous avons toutes les variables ncessaires notre sort.

3) Dommages et rduction de la dure restante

Cette partie reste trs simple, points de dgts infliger:

call UnitDamageTarget( caster, target, dmg, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)

Rduction de la dure:

set duree = duree - 1.0
call StoreReal( udg_GC, m, "duree", duree)

4) Fin du sort et destruction des donnes

Lorsque les Y secondes se sont coules -> variable "duree" infrieur ou gal 0.0 OU que la cible est morte, il est ncessaire de stopper le sort, dtruire le compteur et librer la mmoire utilise dans le GC.

if( duree <= 0.0 or IsUnitDeadBJ(target)) then
call FlushStoredMission(udg_GC, m)	// Libre la mmoire utilise par le gamecache
call DestroyTimer(t)			// Dtruit le compteur
endif

5) Nettoyage pour viter les petites fuites de mmoires

Avant le "endfunction" ajoutez ces quelques lignes:

set t = null
set caster = null
set target = null

Au final votre fonction "Poison" devrait ressembler ceci:

function Poison takes nothing returns nothing
local timer t = GetExpiredTimer()	//On rcupre le compteur qui a lanc la fonction
local string m = I2S(H2I(t))		// Identifiant unique du compteur
local unit caster = H2U( GetStoredInteger( udg_GC, m, "caster") )	// Rcupration du lanceur de sort
local unit target = H2U( GetStoredInteger( udg_GC, m, "target") )	// Rcupration de la cible du sort
local real dmg = GetStoredReal( udg_GC, m, "dmg") )			// Rcupration des dommages  infliger
local real duree = GetStoredReal( udg_GC, m, "duree") )		// Rcupration de la dure restante

call UnitDamageTarget( caster, target, dmg, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
set duree = duree - 1.0
call StoreReal( udg_GC, m, "duree", duree)

if( duree <= 0.0 or IsUnitDeadBJ(target)) then
call FlushStoredMission(udg_GC, m)	// Libre la mmoire utilise par le gamecache
call DestroyTimer(t)			// Dtruit le compteur
endif

set t = null
set caster = null
set target = null
endfunction

V-Conclusion:

Le sort est termin, il est extrmement basique, ce qui importe c'est la technique utilise. Vous pouvez dsormais exploiter cette technique pour raliser normment de sorts bien plus intressant. Bien que basique ce sort est multi-instanciable, facile raliser en JASS mais quasiment impossible en GUI.