Monday, April 16, 2012

Conditions and locals... again. LoL!

Hello once again. I feel like an idiot for doing this but: I have a trigger which uses 1 trigger condition (this one is NOT the problem) and 2 Action Conditions (one boolean using an "and". (These 2 make out the problem)). I'm once again having difficulties JASSing it and making the variables local. And it's once again the f*cking conditions' fault :D

O = working GUI

O = working JASS

O = failing jass

GUI: (works)


Code:
Smoke Bomb Copy
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Smoke Bomb
Actions
Set u1 = (Triggering unit)
Set p = (Target point of ability being cast)
Unit - Create 1 Smoke Bomb Dummy for (Owner of u1) at p facing Default building facing degrees
Unit - Add a 8.00 second Generic expiration timer to (Last created unit)
For each (Integer A) from 1 to 16, do (Actions)
Loop - Actions
Unit Group - Pick every unit in (Units within 125.00 of p matching ((((Matching unit) belongs to an ally of (Owner of u1)) Equal to True) and ((Unit-type of (Matching unit)) Not equal to Shaman))) and do (Actions)
Loop - Actions
Unit - Create 1 Shaman for (Owner of u1) at (Position of (Picked unit)) facing Default building facing degrees
Unit - Add a 0.25 second Generic expiration timer to (Last created unit)
Unit - Order (Last created unit) to Human Sorceress - Invisibility (Picked unit)
Wait 0.35 seconds



JASS: (working version)


Code:
function Trig_Smoke_Bomb_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A005' ) ) then
return false
endif
return true
endfunction

function Trig_Smoke_Bomb_Func005Func001001003001 takes nothing returns boolean
return ( IsUnitAlly(GetFilterUnit(), GetOwningPlayer(udg_u1)) == true )
endfunction

function Trig_Smoke_Bomb_Func005Func001001003002 takes nothing returns boolean
return ( GetUnitTypeId(GetFilterUnit()) != 'oshm' )
endfunction

function Trig_Smoke_Bomb_Func005Func001001003 takes nothing returns boolean
return GetBooleanAnd( Trig_Smoke_Bomb_Func005Func001001003001(), Trig_Smoke_Bomb_Func005Func001001003002() )
endfunction

function Trig_Smoke_Bomb_Func005Func001A takes nothing returns nothing
call CreateNUnitsAtLoc( 1, 'oshm', GetOwningPlayer(udg_u1), GetUnitLoc(GetEnumUnit()), bj_UNIT_FACING )
call UnitApplyTimedLifeBJ( 0.25, 'BTLF', GetLastCreatedUnit() )
call IssueTargetOrderBJ( GetLastCreatedUnit(), "invisibility", GetEnumUnit() )
endfunction

function Trig_Smoke_Bomb_Actions takes nothing returns nothing
set udg_u1 = GetTriggerUnit()
set udg_p = GetSpellTargetLoc()
call CreateNUnitsAtLoc( 1, 'o003', GetOwningPlayer(udg_u1), udg_p, bj_UNIT_FACING )
call UnitApplyTimedLifeBJ( 8.00, 'BTLF', GetLastCreatedUnit() )
set bj_forLoopAIndex = 1
set bj_forLoopAIndexEnd = 16
loop
exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
call ForGroupBJ( GetUnitsInRangeOfLocMatching(125.00, udg_p, Condition(function Trig_Smoke_Bomb_Func005Func001001003)), function Trig_Smoke_Bomb_Func005Func001A )
call TriggerSleepAction( 0.35 )
set bj_forLoopAIndex = bj_forLoopAIndex + 1
endloop
endfunction

//===========================================================================
function InitTrig_Smoke_Bomb takes nothing returns nothing
set gg_trg_Smoke_Bomb = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Smoke_Bomb, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Smoke_Bomb, Condition( function Trig_Smoke_Bomb_Conditions ) )
call TriggerAddAction( gg_trg_Smoke_Bomb, function Trig_Smoke_Bomb_Actions )
endfunction



JASS: (not so working)


Code:
function Trig_Smoke_Bomb_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A005' ) ) then
return false
endif
return true
endfunction

function Trig_Smoke_Bomb_Func005Func001A takes nothing returns nothing
call CreateNUnitsAtLoc( 1, 'oshm', GetOwningPlayer(udg_u1), GetUnitLoc(GetEnumUnit()), bj_UNIT_FACING )
call UnitApplyTimedLifeBJ( 0.25, 'BTLF', GetLastCreatedUnit() )
call IssueTargetOrderBJ( GetLastCreatedUnit(), "invisibility", GetEnumUnit() )
endfunction

function Trig_Smoke_Bomb_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local location p = GetSpellTargetLoc()
local integer i = 1
call CreateNUnitsAtLoc( 1, 'o003', GetOwningPlayer(u), p, bj_UNIT_FACING )
call UnitApplyTimedLifeBJ( 8.00, 'BTLF', GetLastCreatedUnit() )
loop
exitwhen i > 16
call ForGroupBJ( GetUnitsInRangeOfLocMatching(125.00, p, ( IsUnitAlly(GetFilterUnit(), GetOwningPlayer(u)) == true ), ( GetUnitTypeId(GetFilterUnit()) != 'oshm' )
call TriggerSleepAction( 0.35 )
set i = i + 1
endloop
endfunction

//===========================================================================
function InitTrig_Smoke_Bomb takes nothing returns nothing
set gg_trg_Smoke_Bomb = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Smoke_Bomb, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Smoke_Bomb, Condition( function Trig_Smoke_Bomb_Conditions ) )
call TriggerAddAction( gg_trg_Smoke_Bomb, function Trig_Smoke_Bomb_Actions )
endfunction

notes: 'oshm' or "Shaman" in the GUI is a dummy and it was causing BIIIIIG lags if it got invisibility cast on it (or something, it caused lags as long as it wasnt sorted out with a boolean), hence the 2 conditions.

I also want to work in
Code:
function Trig_Smoke_Bomb_Func005Func001A takes nothing returns nothing
call CreateNUnitsAtLoc( 1, 'oshm', GetOwningPlayer(udg_u1), GetUnitLoc(GetEnumUnit()), bj_UNIT_FACING )
call UnitApplyTimedLifeBJ( 0.25, 'BTLF', GetLastCreatedUnit() )
call IssueTargetOrderBJ( GetLastCreatedUnit(), "invisibility", GetEnumUnit() )
endfunction

into this line:
Code:
Unit Group - Pick every unit in (Units within 125.00 of p matching ((((Matching unit) belongs to an ally of (Owner of u1)) Equal to True) and ((Unit-type of (Matching unit)) Not equal to Shaman))) and do (Actions)

so that the same line picks all units within 125 of a local point that are allies to a local unit, and casts invisibility on them.|||If you look in Blizzard.j, you'll find that GetUnitsInRangeOfLocMatching is defined as:

function GetUnitsInRangeOfLocMatching takes real radius, location whichLocation, boolexpr filter returns group

The important argument here is 'boolexpr filter'. You can not simply pass a boolean value to it and expect it to work. What you want is a boolexpr returned by the native 'Condition'. You CANNOT inline a boolexpr. Here's the code you want:


Code:
function Trig_Smoke_Bomb_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A005' ) ) then
return false
endif
return true
endfunction

function SmokeBombBxprFunc takes nothing returns boolean
return ( ( IsUnitAlly(GetFilterUnit(), GetOwningPlayer(u)) ) and ( GetUnitTypeId(GetFilterUnit()) != 'oshm' ) )
endfunction

function SmokeBombCallbackFunc takes nothing returns nothing
set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer(udg_u1), 'oshm', GetUnitX(GetEnumUnit()), GetUnitY(GetEnumUnit()), bj_UNIT_FACING )
call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 0.25 )
call IssueTargetOrder( bj_lastCreatedUnit, "invisibility", GetEnumUnit() )
endfunction

function Trig_Smoke_Bomb_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local location p = GetSpellTargetLoc()
local boolexpr bxpr = Condition( function SmokeBombBxprFunc )
local integer i = 1
set bj_lastCreatedUnit = CreateUnitAtLoc( GetOwningPlayer(u), 'o003', p, bj_UNIT_FACING )
call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 8.00 )
loop
exitwhen i > 16
set bj_wantDestroyGroup = true
call ForGroupBJ( GetUnitsInRangeOfLocMatching(125.00, p, bxpr)
call TriggerSleepAction( 0.35 )
set i = i + 1
endloop
call RemoveLocation(p)
call DestroyBoolExpr(bxpr)
set u = null
set p = null
set bxpr = null
endfunction

//===========================================================================
function InitTrig_Smoke_Bomb takes nothing returns nothing
set gg_trg_Smoke_Bomb = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Smoke_Bomb, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Smoke_Bomb, Condition( function Trig_Smoke_Bomb_Conditions ) )
call TriggerAddAction( gg_trg_Smoke_Bomb, function Trig_Smoke_Bomb_Actions )
endfunction
|||okay. However, this seem to require "local unit u" to be a global though 'cause the first error I get is "expected a name" on
Code:
function SmokeBombBxprFunc takes nothing returns boolean
return ( ( IsUnitAlly(GetFilterUnit(), GetOwningPlayer(u)) ) and ( GetUnitTypeId(GetFilterUnit()) != 'oshm' ) )
endfunction

that function :S

I really need this to be local cause the trigger will run in multiple instances at the same time.

But I noticed you used a global in
Code:
    set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer(udg_u1), 'oshm', GetUnitX(GetEnumUnit()), GetUnitY(GetEnumUnit()), bj_UNIT_FACING )

is that a mistake from your side or is "udg_u1" intended to be local? or is the local in the last code intended to be GLOBAL?

'cause if it's intended to be global I'm afraid I can't use the trigger :( :S

Im sorry if i'm being a pain in the a$$ :P|||Sorry, my bad, replace u with GetTriggerUnit() in the SmokeBombBxprFunc function. As for udg_u1, I only used it because you used it in your version of that code. I don't know to what it refers.

EDIT: Also, GetTriggerUnit() does not break multi-instanceability, even after a delay.|||sweet :P

u1 is supposed to be the triggering unit. But if i've got this right I can use (Triggering Unit) or GetTriggerUnit even after a "wait"? I've always thought that was a global... thing :P

So I don't need a variable even if i have a wait between, like in this case, the spellcast and the unit creation? that's awesome!



EDIT:

here's the trigger atm:


Code:
function Trig_Smoke_Bomb_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A005' ) ) then
return false
endif
return true
endfunction

function SmokeBombBxprFunc takes nothing returns boolean
return ( ( IsUnitAlly(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) ) and ( GetUnitTypeId(GetFilterUnit()) != 'oshm' ) )
endfunction

function SmokeBombCallbackFunc takes nothing returns nothing
set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer(GetTriggerUnit()), 'oshm', GetUnitX(GetEnumUnit()), GetUnitY(GetEnumUnit()), bj_UNIT_FACING )
call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 0.25 )
call IssueTargetOrder( bj_lastCreatedUnit, "invisibility", GetEnumUnit() )
endfunction

function Trig_Smoke_Bomb_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local location l = GetSpellTargetLoc()
local boolexpr bxpr = Condition( function SmokeBombBxprFunc )
local integer i = 1
set bj_lastCreatedUnit = CreateUnitAtLoc( GetOwningPlayer(u), 'o003', l, bj_UNIT_FACING )
call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 8.00 )
loop
exitwhen i > 16
set bj_wantDestroyGroup = true
call ForGroupBJ( GetUnitsInRangeOfLocMatching(125.00, l, bxpr)
call TriggerSleepAction( 0.50 )
set i = i + 1
endloop
call RemoveLocation(l)
call DestroyBoolExpr(bxpr)
set u = null
set l = null
set bxpr = null
endfunction

//===========================================================================
function InitTrig_Smoke_Bomb takes nothing returns nothing
set gg_trg_Smoke_Bomb = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Smoke_Bomb, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Smoke_Bomb, Condition( function Trig_Smoke_Bomb_Conditions ) )
call TriggerAddAction( gg_trg_Smoke_Bomb, function Trig_Smoke_Bomb_Actions )
endfunction

I changed udg_u1 to GetTriggerUnit

I changed u (the local) to GetTriggerUnit in "SmokeBombBxprFunc"

I renamed p to l

But it says " expected ' " on this line:


Code:
        call ForGroupBJ( GetUnitsInRangeOfLocMatching(125.00, l, bxpr)

what do?|||And this is why I need to start previewing my posts before posting them. That line should be:


Code:
        call ForGroupBJ( GetUnitsInRangeOfLocMatching(125.00, l, bxpr), function SmokeBombCallbackFunc )
|||thanks! just one last thing, and I hope this shouldn't mess things up... In the madness of codes I forgot that I wanted to sort out from the units within 125 of local location l the ones which are 'o003''s. I'm just not exactly sure where i should type what. This whole thread have been full of news to me

bla bla bla.

I want to sort out the 'o003''s cause they cause big lags.|||If I understand what you're saying correctly, you're saying that you DON'T want o003s to be included in the trigger? If so, change


Code:
function SmokeBombBxprFunc takes nothing returns boolean
return ( ( IsUnitAlly(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) ) and ( GetUnitTypeId(GetFilterUnit()) != 'oshm' ) )
endfunction

to


Code:
function SmokeBombBxprFunc takes nothing returns boolean
return ( ( IsUnitAlly(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) ) and ( GetUnitTypeId(GetFilterUnit()) != 'oshm' ) and ( GetUnitTypeId(GetFilterUnit()) != 'o003' ) )
endfunction
|||Quote:




If I understand what you're saying correctly, you're saying that you DON'T want o003s to be included in the trigger? If so, change




you are correct sir. Hmm... I'm still having problems though.

Here's what I want to do: create a smoke cloud at a location, and every 0.5 seconds cast invisibilty on all friendly units within 125 of the cloud. The problems are:

It used to cause lag which freezed the game. I fixed this with this trigger:


Code:
DummyDies
Events
Unit - A unit Dies
Conditions
Or - Any (Conditions) are true
Conditions
(Unit-type of (Triggering unit)) Equal to Main Dummy
(Unit-type of (Triggering unit)) Equal to Smoke Bomb Dummy
(Unit-type of (Triggering unit)) Equal to Smoke Bomb Dummy Two
Actions
Game - Display to (All players) the text: (Name of (Triggering unit))
Unit - Remove (Triggering unit) from the game

(sorting out o003 didn't cut it :S)

problem 2:

when I had multiple instances of the Smoke_Bomb trigger running at the same time, some units would keep the invisibily buff forever! Which boggles my mind cause the buff only lasts for 0.75 seconds, and, no dummys are being created. I know that because Smoke_Bomb is the only trigger which creates o003's and orders them to cast invis, PLUS the DummyDies trigger displays the name of dying dummies, but no text appears when a unit stays invisible... siiiigh

No comments:

Post a Comment