| 03-27-2010, 06:26 PM | #1 |
Hi, I am trying to have an item cause some action every X seconds when carried by a unit. I have figured out how to do this, sort of, but it isn't MUI and it is very ugly. The code so far: JASS:function Trig_Silmaril_Enticement_FilterIsEnemy takes nothing returns boolean return IsUnitEnemy(GetFilterUnit(), bj_groupEnumOwningPlayer) and GetWidgetLife(GetFilterUnit()) > 0.405 endfunction function Trig_Silmaril_Enticement_Filter takes nothing returns boolean local group g local unit t local boolean b = false set g = GetUnitsOfPlayerAll(Player(0)) loop set t = FirstOfGroup(g) exitwhen t == null call GroupRemoveUnit(g,t) if UnitHasItemOfTypeBJ(t, 'ratf') then set b = true endif endloop call DestroyGroup(g) set g = null return b endfunction function Trig_Silmaril_Enticement_Conditions takes nothing returns boolean return Trig_Silmaril_Enticement_Filter() endfunction function Trig_Silmaril_Enticement_Actions takes nothing returns nothing local unit U local player P local location L local group g = CreateGroup() local boolexpr b = Condition(function Trig_Silmaril_Enticement_FilterIsEnemy) local unit t local integer i = 1 set g = GetUnitsOfPlayerAll(Player(0)) loop set t = FirstOfGroup(g) exitwhen t == null call GroupRemoveUnit(g,t) if UnitHasItemOfTypeBJ(t, 'ratf') then set U = t endif endloop set P = GetOwningPlayer( U ) set L = GetUnitLoc( U ) call DestroyGroup(g) set g = CreateGroup() call DisplayTimedTextToPlayer( P, 0, 0, 5. ,"TAUNT " + GetPlayerName(P) ) call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Taunt\\TauntCaster.mdl", U, "origin" ) ) set bj_groupEnumOwningPlayer = P call GroupEnumUnitsInRangeOfLoc(g, L, 1000, b) call DestroyBoolExpr(b) loop set t = FirstOfGroup(g) exitwhen t == null call GroupRemoveUnit(g,t) call IssueTargetOrder( t, "attack", U ) endloop call DestroyGroup(g) call RemoveLocation(L) set g = null set b = null set t = null set P = null set U = null set L = null endfunction function InitTrig_Silmaril_taunt takes nothing returns nothing set gg_trg_Silmaril_taunt = CreateTrigger( ) call TriggerRegisterTimerEvent( gg_trg_Silmaril_taunt, 5., true ) call TriggerAddCondition( gg_trg_Silmaril_taunt , Condition(function Trig_Silmaril_Enticement_Conditions)) call TriggerAddAction( gg_trg_Silmaril_taunt, function Trig_Silmaril_Enticement_Actions ) endfunction The condition here goes through all of player(0)'s units and checks for the item, if found, it runs the action that searches for the unit again, and then will cast the taunt effect every 5 seconds. Note that I am wishing to use something like this for any type of spell, not just taunt. Is there an easier way to grab the item-owning unit than this? And make it work for any number of players who may have it? Thank you |
| 03-27-2010, 06:43 PM | #2 |
I assume you make some middleearth-map... If there is only one silmaril in your map: save the current holder upon item-pickup into a global, everytime the item is picked, removed If there are more slimaril in your map: save all current holders into a global group and remove/add everyone who drops/picks a silmaril |
| 03-27-2010, 06:49 PM | #3 |
The middle-earth stories are fun, aren't they? Is there an easier way to finding the current item holders than iterating through the owning units of every player? |
| 03-27-2010, 06:59 PM | #4 |
have you read my post?? you've simply to store the current holder(s) when they pickup, drop an item or die |
| 03-27-2010, 07:12 PM | #5 |
Hi, Yes. I read your post, thank you. I am currently implementing multiple triggers to try and do as you suggest. I would like to clarify my question, (please humor me): Is there a simpler way to grab the current owning unit within the one trigger. Such as by using GetTriggerUnit() or GetManipulatingUnit() - both of which don't work of course... There may not be a simpler way, in which case your method might be the best and I will use that. Thanks |
| 03-27-2010, 07:27 PM | #6 |
your code:function Trig_Silmaril_Enticement_FilterIsEnemy takes nothing returns boolean return IsUnitEnemy(GetFilterUnit(), bj_groupEnumOwningPlayer) and GetWidgetLife(GetFilterUnit()) > 0.405 endfunction function Trig_Silmaril_Enticement_Filter takes nothing returns boolean local group g local unit t local boolean b = false set g = GetUnitsOfPlayerAll(Player(0)) loop set t = FirstOfGroup(g) exitwhen t == null call GroupRemoveUnit(g,t) if UnitHasItemOfTypeBJ(t, 'ratf') then set b = true endif endloop call DestroyGroup(g) set g = null return b endfunction function Trig_Silmaril_Enticement_Conditions takes nothing returns boolean return Trig_Silmaril_Enticement_Filter() endfunction function Trig_Silmaril_Enticement_Actions takes nothing returns nothing local unit U local player P local location L local group g = CreateGroup() local boolexpr b = Condition(function Trig_Silmaril_Enticement_FilterIsEnemy) local unit t local integer i = 1 set g = GetUnitsOfPlayerAll(Player(0)) loop set t = FirstOfGroup(g) exitwhen t == null call GroupRemoveUnit(g,t) if UnitHasItemOfTypeBJ(t, 'ratf') then set U = t endif endloop set P = GetOwningPlayer( U ) set L = GetUnitLoc( U ) call DestroyGroup(g) set g = CreateGroup() call DisplayTimedTextToPlayer( P, 0, 0, 5. ,"TAUNT " + GetPlayerName(P) ) call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Taunt\\TauntCaster.mdl", U, "origin" ) ) set bj_groupEnumOwningPlayer = P call GroupEnumUnitsInRangeOfLoc(g, L, 1000, b) call DestroyBoolExpr(b) loop set t = FirstOfGroup(g) exitwhen t == null call GroupRemoveUnit(g,t) call IssueTargetOrder( t, "attack", U ) endloop call DestroyGroup(g) call RemoveLocation(L) set g = null set b = null set t = null set P = null set U = null set L = null endfunction function InitTrig_Silmaril_taunt takes nothing returns nothing set gg_trg_Silmaril_taunt = CreateTrigger( ) call TriggerRegisterTimerEvent( gg_trg_Silmaril_taunt, 5., true ) call TriggerAddCondition( gg_trg_Silmaril_taunt , Condition(function Trig_Silmaril_Enticement_Conditions)) call TriggerAddAction( gg_trg_Silmaril_taunt, function Trig_Silmaril_Enticement_Actions ) endfunction optimized code:function Trig_Silmaril_Enticement_FilterIsEnemy takes nothing returns boolean local unit u=GetFilterUnit() local boolean b=(u!=null and IsUnitEnemy(u, bj_groupEnumOwningPlayer) and GetWidgetLife(u) > 0.405) set u=null return b endfunction globals group tempGroup=CreateGroup() boolexpr enemyFilter=Condition(function Trig_Silmaril_Enticement_FilterIsEnemy) endglobals function Trig_Silmaril_Enticement_Filter takes nothing returns boolean local unit t call GroupClear(tempGroup) call GroupEnumUnitsOfPlayer(tempGroup,p,null) loop set t = FirstOfGroup(tempGroup) exitwhen t == null call GroupRemoveUnit(tempGroup,t) if UnitHasItemOfTypeBJ(t, 'ratf') then return true endif endloop return false endfunction function Trig_Silmaril_Enticement_Actions takes nothing returns nothing local player P local unit t local unit U local integer i = 1 call GroupClear(tempGroup) call GroupEnumUnitsOfPlayer(tempGroup,P,null) loop set t = FirstOfGroup(tempGroup) exitwhen t == null call GroupRemoveUnit(tempGroup,t) exitwhen UnitHasItemOfTypeBJ(t, 'ratf') endloop if t==null then return //no one holds the item endif set U=t set P = GetOwningPlayer( U ) call DisplayTimedTextToPlayer( P, 0, 0, 5. ,"TAUNT " + GetPlayerName(P) ) call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Taunt\\TauntCaster.mdl", U, "origin" ) ) set bj_groupEnumOwningPlayer = P call ClearGroup(tempGroup) call GroupEnumUnitsInRange(tempGroupo, GetUnitX(U),GetUnitY(U), 1000, enemyFilter) loop set t = FirstOfGroup(tempGroup) exitwhen t == null call GroupRemoveUnit(tempGroup,t) call IssueTargetOrder( t, "attack", U ) endloop set t = null set P = null set U = null endfunction function InitTrig_Silmaril_taunt takes nothing returns nothing set gg_trg_Silmaril_taunt = CreateTrigger( ) call TimerStart(CreateTimer(),5.0,true, function gg_trg_Silmaril_taunt) call TriggerAddCondition( gg_trg_Silmaril_taunt , Condition(function Trig_Silmaril_Enticement_Filter)) call TriggerAddAction( gg_trg_Silmaril_taunt, function Trig_Silmaril_Enticement_Actions ) endfunction if you're using plain JASS, simply create variables for each var in the golbals-block and replace them with udg_<name> within the trigger |
| 03-27-2010, 08:44 PM | #7 | |
Quote:
There is no native, which leads to your desired unit. You need to do some kind of workaround. You can use ToTs method. There are other methods, though. You could, for example, use Item Indexing (as Items got a Custom Value afaik) or Hashtables to store the current owner for every item. However, this is probably too complicated, if you only need this check for one item. |
| 03-28-2010, 09:05 AM | #8 |
ItemUtils comes with the function GetItemOwningUnit() which can give you the unit currently carrying the item. The library itself uses the method Tot mentioned internally. |
