• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece!🔗 Click here to enter!

My Storm Earth and Fire

Status
Not open for further replies.
Level 13
Joined
Jan 2, 2016
Messages
973
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~
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
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'.
 
Status
Not open for further replies.
Top