Exide
I am amazingly focused right now!
- Reaction score
- 448
Hi.
I'm trying to learn vJASS, so I decided to play around with it, creating some spells. I'm pretty satisfied with the result so far, so I decided to put them into a pack and post them here.
Suggestions on how to improve the code is appriciated.
These spells don't have anything in common, hence the lousy thread name.
Requirements: NewGen.
Leakless: I believe so.
Lagless: Yup.
MUI: I doubt it.
Pros: Highly Modifiable.
Pushback
Not so original.
A simple spell that targets a point and pushes all nearby enemy backwards, damaging them in the process. Also kills trees that pushed units come in contact with.
Code:
Life Drain:
An aura that passively steals hp away from nearby enemies and give them to the Hero.
Code:
Some Orb:
A custom orb effect.
This passive ability has a chance of hitting the enemy with a variety of spells, when attacking.
Clarification:
Passive ability. X% chance of occuring. Upon activation; creates a dummy, casts one out of Y (3, by default) spells on the target. Activates when a unit is attacked and takes damage by the Hero. (Not simply order attack.)
Code:
Flash Step:
Bleach rip-off.
Grants X% chance of evading incoming attacks.
Blinks the Hero to position of target move/smart-order, if the distance between the Hero and the point is greater than 250 and less than Y. Costs 25 (by default) mana. 2 seconds cd (also by default.)
Code:
Demomap attached.
Feedback appriciated.
I'm trying to learn vJASS, so I decided to play around with it, creating some spells. I'm pretty satisfied with the result so far, so I decided to put them into a pack and post them here.
Suggestions on how to improve the code is appriciated.
These spells don't have anything in common, hence the lousy thread name.
Requirements: NewGen.
Leakless: I believe so.
Lagless: Yup.
MUI: I doubt it.
Pros: Highly Modifiable.
Pushback
Not so original.
A simple spell that targets a point and pushes all nearby enemy backwards, damaging them in the process. Also kills trees that pushed units come in contact with.
Code:
JASS:
scope Pushback initializer Run //-!Do Not Touch!-
globals
private constant integer ABILITYID = 039;A001039; //Ability Rawcode
private constant string FIRSTSPECIALEFFECT = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl" //This Effect Must Have A Birth Animation!
private constant string SECONDSPECIALEFFECT = "Units\\NightElf\\Wisp\\WispExplode.mdl" //This Effect Must Have A Birth Animation!
private constant real MIN_DAMAGE = 5 //Formula = MIN_DAMAGE + MAX_DAMAGE * Level of ABILITYID of CASTER
private constant real MAX_DAMAGE = 5 //5 + 5 * X by default
private group PUSHBACKGROUP = CreateGroup() //-!Do Not Touch!-
private timer TIMER = CreateTimer() //-!Do Not Touch!-
private rect AREA = null //-!Do Not Touch!-
private unit CASTER //-!Do Not Touch!-
private real DAMAGE = 0 //-!Do Not Touch!-
private real SPELLTARGETX //-!Do Not Touch!-
private real SPELLTARGETY //-!Do Not Touch!-
private real DESTRUCTABLEX //-!Do Not Touch!-
private real DESTRUCTABLEY //-!Do Not Touch!-
endglobals
//===========================================================================
//=============//-!Do Not Touch Anything Below This Point!-==================
//===========================================================================
private function B takes nothing returns boolean
return (GetSpellAbilityId() == ABILITYID)
endfunction
function J takes nothing returns boolean
return (GetLearnedSkill() == ABILITYID)
endfunction
function I takes nothing returns nothing
set CASTER = GetTriggerUnit()
set DAMAGE = MIN_DAMAGE + MAX_DAMAGE * GetUnitAbilityLevel(CASTER, ABILITYID)
endfunction
function H takes nothing returns boolean
local real xf = GetDestructableX(GetFilterDestructable())
local real yf = GetDestructableY(GetFilterDestructable())
local real dx = DESTRUCTABLEX - xf
local real dy = DESTRUCTABLEY - yf
local real dist = SquareRoot(dx * dx + dy * dy)
local boolean result
set result = dist <= bj_enumDestructableRadius
return result
endfunction
private function G takes nothing returns nothing
call KillDestructable(GetEnumDestructable())
endfunction
private function F takes nothing returns nothing
call GroupRemoveUnit(PUSHBACKGROUP, GetTriggerUnit())
endfunction
private function E takes nothing returns nothing
local unit u = GetEnumUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real dx = x - SPELLTARGETX
local real dy = y - SPELLTARGETY
local real distance = SquareRoot(dx * dx + dy * dy)
local real angle = bj_RADTODEG * Atan2(y - SPELLTARGETY, x - SPELLTARGETX)
if (distance < 400) then
call PauseUnit(u, true)
set DESTRUCTABLEX = x + 8 * Cos(angle * bj_DEGTORAD)
set DESTRUCTABLEY = y + 8 * Sin(angle * bj_DEGTORAD)
call SetUnitPosition(u, DESTRUCTABLEX, DESTRUCTABLEY)
call UnitDamageTarget(CASTER, u, DAMAGE, true, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_DIVINE, WEAPON_TYPE_WHOKNOWS)
set bj_enumDestructableRadius = 150
if (AREA == null) then
set AREA = Rect(DESTRUCTABLEX - 150, DESTRUCTABLEY - 150, DESTRUCTABLEX + 150, DESTRUCTABLEY + 150)
else
call SetRect(AREA, DESTRUCTABLEX - 150, DESTRUCTABLEY - 150, DESTRUCTABLEX + 150, DESTRUCTABLEY + 150)
endif
call EnumDestructablesInRect(AREA, Filter(function H), function G)
else
call PauseUnit(u, false)
call GroupRemoveUnit(PUSHBACKGROUP, u)
endif
endfunction
private function D takes nothing returns nothing
call ForGroup(PUSHBACKGROUP, function E)
endfunction
private function C takes nothing returns boolean
return (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) and (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.405) and (IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(CASTER)) == true)
endfunction
private function A takes nothing returns nothing
local location loc = GetSpellTargetLoc()
set SPELLTARGETX = GetLocationX(loc)
set SPELLTARGETY = GetLocationY(loc)
call DestroyEffect(AddSpecialEffect(FIRSTSPECIALEFFECT, SPELLTARGETX, SPELLTARGETY))
call DestroyEffect(AddSpecialEffect(SECONDSPECIALEFFECT, SPELLTARGETX, SPELLTARGETY))
call GroupEnumUnitsInRange(PUSHBACKGROUP, SPELLTARGETX, SPELLTARGETY, 400, Filter(function C))
call RemoveLocation(loc)
set loc = null
endfunction
//===========================================================================
private function Run takes nothing returns nothing
local trigger t = CreateTrigger()
local trigger tt = CreateTrigger()
local trigger ttt = CreateTrigger()
local integer i = 0
loop
exitwhen i == 16
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerRegisterPlayerUnitEvent(tt, Player(i), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerRegisterPlayerUnitEvent(ttt, Player(i), EVENT_PLAYER_HERO_SKILL, null)
set i = i + 1
endloop
call TriggerAddCondition(t, Condition( function B))
call TriggerAddCondition(ttt, Condition( function J))
call TriggerAddAction(t, function A)
call TriggerAddAction(tt, function F)
call TriggerAddAction(ttt, function I)
call TimerStart(TIMER, .02, true, function D)
endfunction
endscope
Life Drain:
An aura that passively steals hp away from nearby enemies and give them to the Hero.
Code:
JASS:
scope LifeDrain initializer Run //-!Do Not Touch!-
globals
private constant integer ABILITYID = 039;A000039; //Ability Rawcode
private constant integer AREAOFEFFECT = 600 //The Area of Effect
private string array RANDOMEFFECT //These Effects Are Declared In initializer Run. These Effects Must Have A Birth Animation!
private real INTERVAL = 2 //The Amount Of Time Between The Life Drains.
private real MIN_AMOUNT = 2 //Formula = MIN_AMOUNT + MAX_AMOUNT * Level of ABILITYID of DRAINER
private real MAX_AMOUNT = 2 //2 + 2 * X by default
private integer MIN_TARGETS = 3 //Formula = MIN_TARGETS * Level of ABILITYID of DRAINER 3 * X by default
private integer NUMBEROFTARGETS = 0 //-!Do Not Touch!-
private group LIFEDRAINGROUP = CreateGroup() //-!Do Not Touch!-
private timer TIMER = CreateTimer() //-!Do Not Touch!-
private real AMOUNT = 0 //-!Do Not Touch!-
private unit DRAINER //-!Do Not Touch!-
endglobals
//===========================================================================
//=============//-!Do Not Touch Anything Below This Point!-==================
//===========================================================================
function B takes nothing returns boolean
return (GetLearnedSkill() == ABILITYID)
endfunction
private function E takes nothing returns nothing
call GroupRemoveUnit(LIFEDRAINGROUP, GetTriggerUnit())
endfunction
private function D takes nothing returns boolean
return (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) and (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.405) and (IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(DRAINER)) == true)
endfunction
function C takes nothing returns nothing
local real x = GetUnitX(DRAINER)
local real y = GetUnitY(DRAINER)
local integer i = 0
local unit u
call GroupEnumUnitsInRange(LIFEDRAINGROUP, x, y, AREAOFEFFECT, Filter(function D))
loop
set u = FirstOfGroup(LIFEDRAINGROUP)
exitwhen u == null
call DestroyEffect(AddSpecialEffectTarget(RANDOMEFFECT[GetRandomInt(0,6)], u, "chest"))
call UnitDamageTarget(DRAINER, u, AMOUNT, true, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_DIVINE, WEAPON_TYPE_WHOKNOWS)
call SetWidgetLife(DRAINER, GetWidgetLife(DRAINER) + AMOUNT)
call GroupRemoveUnit(LIFEDRAINGROUP, u)
set i = i + 1
if (i == NUMBEROFTARGETS) then
call GroupClear(LIFEDRAINGROUP)
set u = null
return
endif
endloop
set u = null
endfunction
function A takes nothing returns nothing
set DRAINER = GetTriggerUnit()
set NUMBEROFTARGETS = MIN_TARGETS * GetUnitAbilityLevel(DRAINER, ABILITYID)
set AMOUNT = MIN_AMOUNT + MAX_AMOUNT * GetUnitAbilityLevel(DRAINER, ABILITYID)
endfunction
//===========================================================================
function Run takes nothing returns nothing
local trigger t = CreateTrigger()
local trigger tt = CreateTrigger()
local integer i = 0
loop
exitwhen i == 16
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_HERO_SKILL, null)
call TriggerRegisterPlayerUnitEvent(tt, Player(i), EVENT_PLAYER_UNIT_DEATH, null)
set i = i + 1
endloop
call TriggerAddCondition(t, Condition( function B))
call TriggerAddAction(t, function A)
call TriggerAddAction(tt, function E)
call TimerStart(TIMER, INTERVAL, true, function C)
set RANDOMEFFECT[0] = "Objects\\Spawnmodels\\Orc\\Orcblood\\HeroShadowHunterBlood.mdl" //-Feel Free To Touch-
set RANDOMEFFECT[1] = "Objects\\Spawnmodels\\Orc\\Orcblood\\BattrollBlood.mdl"
set RANDOMEFFECT[2] = "Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodRifleman.mdl"
set RANDOMEFFECT[3] = "Objects\\Spawnmodels\\NightElf\\NightElfBlood\\NightElfBloodDruidRaven.mdl"
set RANDOMEFFECT[4] = "Objects\\Spawnmodels\\Orc\\Orcblood\\OrcBloodHeroFarSeer.mdl"
set RANDOMEFFECT[5] = "Objects\\Spawnmodels\\Undead\\UndeadBlood\\UndeadBloodGargoyle.mdl"
set RANDOMEFFECT[6] = "Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodKnight.mdl" //-Feel Free To Touch-
endfunction
endscope
Some Orb:
A custom orb effect.
This passive ability has a chance of hitting the enemy with a variety of spells, when attacking.
Clarification:
Passive ability. X% chance of occuring. Upon activation; creates a dummy, casts one out of Y (3, by default) spells on the target. Activates when a unit is attacked and takes damage by the Hero. (Not simply order attack.)
Code:
JASS:
scope SomeOrb initializer Run //-!Do Not Touch!-
globals
private constant integer ABILITYID = 039;A002039; //Ability Rawcode
private constant integer BUFFID = 039;B003039; //Buff Rawcode
private integer array ORBABILITY //Ability Rawcode of the Orb Effect. These Integers Are Declared In initializer Run.
private string array ORBORDER //Order String of the Orb Effect. These Strings Are Declared In initializer Run.
private integer DUMMYUNITID = 039;h001039; //Dummy Unit ID
private integer MAXNUMBEROFORBS = 3 //The max number of different Orb Effects.
private integer MAX_CHANCE = 8 //Formula = X = MAX_CHANCE - Level of ABILITYID of BUFFPLACER = 1 chance in X
//For Example: X = 8 - 1/2/3/4 = 7/6/5/4 = 1 chance in 7/6/5/4 ~ 14%/16%/20%/25%
private group ORBGROUP = CreateGroup() //-!Do Not Touch!-
private timer TIMER = CreateTimer() //-!Do Not Touch!-
private integer CHANCETOOCCUR //-!Do Not Touch!-
private integer ABILITYLEVEL //-!Do Not Touch!-
private unit BUFFPLACER //-!Do Not Touch!-
private integer OWNERID //-!Do Not Touch!-
endglobals
//===========================================================================
//=============//-!Do Not Touch Anything Below This Point!-==================
//===========================================================================
private function B takes nothing returns boolean
return (GetLearnedSkill() == ABILITYID)
endfunction
private function D takes nothing returns boolean
return (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) and (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.405) and (IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(BUFFPLACER)) == true)
endfunction
private function C takes nothing returns nothing
local real x = GetUnitX(BUFFPLACER)
local real y = GetUnitY(BUFFPLACER)
local integer r
local integer i
local unit u
local unit d
call GroupEnumUnitsInRange(ORBGROUP, x, y, 200, Filter(function D))
loop
set u = FirstOfGroup(ORBGROUP)
exitwhen u == null
set i = GetUnitAbilityLevel(u, BUFFID)
if (i != 0) then
set i = GetRandomInt(1, CHANCETOOCCUR)
if (i == 1) then
set r = GetRandomInt(1, MAXNUMBEROFORBS)
set d = CreateUnit(Player(OWNERID), DUMMYUNITID, x, y, 270)
call UnitApplyTimedLife(d, 039;BTLF039;, 3)
call UnitAddAbility(d, ORBABILITY[r])
call SetUnitAbilityLevel(d, ORBABILITY[r], ABILITYLEVEL)
call IssueTargetOrder(d, ORBORDER[r], u)
endif
endif
call GroupRemoveUnit(ORBGROUP, u)
endloop
set u = null
endfunction
private function A takes nothing returns nothing
set BUFFPLACER = GetTriggerUnit()
set ABILITYLEVEL = GetUnitAbilityLevel(BUFFPLACER, ABILITYID)
set OWNERID = GetPlayerId(GetOwningPlayer(BUFFPLACER))
set CHANCETOOCCUR = MAX_CHANCE - GetUnitAbilityLevel(BUFFPLACER, ABILITYID)
if (CHANCETOOCCUR < 1) then
set CHANCETOOCCUR = 1
endif
endfunction
//===========================================================================
private function Run takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
exitwhen i == 16
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_HERO_SKILL, null)
set i = i + 1
endloop
call TriggerAddCondition(t, Condition( function B))
call TriggerAddAction(t, function A)
call TimerStart(TIMER, .01, true, function C)
set ORBABILITY[1] = 039;A003039; //-Feel Free To Touch-
set ORBABILITY[2] = 039;A005039;
set ORBABILITY[3] = 039;A006039;
set ORBORDER[1] = "frostnova"
set ORBORDER[2] = "deathcoil"
set ORBORDER[3] = "chainlightning" //-Feel Free To Touch-
endfunction
endscope
Flash Step:
Bleach rip-off.
Grants X% chance of evading incoming attacks.
Blinks the Hero to position of target move/smart-order, if the distance between the Hero and the point is greater than 250 and less than Y. Costs 25 (by default) mana. 2 seconds cd (also by default.)
Code:
JASS:
scope FlashStep initializer Run //-!Do Not Touch!-
globals
private constant integer ABILITYID = 039;A004039; //Ability Rawcode
private real MINDISTANCE = 200 //Formula = MINDISTANCE + MINDISTANCE * Level of ABILITYID of FLASHUNIT
private constant string FIRSTSPECIALEFFECT = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl" //This Effect Must Have A Birth Animation!
private constant string SECONDSPECIALEFFECT = "Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl" //This Effect Must Have A Birth Animation!
private integer MANACOST = 25 //Mana cost of Flash Step
private real COOLDOWN = 2 //Cooldown time of Flash Step
private trigger FLASHTRIGGER = CreateTrigger() //-!Do Not Touch!-
private real MAXDISTANCE //-!Do Not Touch!-
private unit FLASHUNIT //-!Do Not Touch!-
endglobals
//===========================================================================
//=============//-!Do Not Touch Anything Below This Point!-==================
//===========================================================================
private function B takes nothing returns boolean
return (GetLearnedSkill() == ABILITYID)
endfunction
private function C takes nothing returns boolean
return (GetIssuedOrderId() == OrderId("smart")) or (GetIssuedOrderId() == OrderId("move"))
endfunction
private function E takes nothing returns nothing
call TriggerSleepAction(COOLDOWN)
call EnableTrigger(FLASHTRIGGER)
endfunction
private function D takes nothing returns nothing
local real currentmana = GetUnitState(FLASHUNIT, UNIT_STATE_MANA)
local real x = GetOrderPointX()
local real y = GetOrderPointY()
local real xx = GetUnitX(FLASHUNIT)
local real yy = GetUnitY(FLASHUNIT)
local real dx = x - xx
local real dy = y - yy
local real distance = SquareRoot(dx * dx + dy * dy)
if (currentmana > MANACOST) then
if (distance > 250) and (distance < MAXDISTANCE) then
call DestroyEffect(AddSpecialEffect(FIRSTSPECIALEFFECT, xx, yy))
call SetUnitPosition(FLASHUNIT, x, y)
call SetUnitState(FLASHUNIT, UNIT_STATE_MANA, currentmana - MANACOST)
call DestroyEffect(AddSpecialEffect(SECONDSPECIALEFFECT, x, y))
call DisableTrigger(FLASHTRIGGER)
call E.execute()
endif
endif
endfunction
private function A takes nothing returns nothing
set FLASHUNIT = GetTriggerUnit()
set MAXDISTANCE = MINDISTANCE + MINDISTANCE * GetUnitAbilityLevel(FLASHUNIT, ABILITYID)
call TriggerRegisterUnitEvent(FLASHTRIGGER, FLASHUNIT, EVENT_UNIT_ISSUED_POINT_ORDER)
call TriggerAddCondition(FLASHTRIGGER, Condition( function C))
call TriggerAddAction(FLASHTRIGGER, function D)
endfunction
//===========================================================================
private function Run takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
exitwhen i == 16
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_HERO_SKILL, null)
set i = i + 1
endloop
call TriggerAddCondition(t, Condition( function B))
call TriggerAddAction(t, function A)
endfunction
endscope
Demomap attached.
Feedback appriciated.