| 09-13-2007, 12:34 AM | #1 |
Why does this not work? It all runs fine except the part where the dummies actually cast polymorph. I use a modified custom version of polymorph but it has the same order string so... I've tried to make the code easy to go through for you. JASS://=========================================================================== //=======================Shepherding by ~Void~=============================== //=========================================================================== constant function Shep_ID takes nothing returns integer return 'A000' //Rawcode of the ability being cast endfunction constant function Shep_Dummy takes nothing returns integer return 'h000' //Rawcode of the dummy unit endfunction constant function Shep_Range1 takes nothing returns integer return 300 //The first number in formula for spell radius: Shep_Range1 + (abilitylevel * Shep_Range2) endfunction constant function Shep_Range2 takes nothing returns integer return 100 //The multiplier for the spell level in formula for spell radius: Shep_Range1 + (abilitylevel * Shep_Range2) endfunction //=========================================================================== //=========================================================================== function Trig_Shepherding_Conditions takes nothing returns boolean if ( not ( GetSpellAbilityId() == 'A000' ) ) then return false endif return true endfunction //=========================================================================== function Shep_Conditions takes nothing returns boolean local unit filt = GetFilterUnit() return ( filt != GetTriggerUnit() ) and( GetUnitTypeId(filt) != Shep_Dummy()) //makes sure the caster doesn't get polymorphed. endfunction //=========================================================================== function Shep_Dummy_Create takes nothing returns nothing //creates the dummy and orders it to poly the picked unit local unit temp call CreateNUnitsAtLoc( 1, Shep_Dummy(), Player(PLAYER_NEUTRAL_PASSIVE), GetSpellTargetLoc(), bj_UNIT_FACING ) set temp = GetLastCreatedUnit() call UnitApplyTimedLifeBJ( 1.00, 'BTLF', temp ) call IssueTargetOrderBJ( temp, "polymorph", GetEnumUnit() ) set temp = null endfunction //=========================================================================== function Trig_Shepherding_Actions takes nothing returns nothing local unit cast = GetTriggerUnit() local location targ = GetSpellTargetLoc() local integer abil = GetUnitAbilityLevelSwapped(Shep_ID(),cast) call ForGroupBJ( GetUnitsInRangeOfLocMatching( (Shep_Range1() + ( Shep_Range2() * I2R(abil))), targ, Condition(function Shep_Conditions)), function Shep_Dummy_Create ) endfunction //=========================================================================== //=========================================================================== function InitTrig_Shepherding takes nothing returns nothing set gg_trg_Shepherding = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Shepherding, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Shepherding, Condition( function Trig_Shepherding_Conditions ) ) call TriggerAddAction( gg_trg_Shepherding, function Trig_Shepherding_Actions ) endfunction |
| 09-13-2007, 01:33 AM | #2 |
JASS:function Shep_Dummy_Create takes nothing returns nothing //creates the dummy and orders it to poly the picked unit local unit temp call CreateNUnitsAtLoc( 1, Shep_Dummy(), Player(PLAYER_NEUTRAL_PASSIVE), GetSpellTargetLoc(), bj_UNIT_FACING ) set temp = GetLastCreatedUnit() call UnitApplyTimedLifeBJ( 1.00, 'BTLF', temp ) call IssueTargetOrderBJ( temp, "polymorph", GetEnumUnit() ) set temp = null endfunction I'm thinking it's the GetSpellTargetLoc on the 2nd line of that function. I don't think it carries over for some reason. Doesn't really make sense, but try storing that to a global variable to transfer it through. Oh another thing, the UnitApplyTimedLife might have too short of a time (depending on how your dummy unit is set up). Try increasing it to 2 seconds. And...that is some ugly ass code, to put it nicely =D. BJ's all over, leaking locations, it almost looks like it was just converted from GUI. Since I'm not really confident in my answer - where exactly was the problem? Did the dummy units never spawn, or did the spell just not get cast? |
| 09-13-2007, 03:37 AM | #3 |
No, TaintedReality, that is the error. Now that we've found it, you should learn to optimize: Since we know that the "return" keyword is used to return a boolean statement, you can simply replace this: JASS:function Trig_Shepherding_Conditions takes nothing returns boolean if ( not ( GetSpellAbilityId() == 'A000' ) ) then return false endif return true endfunction JASS:function Trig_Shepherding_Conditions takes nothing returns boolean return GetSpellAbilityId() == Shep_Id() endfunction This function leaks a unit variable: JASS:function Shep_Conditions takes nothing returns boolean local unit filt = GetFilterUnit() return ( filt != GetTriggerUnit() ) and( GetUnitTypeId(filt) != Shep_Dummy()) //makes sure the caster doesn't get polymorphed. endfunction JASS:function Shep_Conditions takes nothing returns boolean local unit filt = GetFilterUnit() local boolean b = (filt != GetTriggerUnit()) and(GetUnitTypeId(filt) != Shep_Dummy()) //makes sure the caster doesn't get polymorphed. set filt = null return b endfunction Now, you should notice that this is still inefficient because it calls 2 function calls that could be avoided by using global variables. There is no need to create our own (which you could easily do), as we can just use these two variables from Blizzard.j: bj_ghoul[300] and bj_meleeTwinkedHeroes[300]: JASS:function Shep_Conditions takes nothing returns boolean local unit filt = GetFilterUnit() local boolean b = (filt != bj_ghoul[300]) and(GetUnitTypeId(filt) != bj_meleeTwinkedHeroes[300]) //makes sure the caster doesn't get polymorphed. set filt = null return b endfunction //... function Trig_Shepherding_Actions takes nothing returns nothing local location targ = GetSpellTargetLoc() local integer abil set bj_ghoul[300] = GetTriggerUnit() //Just use these variables here, no need to have a local and global that point the same thing set abil = GetUnitAbilityLevelSwapped(Shep_ID(),bj_ghoul[300]) set bj_meleeTwinkedHeroes[300] = Shep_Dummy() call ForGroupBJ( GetUnitsInRangeOfLocMatching( (Shep_Range1() + ( Shep_Range2() * I2R(abil))), targ, Condition(function Shep_Conditions)), function Shep_Dummy_Create ) endfunction Next, the Trig_Shepherding_Actions function has a fair amount of BJs and a leak that should be fixed like so: JASS:function Trig_Shepherding_Actions takes nothing returns nothing local location targ = GetSpellTargetLoc() local group g = CreateGroup() set bj_ghoul[300] = GetTriggerUnit() set bj_meleeTwinkedHeroes[300] = Shep_Dummy() call GroupEnumUnitsInRangeOfLoc(g, targ, Shep_Range1()+(Shep_Range2()*GetUnitAbilityLevel(bj_ghoul[300], Shep_ID()), Condition(function Shep_Conditions)) call ForGroup(g, function Shep_Dummy_Create) call DestroyGroup(g) call RemoveLocation(targ) set g = null set targ = null endfunction Last, we can see that we should remove the usage of locations and instead use x/y values. To do this (and to fix the problem you had before), we'll have to replace the ForGroup call with this simple workaround: JASS:loop set U = FirstOfGroup(G) //U being the unit variable and G being our group exitwhen U == null //So we can exit when the group is empty //Do some stuff with U GroupRemoveUnit(G, U) //Removing it from the group endloop JASS:function Trig_Shepherding_Actions takes nothing returns nothing local location targ = GetSpellTargetLoc() local group g = CreateGroup() local real x = GetLocationX(targ) local real y = GetLocationY(targ) local unit u local unit temp set bj_ghoul[300] = GetTriggerUnit() set bj_meleeTwinkedHeroes[300] = Shep_Dummy() call GroupEnumUnitsInRange(g, x, y, Shep_Range1()+(Shep_Range2()*GetUnitAbilityLevel(bj_ghoul[300], Shep_ID())), Condition(function Shep_Conditions)) loop set u = FirstOfGroup(g) exitwhen u == null //This also removes a minor leak set temp = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), bj_meleeTwinkedHeroes[300], x, y, 0.00) call UnitApplyTimedLife(temp, 'BTLF', 1.00) call IssueTargetOrder(temp, "polymorph", u) call GroupRemoveUnit(g, u) endloop call DestroyGroup(g) call RemoveLocation(targ) set g = null set targ = null set temp = null endfunction All together, it should look like this: JASS://=========================================================================== //=======================Shepherding by ~Void~=============================== //=========================================================================== constant function Shep_ID takes nothing returns integer return 'A000' //Rawcode of the ability being cast endfunction constant function Shep_Dummy takes nothing returns integer return 'h000' //Rawcode of the dummy unit endfunction constant function Shep_Range1 takes nothing returns integer return 300 //The first number in formula for spell radius: Shep_Range1 + (abilitylevel * Shep_Range2) endfunction constant function Shep_Range2 takes nothing returns integer return 100 //The multiplier for the spell level in formula for spell radius: Shep_Range1 + (abilitylevel * Shep_Range2) endfunction //=========================================================================== //=========================================================================== function Trig_Shepherding_Conditions takes nothing returns boolean return GetSpellAbilityId() == Shep_ID() endfunction //=========================================================================== function Shep_Conditions takes nothing returns boolean local unit filt = GetFilterUnit() local boolean b = (filt != bj_ghoul[300]) and(GetUnitTypeId(filt) != bj_meleeTwinkedHeroes[300]) //makes sure the caster doesn't get polymorphed. set filt = null return b endfunction //=========================================================================== function Trig_Shepherding_Actions takes nothing returns nothing local location targ = GetSpellTargetLoc() local group g = CreateGroup() local real x = GetLocationX(targ) local real y = GetLocationY(targ) local unit u local unit temp set bj_ghoul[300] = GetTriggerUnit() set bj_meleeTwinkedHeroes[300] = Shep_Dummy() call GroupEnumUnitsInRange(g, x, y, Shep_Range1()+(Shep_Range2()*GetUnitAbilityLevel(bj_ghoul[300], Shep_ID())), Condition(function Shep_Conditions)) loop set u = FirstOfGroup(g) exitwhen u == null //This also removes a minor leak set temp = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), bj_meleeTwinkedHeroes[300], x, y, 0.00) call UnitApplyTimedLife(temp, 'BTLF', 1.00) call IssueTargetOrder(temp, "polymorph", u) call GroupRemoveUnit(g, u) endloop call DestroyGroup(g) call RemoveLocation(targ) set g = null set targ = null set temp = null endfunction //=========================================================================== //=========================================================================== function InitTrig_Shepherding takes nothing returns nothing set gg_trg_Shepherding = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Shepherding, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Shepherding, Condition( function Trig_Shepherding_Conditions ) ) call TriggerAddAction( gg_trg_Shepherding, function Trig_Shepherding_Actions ) endfunction |
| 09-13-2007, 04:56 AM | #4 |
Variables in functions which return something don't need to be nulled, I thought. |
| 09-13-2007, 05:08 AM | #5 |
The variable that's returned doesn't need to be nulled. Others do: JASS://Good: function SomeFunc takes nothing returns unit local real PlayerInt = GetRandomInt(0, 15) local unit U = CreateUnit(Player(PlayerInt), 'h000', 0.00, 0.00, 0.00) return U endfunction //Bad: function SomeFunc takes nothing returns integer local real PlayerInt = GetRandomInt(0, 15) local unit U = CreateUnit(Player(PlayerInt), 'h000', 0.00, 0.00, 0.00) return PlayerInt endfunction //Good: function SomeFunc takes nothing returns integer local real PlayerInt = GetRandomInt(0, 15) local unit U = CreateUnit(Player(PlayerInt), 'h000', 0.00, 0.00, 0.00) set U = null return PlayerInt endfunction |
| 09-14-2007, 11:22 PM | #6 |
Thanks pyro, but it still doesn't sheep them. O_o |
| 09-14-2007, 11:29 PM | #7 |
Does it error? Edit: Try changing this: set temp = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), bj_meleeTwinkedHeroes[300], x, y, 0.00) to this: JASS:local player p set bj_ghoul[300] = GetTriggerUnit() set P = GetOwningPlayer(bj_ghoul[300]) //... set temp = CreateUnit(p, bj_meleeTwinkedHeroes[300], x, y, 0.00) //... set p = null //Just null it, you can't destroy players. And/Or changing the timed life time to to 2.00 seconds. Or it could be that the dummy unit does not have the ability... or that the dummy has no mana and the polymorph costs mana... or you forgot to remove tech requirements from polymorph. |
