Posté le: 12/03/09 01:02 Sujet du message: Simple saut +dégâts en Jass
Nom de la fonction : Simple saut + dégâts Créateur : Apocalypse
Fonctions requises: Librairie TimerUtils
Secret:
Jass:
library_once TimerUtils initializer init
//*********************************************************************
//* TimerUtils (Blue flavor for 1.23b or later)
//* ----------
//*
//* 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.
//*
//********************************************************************
//It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
function SetTimerData takes timer t, integer value returns nothing
call SaveInteger(hasht,0, GetHandleId(t), value)
endfunction
function GetTimerData takes timer t returns integer
return LoadInteger(hasht, 0, GetHandleId(t))
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
private function init takes nothing returns nothing
set hasht = InitHashtable()
endfunction
endlibrary
Code :
Secret:
Jass:
//Pour utiliser plusieurs sorts de saut différents: simplement modifer le nom du scope (ici "saut")
//Déclaration du scope
scope saut initializer init
globals
private constant integer IDSORT = 'A000' //L'ID de votre sort de saut.
private constant real TIMEOUT = 0.02 //L'interval entre chaque modification de la position de l'unité, en secondes.
private constant integer TYPE = 'hpea' //Le code de l'unité qui servira à tester si le déplacement est possible.
private unit TEST = null //L'unité de type TYPE qui sera créée
private constant integer RAVEN = 'Amrf' //L'ID du sort "forme de corbeau"
//Dégâts infligés par l'unité:
//Degat total = DEGATFacteurBonusForce*Force du héro +DEGATFacteurNiveauSort*Niveau du sort*DEGATConstant
private constant real DEGATFacteurNiveauSort = 1.00
private constant real DEGATFacteurBonusForce = 1.00
private constant real DEGATConstant = 100.00
private constant real AOE = 250.00//Zone d'effet des dégâts
private constant string EFFET = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapcaster.mdl"//Effet spécial des dégâts
private constant real IMPULSION = 0.50 //Facteur d'impulsion du saut
//Plus il est élevé, plus l'unité s'élève haut.
private constant integer VITESSE = 20//Vitesse du saut.
private constant string ANIMATION = "attack slam" //Animation jouée pendant le saut
//Fonction qui sert à infliger les dégâts finaux (Pour résumer on ajoute les unités à portées de la constante AOE
//Dans un groupe et on les endommage toutes en fonction des réglages des constantes de dégat
//Tout en affichant l'effet spécial réglé dans les constantes
private function DegatFinal takes unit caster, real degat returns nothing
local real x = GetUnitX(caster)
local real y = GetUnitY(caster)
local unit target
local player proprietaire = GetOwningPlayer(caster)
local location position = GetUnitLoc(caster)
local group groupe = GetUnitsInRangeOfLocAll(AOE,position)
call DestroyEffect(AddSpecialEffect(EFFET, x, y ))
loop
set target = FirstOfGroup(groupe)
exitwhen (target == null)
call GroupRemoveUnit(groupe, target)
if IsUnitEnemy(target,proprietaire) then
call UnitDamageTargetBJ( caster, target, degat, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
endif
endloop
set caster= null
call DestroyGroup(groupe)
set groupe = null
call RemoveLocation(position)
set position = null
set proprietaire = null
endfunction
//Permet de savoir si le prochain déplacement de l'unité est possible ou pas
//On créé une unité sur le sol. Si elle ne peut pas être crée, c'est que le déplacement est imposible.
private function IsPointPathableForUnit takes real x, real y, unit whichUnit returns boolean
local real tx = 0
local real ty = 0
call ShowUnit(whichUnit, false)
if TEST == null then
set TEST = CreateUnit(Player(15), TYPE, 0.0, 0.0, 0.0)
else
call ShowUnit(TEST, true)
endif
call SetUnitPosition(TEST, x, y)
set tx = GetUnitX(TEST)
set ty = GetUnitY(TEST)
call ShowUnit(TEST, false)
call ShowUnit(whichUnit,true)
return (x == tx and y == ty)
endfunction
//Déclaration de la structure. Il s'agit de variables qu'on va pouvoir utiliser sur plusieurs fonctions
//Sans déclarer à chaque fois toutes les variables nécessaires
struct StructureSaut
unit caster
real angle
integer distance
integer i
real degat
endstruct
//La fonction périodique. Elle va permettre de faire bouger l'unité.
private function Periodic takes nothing returns nothing
local timer chrono = GetExpiredTimer() //On récupère le timer
local StructureSaut data = GetTimerData(chrono) //On récupère les données liées au timer
local real newX = GetUnitX(data.caster) + VITESSE*Cos(data.angle) //On calcule les futures coordonnées x et y
local real newY = GetUnitY(data.caster) + VITESSE*Sin(data.angle) //Sur lesquelles on enverra le lanceur de sort
local real z = GetUnitFlyHeight(data.caster) //On retrouve la hauteur actuelle du lanceur de sort
local real newZ
if (data.i < data.distance) then //Tant que le compteur n'arrive pas à cette valeur
set data.i = data.i + 1 //On l'incrémente
if IsPointPathableForUnit(newX, newY, data.caster) then //Si la destination est viable
call SetUnitPosition(data.caster, newX, newY) //on déplace l'unité sur les nouvelles coordonnées
endif
if (data.i < (data.distance * 0.5)) then //Si on est avant la moitié du saut
set newZ = z + (data.distance * IMPULSION) //On augmente la hauteur
else
set newZ = z - (data.distance * IMPULSION) //Sinon on la diminue
endif
call SetUnitFlyHeight(data.caster, newZ, 0.00)
else
call SetUnitPathing( data.caster, true) //Si le compteur est fini, on redonne une collision au lanceur
call SelectUnitForPlayerSingle( data.caster, GetOwningPlayer(data.caster) ) //on selectionne l'unité
call UnitRemoveAbility( data.caster, RAVEN) //On lui enlève forme de corbeau
call SetUnitTimeScalePercent( data.caster, 1.00 ) //On remet la vitesse d'animation normale
call ReleaseTimer(chrono) //On libère le timer en fonction de la librairie TimerUtils
call DegatFinal(data.caster,data.degat) //On appelle la fonction de dégâts
call data.destroy() //Et on détruit la structure (sinon gare au leak)
endif
endfunction
private function DebutSort takes nothing returns nothing
//La fonction d'initialisation du sort
local timer chrono = NewTimer() //On créé le timer
local StructureSaut data = StructureSaut.create() //On créé la structure
local unit Caster = GetTriggerUnit() //Toutes les variables correspondant à l'unité et à sa cible
local real xOrigine = GetUnitX(Caster)
local real yOrigine = GetUnitY(Caster)
local location Cible = GetSpellTargetLoc()
local real xCible = GetLocationX(Cible)
local real yCible = GetLocationY(Cible)
//La distance du saut et l'angle entre le lanceur de sort et sa cible
local real DistanceSaut = SquareRoot((xCible-xOrigine)*(xCible-xOrigine)+(yCible-yOrigine)*(yCible-yOrigine))
local real FacingCaster = Atan2((yCible -yOrigine), (xCible - xOrigine))
//le calcul des futurs dégâts en fonction de vos réglages
local real degat = DEGATFacteurBonusForce*GetHeroStr(Caster,true)+DEGATFacteurNiveauSort*GetUnitAbilityLevelSwapped(IDSORT,Caster)*DEGATConstant
call SetUnitPathing( Caster, false)//On enlève la collision du lanceur de sort
//On attribue aux variables de la structure
//Les données de la fonction
set data.caster = Caster
set data.angle = FacingCaster
set data.distance = R2I(DistanceSaut/VITESSE)
set data.degat = degat
set data.i = 0
call UnitAddAbility(data.caster, RAVEN) //On ajoute forme de corbeau au lanceur de sort,
call SetUnitAnimation(data.caster, ANIMATION) //On joue l'animation des constantes
call SetUnitTimeScale(data.caster, .30) //On diminue sa vitesse d'animation
call SetTimerData(chrono, data) //On lie le timer à la structure
call TimerStart (chrono, TIMEOUT, true, function Periodic ) //On lance le timer et la fonction périodique
//On supprime les variables dont on a plus besoin pour prévenir des leaks
set Caster = null
call RemoveLocation(Cible)
set Cible = null
//L'architecture du scope (qui est la même que n'importe quel déclencheur: event-condition-action
public function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition(t, Condition(function ConditionsSort))
call TriggerAddAction(t, function DebutSort)
endfunction
//=================================================
endscope
Utilisation : Utiliser une compétence avec cible point et zone d'effet.
Copyright : Libre
Remarques : Voici une version plus présentable du saut que j'ai fait en VJass et qui ne nécessite pas d'appel de fonction.
Pour l'implémenter, il suffit de créer un premier déclencheur avec la librairie TimerUtils, et de faire de même avec ma fonction.
Ensuite il faudra régler les constantes de ma fonction selon vos besoins.
Cette fonction nécessite le Jass NewGen Pack.
Elle nécessite également la librairie TimerUtils qui n'est pas de moi.
Librairie TimerUtils _________________
Dernière édition par jk2pach le 10/08/09 17:45; édité 1 fois
La fonction renvoie true si le sort est le bon, sinon elle renvoie false. Plus court, plus clair.
Autre conseil, revoit l'indentation de tes fonctions. C'est plus agréable et plus pratique à lire.
Jass:
private function DegatFinal takes unit caster, real degat returns nothing
local real x = GetUnitX(caster) // perso je colle pas les lignes de codes tout à gauche sauf pour le début et la fin des fonctions et autres, c'pas bô
call DestroyEffect(AddSpecialEffect(EFFET, x, y ))
loop // ce qui est dans la loop, tu le décales d'un coup de Tab pour bien le détacher
set target = FirstOfGroup(groupe)
if IsUnitEnemy(target,proprietaire) then // pareil pour les blocs if/then/else
call UnitDamageTargetBJ( caster, target, degat, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
endif
endloop
set caster= null
endfunction
Pour le reste, j'ai eu la flemme de regarder, désolé... _________________
Page 1 sur 1 La question posée dans ce topic a été résolue !
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