Inscrit le: 09 Mar 2009 Messages: 1154 Sujets: 54 Spécialité en worldedit: Croâ ?
Posté le: 11/04/09 10:47 Sujet du message: Multi-Drain
Bonjour Comment faire pour créer un Drain de zone? Je pose cette question car si on utilise la technique des dummys, ce sont les dummys qui récupèreront la vie drainée et pas le héros qui a lancé le sort ! _________________
Ce qu'il faudrait faire, c'est utiliser un timer périodique et créer les effets de drains toi même, en updatant leur position régulièrement, et en appliquant toi même le transfert de vie.
Un peu tricky si tu débutes ou si tu ne fais pas de jass^^ _________________
Bêta Systems:70% Bêta Spells:13% Bêta Arts & graphics:70%
Inscrit le: 09 Mar 2009 Messages: 1154 Sujets: 54 Spécialité en worldedit: Croâ ?
Posté le: 11/04/09 13:54 Sujet du message:
=) Rien d'impossible en effet
C'est les vacances et j'ai 2 semaines pleines pour faire un petit sort =D donc je vais me le faire . Si j'y arrive pas je demanderais de l'aideuh ! _________________
Comme sort de base; il faut prendre un sort qui immobilise l'unité, sinon ça va foirer. Du genre étoiles filantes en réglant les dégâts à 0 et en modifiant le buff pour que cela ressemble à ce que tu veux.
En effet, dans ce que je te donne, il y a un deuxième déclencheur qui permet d'annuler le sort dès que l'unité se voit recevoir un ordre. (Le scope StopDrain).
Si tu ne connais pas encore le jass et le vjass, ne t'embête pas à essayer de comprendre mon code, je ne l'ai pas fait pour qu'il soit super lisible. Mais si tu as des questions, je suis là ,)
Tu créés un déclencheur vide, tu le convertis en texte personnalisé, tu supprimes son contenu, et tu le remplaces par le déclencheur.
Tu peux personnaliser les constantes (les "globals")
Secret:
Jass:
scope drainmultiple initializer init
//=================================================
globals
private constant real BoucleLightning = 0.02//intervalle entre chaque mouvement des lightnings
private constant real BoucleDrain = 1.00//intervalle entre chaque drain de vie
private constant string GraphEclair = "DRAL"//graphisme des éclairs, celui-ci est celui de base
private constant integer DUR1 = 500
private constant integer DUR2 = 10
private constant real AOE = 275.00//zone d'effet
private constant real DMG = 50.00 //Vie pompée à chaque intervalle BoucleDrain
private constant integer IDSort = 'A000' //L'id du sort lancé
endglobals
//=================================================
private function filter takes nothing returns boolean
//Filtre les unités: le sort ne fonctionnera pas sur les unités vodatntes, les bâtiments et les morts.
return IsUnitType(GetFilterUnit(),UNIT_TYPE_FLYING)==false and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE)==false and IsUnitType(GetFilterUnit(),UNIT_TYPE_DEAD)==false
endfunction
//=================================================
private struct str2
unit caster
unit cibledrain
integer i
player pl
endstruct
//=================================================
private function PeriodicDrain takes nothing returns nothing
local timer t2 = GetExpiredTimer()
local str2 dat = GetTimerData(t2)
if (dat.i < DUR2) and GetUnitState(dat.cibledrain, UNIT_STATE_LIFE) > 0 and GetUnitState(dat.caster, UNIT_STATE_LIFE) > 0 and GetUnitUserData(dat.caster)==20 then
set dat.i = dat.i + 1
call SetUnitState(dat.cibledrain,UNIT_STATE_LIFE,GetUnitState(dat.cibledrain, UNIT_STATE_LIFE)-DMG)
call SetUnitState(dat.caster,UNIT_STATE_LIFE,GetUnitState(dat.caster, UNIT_STATE_LIFE)+DMG)
else
call ReleaseTimer(t2)
call dat.destroy()
endif
endfunction
//=================================================
private function IniPeriodicDrain takes unit caster,unit cibledrain returns nothing
local timer t1 = NewTimer()
local timer t2 = NewTimer()
local str2 dat = str2.create()
local real x1 = GetUnitX(caster)
local real y1 = GetUnitY(caster)
local real z1 = GetUnitFlyHeight(caster)
local real x2 = GetUnitX(cibledrain)
local real y2 = GetUnitY(cibledrain)
local real z2 = GetUnitFlyHeight(cibledrain)
set dat.caster = caster
set dat.cibledrain = cibledrain
set dat.pl = GetOwningPlayer(dat.caster)
set dat.i = 0
set udg_cast_b[GetPlayerId(dat.pl)+1] = true
call SetTimerData(t2, dat)
call TimerStart (t2, BoucleDrain, true, function PeriodicDrain )
set caster = null
set cibledrain = null
endfunction
//=================================================
private struct str1
unit caster
unit cibledrain
lightning e
integer i
player pl
endstruct
//=================================================
private function PeriodicLightning takes nothing returns nothing
local timer t1 = GetExpiredTimer()
local str1 dat = GetTimerData(t1)
local real x1 = GetUnitX(dat.caster)
local real y1 = GetUnitY(dat.caster)
local real z1 = GetUnitFlyHeight(dat.caster)
local real x2 = GetUnitX(dat.cibledrain)
local real y2 = GetUnitY(dat.cibledrain)
local real z2 = GetUnitFlyHeight(dat.cibledrain)
if (dat.i < DUR1) and GetUnitState(dat.cibledrain, UNIT_STATE_LIFE) > 0 and GetUnitState(dat.caster, UNIT_STATE_LIFE) > 0 and GetUnitUserData(dat.caster)==20 then
set dat.i = dat.i + 1
call MoveLightningEx(dat.e,true,x1, y1, z1, x2, y2, z2 )
else
call DestroyLightning(dat.e)
call ReleaseTimer(t1)
call dat.destroy()
endif
endfunction
//=================================================
private function IniPeriodicLightning takes unit caster,unit cibledrain returns nothing
local timer t1 = NewTimer()
local timer t2 = NewTimer()
local str1 dat = str1.create()
local real x1 = GetUnitX(caster)
local real y1 = GetUnitY(caster)
local real z1 = GetUnitFlyHeight(caster)
local real x2 = GetUnitX(cibledrain)
local real y2 = GetUnitY(cibledrain)
local real z2 = GetUnitFlyHeight(cibledrain)
set dat.caster = caster
set dat.cibledrain = cibledrain
call SetUnitUserData(dat.caster,20)
set dat.e = AddLightningEx(GraphEclair, true, x1, y1, z1, x2, y2, z2)
set dat.i = 0
set dat.pl = GetOwningPlayer(dat.caster)
set udg_cast_b[GetPlayerId(dat.pl)+1] = true
call SetTimerData(t1, dat)
call TimerStart (t1, BoucleLightning, true, function PeriodicLightning )
set caster = null
set cibledrain = null
endfunction
//=================================================
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == IDSort
endfunction
//=================================================
private function Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local player pl = GetOwningPlayer(u)
local real x1 = GetUnitX(u)
local real y1 = GetUnitY(u)
local group g = CreateGroup()
local unit target
call GroupEnumUnitsInRange(g,x1,y1,AOE,Condition(function filter))
loop
set target = FirstOfGroup(g)
exitwhen target == null
call GroupRemoveUnit(g, target)
if IsUnitEnemy(target, pl) == true then
call IniPeriodicLightning (u,target)
call IniPeriodicDrain (u,target)
endif
endloop
call DestroyGroup(g)
set g = null
set u = null
set pl = null
set target = null
endfunction
//=================================================
public function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition(t, Condition(function Conditions))
call TriggerAddAction(t, function Actions)
endfunction
//=================================================
endscope
//=================================================
scope stopdrain initializer init
//=================================================
private function Conditions takes nothing returns boolean
return GetUnitUserData(GetTriggerUnit())== 20
endfunction
//=================================================
private function Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
call SetUnitUserData(u,0)
set u = null
endfunction
//=================================================
public function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerAddCondition(t, Condition(function Conditions))
call TriggerAddAction(t, function Actions)
endfunction
//=================================================
endscope
Librairie TimerUtils
Ibi: déclencheur vide dont le contenu est à remplacer par celui-ci.
Secret:
Jass:
library_once TimerUtils
//*********************************************************************
//* TimerUtils (Blue flavor)
//* ----------
//*
//* To implement it , create a custom text trigger called TimerUtils
//* and paste the contents of this script there.
//*
//* To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass) More scripts: htt://www.wc3campaigns.net
//*
//* For your timer needs:
//* * Attaching
//* * Recycling (with double-free protection)
//*
//* set t=NewTimer() : Get a timer (alternative to CreateTimer)
//* ReleaseTimer(t) : Relese a timer (alt to DestroyTimer)
//* SetTimerData(t,2) : Attach value 2 to timer
//* GetTimerData(t) : Get the timer's value.
//* You can assume a timer's value is 0
//* after NewTimer.
//*
//* Blue Flavor: Slower than the red flavor, it got a 408000 handle id
//* limit, which means that if more than 408000 handle ids
//* are used in your map, TimerUtils might fail, this
//* value is quite big and it is much bigger than the
//* timer limit in Red flavor.
//*
//********************************************************************
//================================================================
globals
private constant integer MAX_HANDLE_ID_COUNT = 408000
// values lower than 8191: very fast, but very unsafe.
// values bigger than 8191: not that fast, the bigger the number is the slower the function gets
// Most maps don't really need a value bigger than 50000 here, but if you are unsure, leave it
// as the rather inflated value of 408000
endglobals
//=================================================================================================
private function H2I takes handle h returns integer
return h
return 0
endfunction
//It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
function SetTimerData takes timer t, integer value returns nothing
debug if(H2I(t)-MIN_HANDLE_ID>=MAX_HANDLE_ID_COUNT) then
debug call BJDebugMsg("SetTimerData: Handle id too big, increase the max handle id count or use gamecache instead")
debug endif
set data[H2I(t)-MIN_HANDLE_ID]=value
endfunction
function GetTimerData takes timer t returns integer
debug if(H2I(t)-MIN_HANDLE_ID>=MAX_HANDLE_ID_COUNT) then
debug call BJDebugMsg("GetTimerData: Handle id too big, increase the max handle id count or use gamecache instead")
debug endif
return data[H2I(t)-MIN_HANDLE_ID]
endfunction
//==========================================================================================
globals
private timer array tT
private integer tN = 0
private constant integer HELD=0x28829022
//use a totally random number here, the more improbable someone uses it, the better.
endglobals
//==========================================================================================
function NewTimer takes nothing returns timer
if (tN==0) then
set tT[0]=CreateTimer()
else
set tN=tN-1
endif
call SetTimerData(tT[tN],0)
return tT[tN]
endfunction
//==========================================================================================
function ReleaseTimer takes timer t returns nothing
if(t==null) then
debug call BJDebugMsg("Warning: attempt to release a null timer")
return
endif
if (tN==8191) then
debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")
//stack is full, the map already has much more troubles than the chance of bug
call DestroyTimer(t)
else
call PauseTimer(t)
if(GetTimerData(t)==HELD) then
debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
return
endif
call SetTimerData(t,HELD)
set tT[tN]=t
set tN=tN+1
endif
endfunction
Inscrit le: 09 Mar 2009 Messages: 1154 Sujets: 54 Spécialité en worldedit: Croâ ?
Posté le: 14/04/09 00:24 Sujet du message:
Merci beaucoup ... Mais j'ai du bug
Je vais me confesser, c'est la première fois que j'insère du Jass dans mes maps et là y a tout qui bug, quand je veux lancer la map en test, mon déclencheur se désactive avec un panneau "Erreur de script" qui s'affichent qui me montre les lignes et au-dessus il y a écrit "Ligne 57 attendait une fin de ligne" et d'autres trucs du genres, ce qui du coup désactive le code xD !
Et mis à part le bug, je sais pas si c'est inclus mais est-ce qu'il y a/serait possible de prévoir 3 levels du sort ? =)
Voilà c'est les seuls problèmes que j'ai ( Tout est relatif ) _________________
Ah oui j'ai oublié : ce truc ne fonctionnera que si tu as le JassNewGenPack 5.b ou supérieur comme éditeur.
Pour les niveau ça donnerait ça je pense.
Secret:
Jass:
scope drainmultiple initializer init
//=================================================
globals
private constant real BoucleLightning = 0.02//intervalle entre chaque mouvement des lightnings
private constant real BoucleDrain = 1.00//intervalle entre chaque drain de vie
private constant string GraphEclair = "DRAL"//graphisme des éclairs, celui-ci est celui de base
private constant integer DUR1 = 500
private constant integer DUR2 = 10
private constant real AOE = 275.00//zone d'effet
private constant real DMG = 50.00 //constante de vie pompée à chaque intervalle BoucleDrain multipliée par le niveau du sort
private constant integer IDSort = 'A000' //L'id du sort lancé
endglobals
//=================================================
private function filter takes nothing returns boolean
//Filtre les unités: le sort ne fonctionnera pas sur les unités vodatntes, les bâtiments et les morts.
return IsUnitType(GetFilterUnit(),UNIT_TYPE_FLYING)==false and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE)==false and IsUnitType(GetFilterUnit(),UNIT_TYPE_DEAD)==false
endfunction
//=================================================
private struct str2
unit caster
unit cibledrain
integer i
player pl
endstruct
//=================================================
private function PeriodicDrain takes nothing returns nothing
local timer t2 = GetExpiredTimer()
local str2 dat = GetTimerData(t2)
if (dat.i < DUR2) and GetUnitState(dat.cibledrain, UNIT_STATE_LIFE) > 0 and GetUnitState(dat.caster, UNIT_STATE_LIFE) > 0 and GetUnitUserData(dat.caster)==20 then
set dat.i = dat.i + 1
call SetUnitState(dat.cibledrain,UNIT_STATE_LIFE,GetUnitState(dat.cibledrain, UNIT_STATE_LIFE)-DMG*GetUnitAbilityLevel(dat.caster,IDSort))
call SetUnitState(dat.caster,UNIT_STATE_LIFE,GetUnitState(dat.caster, UNIT_STATE_LIFE)+DMG*GetUnitAbilityLevel(dat.caster,IDSort)))
else
call ReleaseTimer(t2)
call dat.destroy()
endif
endfunction
//=================================================
private function IniPeriodicDrain takes unit caster,unit cibledrain returns nothing
local timer t1 = NewTimer()
local timer t2 = NewTimer()
local str2 dat = str2.create()
local real x1 = GetUnitX(caster)
local real y1 = GetUnitY(caster)
local real z1 = GetUnitFlyHeight(caster)
local real x2 = GetUnitX(cibledrain)
local real y2 = GetUnitY(cibledrain)
local real z2 = GetUnitFlyHeight(cibledrain)
set dat.caster = caster
set dat.cibledrain = cibledrain
set dat.pl = GetOwningPlayer(dat.caster)
set dat.i = 0
set udg_cast_b[GetPlayerId(dat.pl)+1] = true
call SetTimerData(t2, dat)
call TimerStart (t2, BoucleDrain, true, function PeriodicDrain )
set caster = null
set cibledrain = null
endfunction
//=================================================
private struct str1
unit caster
unit cibledrain
lightning e
integer i
player pl
endstruct
//=================================================
private function PeriodicLightning takes nothing returns nothing
local timer t1 = GetExpiredTimer()
local str1 dat = GetTimerData(t1)
local real x1 = GetUnitX(dat.caster)
local real y1 = GetUnitY(dat.caster)
local real z1 = GetUnitFlyHeight(dat.caster)
local real x2 = GetUnitX(dat.cibledrain)
local real y2 = GetUnitY(dat.cibledrain)
local real z2 = GetUnitFlyHeight(dat.cibledrain)
if (dat.i < DUR1) and GetUnitState(dat.cibledrain, UNIT_STATE_LIFE) > 0 and GetUnitState(dat.caster, UNIT_STATE_LIFE) > 0 and GetUnitUserData(dat.caster)==20 then
set dat.i = dat.i + 1
call MoveLightningEx(dat.e,true,x1, y1, z1, x2, y2, z2 )
else
call DestroyLightning(dat.e)
call ReleaseTimer(t1)
call dat.destroy()
endif
endfunction
//=================================================
private function IniPeriodicLightning takes unit caster,unit cibledrain returns nothing
local timer t1 = NewTimer()
local timer t2 = NewTimer()
local str1 dat = str1.create()
local real x1 = GetUnitX(caster)
local real y1 = GetUnitY(caster)
local real z1 = GetUnitFlyHeight(caster)
local real x2 = GetUnitX(cibledrain)
local real y2 = GetUnitY(cibledrain)
local real z2 = GetUnitFlyHeight(cibledrain)
set dat.caster = caster
set dat.cibledrain = cibledrain
call SetUnitUserData(dat.caster,20)
set dat.e = AddLightningEx(GraphEclair, true, x1, y1, z1, x2, y2, z2)
set dat.i = 0
set dat.pl = GetOwningPlayer(dat.caster)
set udg_cast_b[GetPlayerId(dat.pl)+1] = true
call SetTimerData(t1, dat)
call TimerStart (t1, BoucleLightning, true, function PeriodicLightning )
set caster = null
set cibledrain = null
endfunction
//=================================================
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == IDSort
endfunction
//=================================================
private function Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local player pl = GetOwningPlayer(u)
local real x1 = GetUnitX(u)
local real y1 = GetUnitY(u)
local group g = CreateGroup()
local unit target
call GroupEnumUnitsInRange(g,x1,y1,AOE,Condition(function filter))
loop
set target = FirstOfGroup(g)
exitwhen target == null
call GroupRemoveUnit(g, target)
if IsUnitEnemy(target, pl) == true then
call IniPeriodicLightning (u,target)
call IniPeriodicDrain (u,target)
endif
endloop
call DestroyGroup(g)
set g = null
set u = null
set pl = null
set target = null
endfunction
//=================================================
public function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition(t, Condition(function Conditions))
call TriggerAddAction(t, function Actions)
endfunction
//=================================================
endscope
//=================================================
scope stopdrain initializer init
//=================================================
private function Conditions takes nothing returns boolean
return GetUnitUserData(GetTriggerUnit())== 20
endfunction
//=================================================
private function Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
call SetUnitUserData(u,0)
set u = null
endfunction
//=================================================
public function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerAddCondition(t, Condition(function Conditions))
call TriggerAddAction(t, function Actions)
endfunction
//=================================================
endscope
Inscrit le: 09 Mar 2009 Messages: 1154 Sujets: 54 Spécialité en worldedit: Croâ ?
Posté le: 14/04/09 00:46 Sujet du message:
Oo le JassNewGenPack 5.b? C'est quoi? C'est pas le vJass avec grimoire et tout le tralala? ^^ parce que si c'est ça il est pas question que je l'installe ! Il m'affiche tout le temps des virus et après il veut que je débranche mon anti-virus ~~ _________________
C'est un pack qui contient en effet tout ces petits programmes.
Il suffit d'autoriser le fichier que ton antivirus considère comme un virus, car c'est un *.exe qui modifie d'autres fichiers (dont certains de Frozen Throne) ce qui explique qu'il est considéré comme virus. Mais il n'en n'est rien, je te rassure _________________
Toutes les heures sont au format GMT + 1 Heure Aller à la page 1, 2Suivante
Page 1 sur 2
Vous ne pouvez pas poster de nouveaux sujets dans ce forum Vous ne pouvez pas répondre aux sujets dans ce forum Vous ne pouvez pas éditer vos messages dans ce forum Vous ne pouvez pas supprimer vos messages dans ce forum Vous ne pouvez pas voter dans les sondages de ce forum