• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Jass Arrow Rain + Blizzard, reply pls :D

Status
Not open for further replies.
Level 17
Joined
Nov 13, 2006
Messages
1,814
i am just curios if have something wrong, or it is efficient (exclude i dont use 1 timer for all channel ability)

since both channel based ability, i mean based on check hero order and drain mana so cant cast same time 2 channel based ability

1 - arrow rain, create 5 arrow each sec, going to top then after a short delay falling down but more arrow / sec and deal dmg in target area

Sylvanis got in demo map

2. - blizzard, cast blizzard in target area, and who stay in area longer than 1 sec get movement speed reduction buff (i solved this with creating a dummy unit in ability target point with slow aura tornado ability :D)

i attached the map

if somebody dont got time for check it then here the jass

arrow rain
JASS:
function Trig_Arrow_Rain_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'ANcl'
endfunction

function ArrowUpDown takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local unit u = LoadUnitHandle(udg_Channel_Table, id, 1)
    local unit u1
    local unit pu
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real mana = GetUnitState(u, UNIT_STATE_MANA)
    local integer i = 0
    local integer cv = GetUnitUserData(u)
    local string s = OrderId2String(GetUnitCurrentOrder(u))
     
    set udg_Channel_Dur[cv] = udg_Channel_Dur[cv] + 0.2

    if mana >= udg_Channel_ManaCost[cv] and s == "channel" then
        set udg_Channel_Count[cv] = udg_Channel_Count[cv] + 1
        if I2R(R2I(udg_Channel_Dur[cv] + 1)) == udg_Channel_Dur[cv] then
            call SetUnitState (u, UNIT_STATE_MANA, (mana - udg_Channel_ManaCost[cv]))
        endif
        loop
            exitwhen i > 2
            set u1 = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'h000', x + GetRandomInt(0, 100) * Cos(GetRandomReal(0, 360.00) * bj_DEGTORAD) , y + GetRandomInt(0, 100) * Sin(GetRandomReal(0, 360.00) * bj_DEGTORAD), 0)
            call SetUnitFlyHeight(u1, 1500.00, 1200 )
            call UnitApplyTimedLife(u1, 'BTLF', 1.00 )
            set i = i + 1
        endloop
    endif

    if udg_Channel_Dur[cv] > 1.4 then
        set udg_Channel_Count[cv] = udg_Channel_Count[cv] - 1
        set x = udg_Channel_X[cv]
        set y = udg_Channel_Y[cv]
        if I2R(R2I(udg_Channel_Dur[cv] + 1)) == udg_Channel_Dur[cv] then
            call GroupEnumUnitsInRange(udg_UG, x, y, 250.00, null)
            loop
                set pu = FirstOfGroup(udg_UG)
                exitwhen (pu==null)
                if IsUnitEnemy(pu, GetOwningPlayer(u)) then
                    call UnitDamageTarget(u, pu, udg_Channel_Dmg[cv], true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                endif
                call GroupRemoveUnit(udg_UG, pu)
            endloop
        endif
        set i = 0
        loop
            exitwhen i > 4

            set u1 = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'h001', udg_Channel_X[cv] + GetRandomInt(0, 250) * Cos(GetRandomReal(0, 360.00) * bj_DEGTORAD) , udg_Channel_Y[cv] + GetRandomInt(0, 250) * Sin(GetRandomReal(0, 360.00) * bj_DEGTORAD), 0)
            call SetUnitFlyHeight( u1, GetRandomReal(5.00, 40.00), 1500 )
            call UnitApplyTimedLife( u1, 'BTLF', 2.00 )
            set i = i + 1
        endloop
    endif

    if udg_Channel_Count[cv] == 0 then
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(udg_Channel_Table, id)
        if udg_Channel_CasterSF[cv] != null then
            call IssueImmediateOrder( u, "stop" )
            call DestroyEffect(udg_Channel_CasterSF[cv])
        endif
    else
        call TimerStart(t, 0.2, false, function ArrowUpDown)
    endif

    set t = null
    set u = null
    set u1 = null
    set s = null
    set pu = null
endfunction

function Trig_Arrow_Rain_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local real x = GetSpellTargetX()
    local real y = GetSpellTargetY()
    local real dmg = 100.00
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)
    local integer cv = GetUnitUserData(u)
    set udg_Channel_X[cv] = x
    set udg_Channel_Y[cv] = y
    set udg_Channel_ManaCost[cv] = 10
    set udg_Channel_Dmg[cv] = dmg
    if GetUnitState(u, UNIT_STATE_MANA) >= 10 then
        set udg_Channel_Count[cv] = 0
        set udg_Channel_Dur[cv] = 0
        call SaveUnitHandle(udg_Channel_Table, id, 1, u)
        call TimerStart(t, 0.2, false, function ArrowUpDown)
        set udg_Channel_CasterSF[cv] = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl", u, "origin")
    endif
    set t = null
    set u = null
endfunction

//===========================================================================
function InitTrig_Arrow_Rain takes nothing returns nothing
    set gg_trg_Arrow_Rain = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Arrow_Rain, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Arrow_Rain, Condition( function Trig_Arrow_Rain_Conditions ) )
    call TriggerAddAction( gg_trg_Arrow_Rain, function Trig_Arrow_Rain_Actions )
endfunction

blizzard

JASS:
function Trig_Blizzard_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00A'
endfunction

function BlizzardTimer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local unit u = LoadUnitHandle(udg_Channel_Table, id, 1)
    local integer cv = GetUnitUserData(u)
    local unit pu
    local real x = udg_Channel_X[cv]
    local real y = udg_Channel_Y[cv]
    local real mana = GetUnitState(u, UNIT_STATE_MANA)
    local integer i = 0
    local string s = OrderId2String(GetUnitCurrentOrder(u))
     
    set udg_Channel_Dur[cv] = udg_Channel_Dur[cv] + 1

    if mana >= udg_Channel_ManaCost[cv] and s == "blizzard" then
        set udg_Channel_Count[cv] = udg_Channel_Count[cv] + 1
        call SetUnitState (u, UNIT_STATE_MANA, (mana - udg_Channel_ManaCost[cv]))
        loop
            exitwhen i > 15
            call DestroyEffect(AddSpecialEffect ("Abilities\\Spells\\Human\\Blizzard\\BlizzardTarget.mdl", x + 250 * Cos(GetRandomReal(0, 360.00) * bj_DEGTORAD) , y + 250 * Sin(GetRandomReal(0, 360.00) * bj_DEGTORAD)))
            set i = i + 1
        endloop
    endif

    if udg_Channel_Dur[cv] > 1 then
        if udg_Channel_Unit[cv] == null then
            set udg_Channel_Unit[cv] = CreateUnit (GetOwningPlayer(u), 'o000', x, y, 0)
        endif
        set udg_Channel_Count[cv] = udg_Channel_Count[cv] - 1
        call GroupEnumUnitsInRange(udg_UG, x, y, 300.00, null)
            loop
                set pu = FirstOfGroup(udg_UG)
                exitwhen (pu==null)
                if IsUnitEnemy(pu, GetOwningPlayer(u)) then
                    call UnitDamageTarget(u, pu, udg_Channel_Dmg[cv], true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                endif
                call GroupRemoveUnit(udg_UG, pu)
            endloop
    endif

    if udg_Channel_Count[cv] == 0 then
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(udg_Channel_Table, id)
        if udg_Channel_CasterSF[cv] != null then
            call IssueImmediateOrder( u, "stop" )
            call DestroyEffect(udg_Channel_CasterSF[cv])

        endif
        if udg_Channel_Unit[cv] != null then
            call RemoveUnit (udg_Channel_Unit[cv])
            set udg_Channel_Unit[cv] = null
        endif
    else
        call TimerStart(t, 1, false, function BlizzardTimer)
    endif

    set t = null
    set u = null
    set s = null
    set pu = null
endfunction

function Trig_Blizzard_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local real x = GetSpellTargetX()
    local real y = GetSpellTargetY()
    local real radius = 300.00
    local real dmg = 100.00
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)
    local integer cv = GetUnitUserData(u)
    set udg_Channel_X[cv] = x
    set udg_Channel_Y[cv] = y
    set udg_Channel_ManaCost[cv] = 10
    set udg_Channel_Dmg[cv] = dmg
    if GetUnitState(u, UNIT_STATE_MANA) >= 10 then
        set udg_Channel_Count[cv] = 0
        set udg_Channel_Dur[cv] = 0
        call SaveUnitHandle(udg_Channel_Table, id, 1, u)
        call TimerStart(t, 0.5, false, function BlizzardTimer)
        set udg_Channel_CasterSF[cv] = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl", u, "origin")
    endif
    set t = null
    set u = null
endfunction

//===========================================================================
function InitTrig_Blizzard takes nothing returns nothing
    set gg_trg_Blizzard = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Blizzard, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Blizzard, Condition( function Trig_Blizzard_Conditions ) )
    call TriggerAddAction( gg_trg_Blizzard, function Trig_Blizzard_Actions )
endfunction
 

Attachments

  • arrowrain.w3x
    56.3 KB · Views: 64
Level 18
Joined
Jan 21, 2006
Messages
2,552
I really recommend you download JNGP and use vJass. It provides you with structs, which are really helpful in organizing your code in situations like this (rather than being a list of functions).

In terms of the code itself, I didn't see anything that really needs much attention. It seems to be clearing all its handles and cleaning up all the memory properly.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Well, if you want you can setup a faster allocation/deallocation by implementing the ID-stack yourself to grab unique IDs (without having to do the so called, "inefficient" part).

JASS:
struct custom extends array
	
	static integer objcount = 0
	thistype next

	method deallocate takes nothing returns nothing
		set next = thistype[0].next
		set thistype[0].next = this
	endmethod
	
	static method allocate takes nothing returns thistype
		local thistype t = thistype[0].next
		if (t == 0) then
			set t = objcount + 1
			set objcount = t
		else
			set thistype[0].next = thistype[0].next.next
		endif
		return (t)
	endmethod
	
endstruct

Something like this.

But, on another note, you really shouldn't worry about premature optimization. If there is something you need to be exclusively quick (a core system detail) then you should worry about optimization. For development, you're going to spend a lot of unnecessary time optimizing scripts that do not need to be optimized. It is something you should consider after you've got a solid foundation.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Well, if you want you can setup a faster allocation/deallocation by implementing the ID-stack yourself to grab unique IDs (without having to do the so called, "inefficient" part).

JASS:
struct custom extends array
	
	static integer objcount = 0
	thistype next

	method deallocate takes nothing returns nothing
		set next = thistype[0].next
		set thistype[0].next = this
	endmethod
	
	static method allocate takes nothing returns thistype
		local thistype t = thistype[0].next
		if (t == 0) then
			set t = objcount + 1
			set objcount = t
		else
			set thistype[0].next = thistype[0].next.next
		endif
		return (t)
	endmethod
	
endstruct

Something like this.

But, on another note, you really shouldn't worry about premature optimization. If there is something you need to be exclusively quick (a core system detail) then you should worry about optimization. For development, you're going to spend a lot of unnecessary time optimizing scripts that do not need to be optimized. It is something you should consider after you've got a solid foundation.

ok just i made a spellpack, and when i posted i got alot usefull comment about what can i replace for work better/more accurated, less cpu usage, so i dont want allways post to spell section if spell still got many thing what i must modify

this arrow rain also from spell pack, and one of the most harder from simple spells (because here need to use more thing than in other spells in my spellpack)
http://www.hiveworkshop.com/forums/spells-569/simple-spellpack-jass-209360/?prev=r=20&page=5

if possible i dont wnna use vjass yet, later when i doing the terrain part then i must use, but atm for me the normal we is more handy, ty the response
 
Status
Not open for further replies.
Top