• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Gas Grenade

Status
Not open for further replies.
We could just create a dummy invisible unit that will act as the damager but I do not like creating more things then necessary.

Agree ..

Anyway, I am mad to announce that it doesn't work ... the same bug as always ... why ?! no idea ... I still Have 1 trick, if everything else fails, but i really don't wanna use because it will be way less efficient.

Anyway, you have the map here ... I think I did it as I should ...

It has your newest code.
 

Attachments

  • Plane !.w3x
    118.1 KB · Views: 42
Level 29
Joined
Jul 29, 2007
Messages
5,174
It was again the dying unit problem.
Don't know what it was this time but creating a dummy unit made it work.

Here is the new code.
JASS:
function GasBombsConditions takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit()) == 'h000'
endfunction
//===========================================================================
function GasTimer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleInt(t, "i")
    local unit bombdummy = GetHandleUnit(t, "bombdummy")
    local real x = GetHandleReal(t, "x")
    local real y = GetHandleReal(t, "y")
    local group g = CreateGroup()
    local unit u
    local unit dummyOne
    local unit dummyTwo
    call GroupEnumUnitsInRange(g, x, y, 250, null)
//******************//
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call GroupRemoveUnit(g, u)
        if IsUnitEnemy(u, GetOwningPlayer(bombdummy)) == true and IsUnitType(u, UNIT_TYPE_MECHANICAL) == false and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) == false then
            call UnitDamageTarget(bombdummy, u, 12.5, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
            // **** dummies part ****
            set dummyOne = CreateUnit(GetOwningPlayer(bombdummy), 'h001', x, y, 0)
            set dummyTwo = CreateUnit(GetOwningPlayer(bombdummy), 'h001', x, y, 0)
            call UnitAddAbility(dummyOne, 'A002')
            call UnitAddAbility(dummyOne, 'A004')
            call IssueTargetOrder(dummyOne, "curse", u)
            call IssueTargetOrder(dummyTwo, "slow", u)
            call UnitApplyTimedLife(dummyOne, 'BTLF', .5)
            call UnitApplyTimedLife(dummyTwo, 'BTLF', .5)
            set dummyOne = null
            set dummyTwo = null
            // **** end dummies part ****
        endif
    endloop
//******************//
    if i == 20 then // when i = 20 the time that passed is 10 seconds
        call FlushHandleLocals(t)
        call DestroyTimer(t)
        call RemoveUnit(bombdummy)
    endif
    call SetHandleInt(t, "i", i + 1)
    set t = null
    call DestroyGroup(g)
    set g = null
    set bombdummy = null
endfunction
//=========================================================
function GasBombsActions takes nothing returns nothing
    local timer t = CreateTimer()
    local integer i = 0
    local real x = GetUnitX(GetTriggerUnit())
    local real y = GetUnitY(GetTriggerUnit())
    local unit bombdummy = CreateUnit(GetOwningPlayer(GetTriggerUnit()), 'h001', x, y, 0)
    local effect e = AddSpecialEffect("war3mapImported\\Radioactivecloud.mdx", x, y)
    call SetHandleHandle(t, "bombdummy", bombdummy)
    call SetHandleReal(t, "x", x)
    call SetHandleReal(t, "y", y)
    call SetHandleInt(t, "i", i)
    call TimerStart(t, 0.5, true, function GasTimer)
    call TriggerSleepAction(10)
    call DestroyEffect(e)
    set bombdummy = null
    set e = null
    set t = null
endfunction
//===========================================================================
function InitTrig_Gas_Bombs takes nothing returns nothing
    set gg_trg_Gas_Bombs = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Gas_Bombs, EVENT_PLAYER_UNIT_DEATH)
    call TriggerAddCondition(gg_trg_Gas_Bombs, Condition(function GasBombsConditions))
    call TriggerAddAction( gg_trg_Gas_Bombs, function GasBombsActions )
endfunction
 
Level 6
Joined
Jun 30, 2006
Messages
230
This trigger really should use structs, and I'll be more than happy to teach you when you get your MSN ready. Structs are easier than attaching one thing at a time, I think. Plus it looks nicer, as well as easier to transfer between maps. And since structs are part of vJASS, might as well a few tips and tricks while we are at it! Don't get overwhelmed, it's actually quite simple. You'll see when we get started.

If you want to, we can reverse GhostWolf's from this to structs, especially since we already have the answer key ;)
 
Level 6
Joined
Jun 30, 2006
Messages
230
The gamecache is slow, man. A struct is so much faster. It's not even close. This is one of the main reasons Handle Vars isn't as good as Cohadar's ABC or Vexorian's stuff. With structs you only have to do 1 attachment, and that speeds things up even if you use Handle Vars. But the afore mentioned systems are even faster than that...

So yeah, storing i in the struct is better.
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
Cant raised is important (LoL if you dont, it will be raised with resuraction)

And for using structs
(make sure you have your WE syntax checking disabled in grimoire and you have lastest version)

Create a trigger
and put following part into it (doesnt need to be on header etc)
JASS:
library TimerAttachment
//
globals
private integer array i1
private integer array i2
private integer array i3
endglobals
//
private function H2I takes handle h returns integer
return h
return 0
endfunction
//
function SetTimerStruct takes timer t, integer s returns nothing
local integer i = H2I(t)-0x100000
if i <= 8000 then
set i1[i] = s
elseif i > 8000 and <= 16000 then
set i2[i] = s-8000
elseif i > 16000 and <= 24000 then
set i3[i] = s-16000
elseif i > 24000 then
call BJDebugMsg("Warning index is too high")
endif
endfunction
//
function GetTimerStruct takes timer t returns integer
local integer i = H2I(t)-0x100000
if i <= 8000 then
return i1[i]
elseif i > 8000 and <= 16000 then
return i2[i]
elseif i > 16000 and <= 24000 then
return i3[i]
elseif i > 24000 then
call BJDebugMsg("Warning index is too high")
endif
endfunction
//
endlibrary

well its normal set INTEGERVAR[H2I(h)] = S
but it makes it
INTEGERVAR1
INTEGERVAR2
INTEGERVAR3
So I you can keep about 200000 timers alive in same time instead of 80000
I think ABC does the same thing :/

JASS:
struct GasbombS
unit u
real x
real y
integer i
group g // just for increasing speed. I'll repleace the members of group each time instead of creating a new group each time
endstruct
//
function GasBombsConditions takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit()) == 'h000'
endfunction
//===========================================================================
function GasTimer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local GasbombS a = GetTimerStruct(t) //you may make it b too it doesnt metter 
    local integer i = a.i
    local unit bombdummy = a.u
    local real x = a.x
    local real y = a.y
    local unit u
    local unit dummyOne
    local unit dummyTwo
    local group g = a.g
    call GroupEnumUnitsInRange(g, x, y, 250, null)
//******************//
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call GroupRemoveUnit(g, u)
        if IsUnitEnemy(u, GetOwningPlayer(bombdummy)) == true and IsUnitType(u, UNIT_TYPE_MECHANICAL) == false and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) == false then
            call UnitDamageTarget(bombdummy, u, 12.5, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
            // **** dummies part ****
            set dummyOne = CreateUnit(GetOwningPlayer(bombdummy), 'h001', x, y, 0)
            set dummyTwo = CreateUnit(GetOwningPlayer(bombdummy), 'h001', x, y, 0)
            call UnitAddAbility(dummyOne, 'A002')
            call UnitAddAbility(dummyOne, 'A004')
            call IssueTargetOrder(dummyOne, "curse", u)
            call IssueTargetOrder(dummyTwo, "slow", u)
            call UnitApplyTimedLife(dummyOne, 'BTLF', .5)
            call UnitApplyTimedLife(dummyTwo, 'BTLF', .5)
            set dummyOne = null
            set dummyTwo = null
            // **** end dummies part ****
        endif
    endloop
//******************//
    if i == 20 then // when i = 20 the time that passed is 10 seconds
        call a.destroy()
        call DestroyTimer(t)
        call RemoveUnit(bombdummy)
        call DestroyGroup(g)
    endif
    set a.i = a.i+1
    set t = null
    set g = null
    set bombdummy = null
endfunction
//=========================================================
function GasBombsActions takes nothing returns nothing
    local timer t = CreateTimer()
    local integer i = 0
    local GasbombS a = GasbombS.create()
    local real x = GetUnitX(GetTriggerUnit())
    local real y = GetUnitY(GetTriggerUnit())
    local unit bombdummy = CreateUnit(GetOwningPlayer(GetTriggerUnit()), 'h001', x, y, 0)
    local effect e = AddSpecialEffect("war3mapImported\\Radioactivecloud.mdx", x, y)
    set a.u = bombdummy
    set a.x = x
    set a.y = y
    set a.i = i
    set a.g = CreateGroup()
    call SetTimerStruct(t,a)
    call TimerStart(t, 0.5, true, function GasTimer)
    call TriggerSleepAction(10)
    call DestroyEffect(e)
    set bombdummy = null
    set e = null
    set t = null
endfunction
//===========================================================================
function InitTrig_Gas_Bombs takes nothing returns nothing
    set gg_trg_Gas_Bombs = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Gas_Bombs, EVENT_PLAYER_UNIT_DEATH)
    call TriggerAddCondition(gg_trg_Gas_Bombs, Condition(function GasBombsConditions))
    call TriggerAddAction( gg_trg_Gas_Bombs, function GasBombsActions )
endfunction

Well. Structs kinda using global variables. Thats why its faster...
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
The gamecache is slow, man. A struct is so much faster. It's not even close. This is one of the main reasons Handle Vars isn't as good as Cohadar's ABC or Vexorian's stuff. With structs you only have to do 1 attachment, and that speeds things up even if you use Handle Vars. But the afore mentioned systems are even faster than that...

So yeah, storing i in the struct is better.

Yes, but instead of just storing i, I need to store x,y,bomb,e,i.
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
I have one as I remember...
GET A MSN (I think you can use gmail on msn with a way. let me search I think you enter your gmail to there and get able to enter msn with your gmail... goodluck)
 
Level 5
Joined
Aug 16, 2007
Messages
149
by the way, if you ever want to optimize code, just take the original code and use Vexorian's map optimizer... much quicker than doing it manually!
 
Level 6
Joined
Jun 30, 2006
Messages
230
It will get rid of wrapper BJ's, I do believe. It's still not the same as doing it yourself, sometimes it creates unnecessary variables depending on the situation, and there's just something about doing it yourself.
 
Status
Not open for further replies.
Top