Sooda
Diversity enchants
 Reaction score
 318
I have done my second MUI JASS ability what is leakless (I hope at least so.) and pretty optimized.
Description: Magic spell which damages enemy units in a line. Each unit after first target takes additional damage.
Level 1: Deals 50 base damage. Each target after takes additional 15 damage. Damage limit is 100 damage.
Level 2: Deals 100 base damage. Each target after takes additional 30 damage. Damage limit is 200 damage.
Level 3: Deals 150 base damage. Each target after takes additional 45 damage. Damage limit is 300 damage.
Links to screenshots:
You can find demo map below my post (See attachments.).
Read map' s README how to implement it.
JASS:
Any suggestions or feedback ? I gladly hear them.
Description: Magic spell which damages enemy units in a line. Each unit after first target takes additional damage.
Level 1: Deals 50 base damage. Each target after takes additional 15 damage. Damage limit is 100 damage.
Level 2: Deals 100 base damage. Each target after takes additional 30 damage. Damage limit is 200 damage.
Level 3: Deals 150 base damage. Each target after takes additional 45 damage. Damage limit is 300 damage.
Links to screenshots:
You can find demo map below my post (See attachments.).
Read map' s README how to implement it.
JASS:
JASS:
constant function AbilityRawId takes nothing returns integer
// default is 'A000'
return 'A000'
endfunction
constant function MissileEffect takes nothing returns string
// default is "Abilities\\Spells\\Undead\\OrbOfDeath\\AnnihilationMissile.mdl"
return "Abilities\\Spells\\Undead\\OrbOfDeath\\AnnihilationMissile.mdl"
endfunction
constant function AbilityBaseDistance takes nothing returns real
// default is 500.
return 500.
endfunction
constant function DistanceAddedPerLevel takes nothing returns real
// default is 100.
return 100.
endfunction
constant function DamageCapPerLevel takes nothing returns real
// DamageCapPerLevel() * abilityLevel
// default is 100.
return 100.
endfunction
constant function AbilityBaseDamage takes nothing returns real
// formulae is AbilityBaseDamage() * abilityLevel
// default is 50.
return 50.
endfunction
constant function DamageAddedPerTarget takes nothing returns real
// formulae is DamageAddedPerTarget() * abilityLevel
// default is 15.
return 15.
endfunction
constant function AbilityRadius takes nothing returns real
// default is 100.
return 100.
endfunction
constant function ShowText takes nothing returns boolean
// default is true
return true
endfunction
constant function TextColor takes nothing returns string
// default is "CFFE55BB0"
return "CFFE55BB0"
endfunction
constant function AbilityAttackType takes nothing returns attacktype
// default is ATTACK_TYPE_NORMAL
return ATTACK_TYPE_NORMAL
endfunction
constant function AbilityDamageType takes nothing returns damagetype
// default is DAMAGE_TYPE_LIGHTNING
return DAMAGE_TYPE_LIGHTNING
endfunction
function ValidUnit takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit())) and GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE) >= .405
endfunction
function ValidAbility takes nothing returns boolean
return GetSpellAbilityId() == AbilityRawId()
endfunction
function ShowFloatingTextTag takes string msg, real locationX, real locationY returns texttag
local texttag damageMsgTag = CreateTextTag()
call SetTextTagText(damageMsgTag,msg,.024)
call SetTextTagPos(damageMsgTag,locationX,locationY,0.)
call SetTextTagColor(damageMsgTag,100,100,100,0)
call SetTextTagVelocity(damageMsgTag,0.,.035)
call SetTextTagFadepoint(damageMsgTag,0.)
call SetTextTagLifespan(damageMsgTag,3.)
call SetTextTagPermanent(damageMsgTag,false)
call SetTextTagVisibility(damageMsgTag,true)
return damageMsgTag
endfunction
function DamageUnitsInLine takes nothing returns nothing
local unit caster = GetTriggerUnit()
local unit enumUnit
local integer abilityLevel = GetUnitAbilityLevel(caster,AbilityRawId())
local integer textTagCounter = 0
local integer textTagCounterMask = 0
local real counter = 0.
local real damage = AbilityBaseDamage() * abilityLevel
local real damageCap = DamageCapPerLevel() * abilityLevel
local real addedDamage = DamageAddedPerTarget() * abilityLevel
local real radius = AbilityRadius()
local boolean showString = ShowText()
local string stringColor = TextColor()
local string damageString
local texttag array enumUnitDamageTag
local attacktype whichAttack = AbilityAttackType()
local damagetype whichDamage = AbilityDamageType()
local location abilityLoc = GetSpellTargetLoc()
local real locationX = GetLocationX(abilityLoc)
local real locationY = GetLocationY(abilityLoc)
local real casterX = GetUnitX(caster)
local real casterY = GetUnitY(caster)
local real enumUnitX
local real enumUnitY
local real angleBetweenPoints = bj_RADTODEG * Atan2(locationY  casterY, locationX  casterX)
local real polarProjectionXCos = Cos(angleBetweenPoints * bj_DEGTORAD)
local real polarProjectionYSin = Sin(angleBetweenPoints * bj_DEGTORAD)
local real locationPolarProjectionY = 0.
local real locationPolarProjectionX = 0.
local real distance = AbilityBaseDistance()+(DistanceAddedPerLevel()*abilityLevel)
local effect missileEffect = null
local group damagedUnits = CreateGroup()
local group tempUnits = CreateGroup()
local boolexpr filterUnits = Condition (function ValidUnit)
loop
exitwhen counter > distance
set locationPolarProjectionX = casterX + counter * polarProjectionXCos
set locationPolarProjectionY = casterY + counter * polarProjectionYSin
set missileEffect = AddSpecialEffect(MissileEffect(),locationPolarProjectionX,locationPolarProjectionY)
call GroupEnumUnitsInRange(tempUnits,locationPolarProjectionX,locationPolarProjectionY,radius,filterUnits)
loop
set enumUnit = FirstOfGroup(tempUnits)
exitwhen enumUnit == null
if (IsUnitInGroup(enumUnit,damagedUnits) == false) then
call GroupAddUnit(damagedUnits,enumUnit)
set enumUnitX = GetUnitX(enumUnit)
set enumUnitY = GetUnitY(enumUnit)
set damageString = stringColor + I2S(R2I(damage)) + "!"
if showString then
set enumUnitDamageTag[textTagCounter] = ShowFloatingTextTag(damageString,enumUnitX,enumUnitY)
set textTagCounter = textTagCounter + 1
endif
call UnitDamageTarget(caster,enumUnit,damage,true,false,whichAttack,whichDamage,WEAPON_TYPE_WHOKNOWS)
call GroupRemoveUnit(tempUnits,enumUnit)
if damage + addedDamage >= damageCap then
set damage = damageCap
else
set damage = damage + addedDamage
endif
endif
call GroupRemoveUnit(tempUnits,enumUnit)
set enumUnit = null
endloop
call DestroyEffect(missileEffect)
set missileEffect = null
set counter = counter + radius
endloop
call DestroyBoolExpr(filterUnits)
set filterUnits = null
call DestroyGroup(damagedUnits)
call DestroyGroup(tempUnits)
set damagedUnits = null
set tempUnits = null
call RemoveLocation(abilityLoc)
set abilityLoc = null
set caster = null
set enumUnit = null
if showString then
call TriggerSleepAction(3.)
loop
exitwhen textTagCounterMask > textTagCounter
call DestroyTextTag(enumUnitDamageTag[textTagCounterMask])
set enumUnitDamageTag[textTagCounterMask] = null
set textTagCounterMask = textTagCounterMask + 1
endloop
endif
endfunction
function InitTrig_ArcaneMagic takes nothing returns nothing
local trigger arcaneMagicTrig = CreateTrigger()
local effect preLoadEffect = AddSpecialEffect(MissileEffect(),0.,0.)
local integer counter = 0
call DestroyEffect(preLoadEffect)
set preLoadEffect = null
call TriggerAddCondition(arcaneMagicTrig,Condition (function ValidAbility))
call TriggerAddAction(arcaneMagicTrig, function DamageUnitsInLine)
loop
exitwhen counter > 15
call TriggerRegisterPlayerUnitEvent(arcaneMagicTrig,Player(counter),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set counter = counter + 1
endloop
set arcaneMagicTrig = null
endfunction
Any suggestions or feedback ? I gladly hear them.
Attachments

53.6 KB Views: 453