This is probobly the most complicated skill I've intended to make until now. I couldn't have completed it without learning JASS.
I'm still working on it, so I decided to ask here for ideas/suggestions how to make it efficient, and bug free.
Skill describtion:
3 different unit types must cast 3 different 'parts' of the skill for it to run. The units are common, so players can have more than 1 of each type. So, when 2 of the units 'click' on the skill - they are "marked" or "chosen" to become 1 of the casters - the skill is disabled for the rest of the units of the type. When the 3-rd unit clicks the spell - it gets to select the area where the skill will be cast.
When this happens - the "chosen ones" move around the targeted point (they make a triangle around it) and when they reach "their" point - they begin chanelling. Player should become unable to command them!
~I can handle the effects afterwards~
The bottom trigger is the 1-st part of the spell - when a unit clicks the ability - the ability is disabled for the player (and the unit is replaced with a 'ward' unit)
When this trigger runs 2-nd time - besides disabling the ability for the player, it also disables the 3-rd ability, and enables the "cast" version of it - where the player can select the area it's cast at.
The trigger at the top runs when a unit casts the "cast" ability - it disables the "cast" ability for the player, replaces the last unit with a 'ward' and orders each of the "chosen" units to move towards their casting location.
At their casting location - I create a dummy, and add trigger with event "A unit gets in range (of the dummy)"
So... in that trigger I'm planing to check if the triggering unit is equal to the correct "chosen" unit, and if it is - I'll pause the unit, make it face the 'target point', and will play its cast/spell animation. (will also destroy the trigger and the dummy).
I will also make some triggers, that will run if a "chosen" unit dies, and stuff like that.
I am making this thread, asking for suggestions/opinions if there are any easier ways to make it work, and how to improve it 'generally'.
I'm still working on it, so I decided to ask here for ideas/suggestions how to make it efficient, and bug free.
Skill describtion:
3 different unit types must cast 3 different 'parts' of the skill for it to run. The units are common, so players can have more than 1 of each type. So, when 2 of the units 'click' on the skill - they are "marked" or "chosen" to become 1 of the casters - the skill is disabled for the rest of the units of the type. When the 3-rd unit clicks the spell - it gets to select the area where the skill will be cast.
When this happens - the "chosen ones" move around the targeted point (they make a triangle around it) and when they reach "their" point - they begin chanelling. Player should become unable to command them!
~I can handle the effects afterwards~
JASS:
function SEF_Begining takes nothing returns boolean
return false
endfunction
function SEF_Activation takes nothing returns boolean
local player p
local integer pn
local unit array sef
local integer i
local real x
local real y
local real tx
local real ty
local real ang
local integer b
local trigger tr
if GetIssuedOrderIdBJ() == String2OrderIdBJ("earthquake") then
set sef[0] = GetTriggerUnit()
set b = 0
if GetUnitAbilityLevel( sef[0], 'A02L') > 0 then
set b = 1
call SaveUnitHandle(udg_Table, pn, 'sefs', sef[0])
call UnitAddAbility(sef[0], 'A02U')
call UnitRemoveAbility(sef[0], 'A02U')
call SetPlayerAbilityAvailable( p, 'A02L', false )
elseif GetUnitAbilityLevel( sef[0], 'A02J') > 0 then
set b = 2
call SaveUnitHandle(udg_Table, pn, 'sefe', sef[0])
call UnitAddAbility(sef[0], 'A02T')
call UnitRemoveAbility(sef[0], 'A02T')
call SetPlayerAbilityAvailable( p, 'A02J', false )
elseif GetUnitAbilityLevel( sef[0], 'A02K') > 0 then
set b = 3
call SaveUnitHandle(udg_Table, pn, 'seff', sef[0])
call UnitAddAbility(sef[0], 'A02S')
call UnitRemoveAbility(sef[0], 'A02S')
call SetPlayerAbilityAvailable( p, 'A02K', false )
endif
if b > 0 then
set x = GetOrderPointX()
set y = GetOrderPointY()
set tx = GetUnitX(sef[0])
set ty = GetUnitY(sef[0])
set p = GetOwningPlayer(sef[0])
set pn = GetPlayerId(p)
set sef[1] = LoadUnitHandle(udg_Table, pn, 'sefs')
set sef[2] = LoadUnitHandle(udg_Table, pn, 'sefe')
set sef[3] = LoadUnitHandle(udg_Table, pn, 'seff')
set ang = Atan2(ty-y,tx-x)
set i = 1
loop
exitwhen i > 3
set tx = x+325*Cos(ang+(2*bj_PI*(b-i)/3))
set ty = y+325*Sin(ang+(2*bj_PI*(b-i)/3))
call IssuePointOrder(sef[i],"move",tx,ty)
set pn = GetHandleId(sef[i])
call SaveInteger(udg_Unit_Table, pn, 0, LoadInteger(udg_Unit_Table, pn, 0) + 1)
call SaveReal(udg_Unit_Table, pn, 'msux', tx)
call SaveReal(udg_Unit_Table, pn, 'msuy', ty)
call SaveReal(udg_Unit_Table, pn, 'mstx', x)
call SaveReal(udg_Unit_Table, pn, 'msty', y)
set sef[0] = CreateUnit(p, 'h00C', tx, ty, 0.00)
set tr = CreateTrigger()
call TriggerRegisterUnitInRangeSimple( tr, 50, sef[0] )
call SaveTriggerHandle(udg_Unit_Table, pn, 'mstr', tr)
call TriggerAddCondition(tr, Condition(function SEF_Begining))
set i = i + 1
endloop
set p = null
set tr = null
set sef[0] = null
set sef[1] = null
set sef[2] = null
set sef[3] = null
endif
set sef[0] = null
endif
return false
endfunction
//===========================================================================
function InitTrig_Storm_Earth_and_Fire_Activation takes nothing returns nothing
set gg_trg_Storm_Earth_and_Fire_Activation = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Storm_Earth_and_Fire_Activation, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerAddCondition( gg_trg_Storm_Earth_and_Fire_Activation, Condition( function SEF_Activation ) )
endfunction
JASS:
function Storm_Preperations takes player p, integer pn, integer i returns nothing
call SetPlayerAbilityAvailable( p, 'A02O', false )
call UnitAddAbility(GetTriggerUnit(), 'A02U')
call UnitRemoveAbility(GetTriggerUnit(), 'A02U')
call SaveUnitHandle(udg_Table, pn, 'sefs', GetTriggerUnit())
call SaveInteger(udg_Table, pn, 'sefc', i + 1)
if i == 1 then
if LoadUnitHandle(udg_Table, pn, 'sefe') == null then
call SetPlayerAbilityAvailable( p, 'A02M', false )
call SetPlayerAbilityAvailable( p, 'A02J', true )
else
call SetPlayerAbilityAvailable( p, 'A02N', false )
call SetPlayerAbilityAvailable( p, 'A02K', true )
endif
endif
set p = null
endfunction
function Earth_Preperations takes player p, integer pn, integer i returns nothing
call SetPlayerAbilityAvailable( p, 'A02M', false )
call UnitAddAbility(GetTriggerUnit(), 'A02T')
call UnitRemoveAbility(GetTriggerUnit(), 'A02T')
call SaveUnitHandle(udg_Table, pn, 'sefe', GetTriggerUnit())
call SaveInteger(udg_Table, pn, 'sefc', i + 1)
if i == 1 then
if LoadUnitHandle(udg_Table, pn, 'seff') == null then
call SetPlayerAbilityAvailable( p, 'A02N', false )
call SetPlayerAbilityAvailable( p, 'A02K', true )
else
call SetPlayerAbilityAvailable( p, 'A02O', false )
call SetPlayerAbilityAvailable( p, 'A02L', true )
endif
endif
set p = null
endfunction
function Fire_Preperations takes player p, integer pn, integer i returns nothing
call SetPlayerAbilityAvailable( p, 'A02N', false )
call UnitAddAbility(GetTriggerUnit(), 'A02S')
call UnitRemoveAbility(GetTriggerUnit(), 'A02S')
call SaveUnitHandle(udg_Table, pn, 'seff', GetTriggerUnit())
call SaveInteger(udg_Table, pn, 'sefc', i + 1)
if i == 1 then
if LoadUnitHandle(udg_Table, pn, 'sefe') == null then
call SetPlayerAbilityAvailable( p, 'A02M', false )
call SetPlayerAbilityAvailable( p, 'A02J', true )
else
call SetPlayerAbilityAvailable( p, 'A02O', false )
call SetPlayerAbilityAvailable( p, 'A02L', true )
endif
endif
set p = null
endfunction
function SEF_Preperations takes nothing returns boolean
local player p
local integer pn
local integer i
if GetIssuedOrderIdBJ() == String2OrderIdBJ("howlofterror") then
if GetUnitAbilityLevelSwapped('A02O', GetTriggerUnit()) > 0 then
set p = GetOwningPlayer(GetTriggerUnit())
set pn = GetPlayerId(p)
set i = LoadInteger(udg_Table, pn, 'sefc')
call Storm_Preperations(p, pn, i)
set p = null
elseif GetUnitAbilityLevelSwapped('A02M', GetTriggerUnit()) > 0 then
set p = GetOwningPlayer(GetTriggerUnit())
set pn = GetPlayerId(p)
set i = LoadInteger(udg_Table, pn, 'sefc')
call Earth_Preperations(p, pn, i)
set p = null
elseif GetUnitAbilityLevelSwapped('A02N', GetTriggerUnit()) > 0 then
set p = GetOwningPlayer(GetTriggerUnit())
set pn = GetPlayerId(p)
set i = LoadInteger(udg_Table, pn, 'sefc')
call Fire_Preperations(p, pn, i)
set p = null
endif
endif
return false
endfunction
//===========================================================================
function InitTrig_Storm_Earth_and_Fire_Preperations takes nothing returns nothing
set gg_trg_Storm_Earth_and_Fire_Preperations = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Storm_Earth_and_Fire_Preperations, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerAddCondition( gg_trg_Storm_Earth_and_Fire_Preperations, Condition( function SEF_Preperations ) )
endfunction
When this trigger runs 2-nd time - besides disabling the ability for the player, it also disables the 3-rd ability, and enables the "cast" version of it - where the player can select the area it's cast at.
The trigger at the top runs when a unit casts the "cast" ability - it disables the "cast" ability for the player, replaces the last unit with a 'ward' and orders each of the "chosen" units to move towards their casting location.
At their casting location - I create a dummy, and add trigger with event "A unit gets in range (of the dummy)"
So... in that trigger I'm planing to check if the triggering unit is equal to the correct "chosen" unit, and if it is - I'll pause the unit, make it face the 'target point', and will play its cast/spell animation. (will also destroy the trigger and the dummy).
I will also make some triggers, that will run if a "chosen" unit dies, and stuff like that.
I am making this thread, asking for suggestions/opinions if there are any easier ways to make it work, and how to improve it 'generally'.