| 06-22-2009, 08:29 AM | #1 |
Hi guys, this is a simple critical spell that heals nearby units. I made it using ADamage and I pan submiting it with other spells I made using ADamage in a small spellpack. Basically, I would like some opinions about the code, rep++ will be awarded. JASS://=========================================================================== //A JESP spell that causes the attacker to deal extra damage to an enemy unit //on an attack. Nearby allied units are then healed by the damaged caused. // //@author Flame_Phoenix // //Requires: // - Adamage // - xebasic and xedamage // //@credits: // - Anitarf, for ADamage // - Vexorian, for xebasic and xedamage // - Moyack, for helping on improving this script // - 0zyx0, for telling me how to make this script more efficient // //@version 1.3.2 //=========================================================================== scope WolfStrike initializer Init //=========================================================================== //=============================SETUP START=================================== //=========================================================================== globals private constant integer AID = 'A023' //rw of the hero ability private constant string ALLY_EFFECT = "Abilities\\Spells\\Undead\\DeathPact\\DeathPactTarget.mdl" //heal effect that will appear on healed units private constant string ENEMY_EFFECT = "Objects\\Spawnmodels\\Other\\BeastmasterBlood\\BeastmasterBlood.mdl" //Damage effect that will appear on damage units private constant string FIRE_EFF = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl" //an extra effect on the victim to make it look cooler =P endglobals private function Radius takes integer level returns real //the radius of the heal return level * 200. endfunction private function HealTargets takes unit attacker, unit friend returns boolean //the targets(friends) that will be healed with the damage caused return IsUnitAlly(friend, GetOwningPlayer(attacker)) and (IsUnitType(friend, UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(friend, UNIT_TYPE_MECHANICAL) == false) and (GetWidgetLife(friend) > 0.405) endfunction private function Chances takes integer level returns real //the chances the caster has of causing extra damage return 1.//level * 0.1 endfunction private function Damage takes real dam, integer level returns real //the extra damage caused return dam * (level + 0.5) endfunction private function setupDamageOptions takes xedamage d returns nothing set d.dtype = DAMAGE_TYPE_NORMAL set d.atype = ATTACK_TYPE_NORMAL endfunction //=========================================================================== //=============================SETUP END===================================== //=========================================================================== globals private group g private boolexpr b private unit tmpAtt private xedamage damageOptions private timer damageTime //timer that will be started at 0.0 to deal the extra damage endglobals private struct aVictim unit attacker unit victim real extraDam integer level static method create takes unit att, unit vic, real bonusDam returns aVictim local aVictim this = aVictim.allocate() set .attacker = att set .victim = vic set .extraDam = bonusDam set .level = GetUnitAbilityLevel(att, AID) return this endmethod endstruct //=========================================================================== private function Targets takes nothing returns boolean return HealTargets(tmpAtt, GetFilterUnit()) endfunction //=========================================================================== private function Conditions takes unit attacker, unit victim returns boolean return (GetRandomReal(0, 1) <= Chances(GetUnitAbilityLevel(attacker, AID))) and (GetUnitAbilityLevel(attacker, AID) > 0) and (damageOptions.isInUse()==false) and IsUnitEnemy(victim, GetOwningPlayer(attacker)) and (IsUnitType(victim, UNIT_TYPE_STRUCTURE)==false) and (IsUnitType(victim, UNIT_TYPE_MECHANICAL)==false) endfunction //=========================================================================== private function DoDamage takes nothing returns nothing local aVictim thisVic = aVictim(GetTimerData(GetExpiredTimer())) //deal damage and release the timer ! call damageOptions.damageTarget(thisVic.attacker, thisVic.victim, thisVic.extraDam) call ReleaseTimer(GetExpiredTimer()) endfunction //=========================================================================== private function Actions takes unit damagedUnit, unit damageSource, real damage, real prevented returns nothing local integer lv //level of the ability local real bonus //bonus damage local texttag text //the nice textag local unit f local aVictim thisVic //this will keep information about the damage we will cause if Conditions(damageSource, damagedUnit) then set lv = GetUnitAbilityLevel(damageSource, AID) set text = CreateTextTag() set bonus = damage + Damage(damage, lv) set damageTime = NewTimer() set thisVic = aVictim.create(damageSource, damagedUnit, bonus) //Let's make the unit look as if it is taking fire, how? Let's make a fireball effect explode on them: call DestroyEffect( AddSpecialEffectTarget(FIRE_EFF, damagedUnit, "origin") ) // We know it is a valid target, let's damage it? // we are retrieving the level from the struct's members, and it is used in // a simple damage formula, for every level the damage increases by 25. call SetTimerData(damageTime, integer(thisVic)) call TimerStart(damageTime, 0.0, false, function DoDamage) call DestroyEffect(AddSpecialEffect(ENEMY_EFFECT, GetUnitX(damagedUnit), GetUnitY(damagedUnit))) set tmpAtt = damageSource call GroupEnumUnitsInRange(g, GetUnitX(damageSource), GetUnitY(damageSource), Radius(lv), b) loop set f = FirstOfGroup(g) exitwhen(f == null) call GroupRemoveUnit(g, f) call SetWidgetLife(f, GetWidgetLife(f) + bonus) call DestroyEffect(AddSpecialEffect(ALLY_EFFECT, GetUnitX(f), GetUnitY(f))) endloop call SetTextTagText(text, I2S(R2I(bonus)) + "!", 0.024) call SetTextTagPos(text, GetUnitX(damageSource), GetUnitY(damageSource), 0.00) call SetTextTagColor(text, 255, 0, 0, 255) call SetTextTagVelocity(text, 0, 0.04) call SetTextTagVisibility(text, true) call SetTextTagFadepoint(text, 2) call SetTextTagLifespan(text, 5) call SetTextTagPermanent(text, false) endif set text = null endfunction //=========================================================================== private function Init takes nothing returns nothing call ADamage_AddResponse( ADamage_Response.Actions ) // Initializing the damage options: set damageOptions=xedamage.create() // first instanciate a xeobject. call setupDamageOptions(damageOptions) // now call the function we saw before. //setting globals set g = CreateGroup() set b = Condition(function Targets) //Preloading effects call Preload(ALLY_EFFECT) call Preload(ENEMY_EFFECT) call Preload(FIRE_EFF) endfunction endscope |
| 06-22-2009, 08:51 AM | #2 |
I never thought ADamage was this lame. |
| 06-22-2009, 10:31 AM | #3 |
JASS:local trigger WolfStrikeTrg = CreateTrigger( ) |
| 06-22-2009, 10:46 AM | #4 |
You could use HealTargets() as a boolexpr directly, it will reduce the number of function call by one every time the filter is called. HealTargets() isn't inline friendly anyway, so there is no noticable drawback in making it a multiline function. setupDamageOptions can be replaced by two global constants. aVictim doesn't need a creation method, the members can be set directly, this reduces the number of function calls. ForGroup() is faster for iterating through groups than the FirstOfGroup() + remove method, but that would require you to pass additional data to a function that doesn't take anything. And don't set damageTime to null. Use a global variable instead. |
| 06-22-2009, 01:41 PM | #5 | |||||||
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
It pisses me off that I can't rep++ you guys, when you deserve it .. I guess I will have to give you a special place in my credits section for you all =P Anyway, you are now on credits, this is the least I can do. |
| 06-22-2009, 02:02 PM | #6 | ||
Quote:
Quote:
|
| 06-22-2009, 02:11 PM | #7 | ||
Quote:
Quote:
Because if not, I was thinking and I intend to make a mini-script library, a function that does the damage, using xedamage and timer utils and it does all timer things inside it, so the user only need to do "UnitADamageTarget(args)" ... =P Anyway, code updated !! =D |
| 06-22-2009, 02:33 PM | #8 | |
Quote:
|
| 06-22-2009, 02:47 PM | #9 | ||
Quote:
JASS:private constant damagetype DTYPE = DAMAGE_TYPE_NORMAL private constant weapontype ATYPE = WEAPON_TYPE_NORMAL //... set damageOptions.dtype = DTYPE set damageOptions.atype = ATYPE Quote:
|
| 06-22-2009, 04:45 PM | #10 | |
JASS:private constant damagetype DTYPE = DAMAGE_TYPE_NORMAL private constant weapontype ATYPE = WEAPON_TYPE_NORMAL //... set damageOptions.dtype = DTYPE set damageOptions.atype = ATYPE 1+1 = fish ! Quote:
Btw, Chinese Gods don't count =P |
