| 02-24-2007, 05:02 AM | #1 |
Im sorta new at JASS not really too new but im having a couple of problems with this script.... JASS:function Trig_Frost_Mine_Conditions takes nothing returns boolean if ( not ( GetUnitTypeId(GetDyingUnit()) == 'n001' ) ) then return false endif return true endfunction function Trig_Frost_Mine_Func001001002 takes nothing returns boolean return ( IsUnitType(GetFilterUnit(), UNIT_TYPE_ANCIENT) != true ) endfunction function Trig_Frost_Mine_Func001A takes nothing returns nothing call PauseUnitBJ( true, GetEnumUnit() ) call AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathTargetArt.mdl", GetEnumUnit(), "origin" ) call PolledWait( 7.00 ) call PauseUnitBJ( false, GetEnumUnit() ) call DestroyEffectBJ(GetLastCreatedEffectBJ()) endfunction function Trig_Frost_Mine_Actions takes nothing returns nothing local location loc = GetUnitLoc(GetDyingUnit()) local effect se call AddSpecialEffectLocBJ( loc, "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl" ) set se = GetLastCreatedEffectBJ() call ForGroupBJ( GetUnitsInRectMatching(GetPlayableMapRect(), Condition(function Trig_Frost_Mine_Func001001002)), function Trig_Frost_Mine_Func001A ) call PolledWait( 2.0 ) call DestroyEffectBJ( se ) set se = null set loc = null endfunction //=========================================================================== function InitTrig_Frost_Mine takes nothing returns nothing set gg_trg_Frost_Mine = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Frost_Mine, EVENT_PLAYER_UNIT_DEATH ) call TriggerAddCondition( gg_trg_Frost_Mine, Condition( function Trig_Frost_Mine_Conditions ) ) call TriggerAddAction( gg_trg_Frost_Mine, function Trig_Frost_Mine_Actions ) endfunction Basically its my custom "Freeze" spell... The mine is suppose to explode then all the units nearby get frozen =P It works by pausing and unpausing the units.... but when the units pause, they wont unpause after the Polled time... =/ and ive tried "messing around" with some of the script to see whats messing it up... Im not sure if its Messed up or its just not written correctly... Please help =] |
| 02-24-2007, 08:03 AM | #2 |
Hows about we learn how to optimize, ok? Take, for example, your first function: JASS:function Trig_Frost_Mine_Conditions takes nothing returns boolean if ( not ( GetUnitTypeId(GetDyingUnit()) == 'n001' ) ) then return false endif return true endfunction JASS:function Trig_Frost_Mine_Conditions takes nothing returns boolean return GetUnitTypeId(GetTriggerUnit()) == 'n001' endfunction Next (switching to the actions), you've got a local location and some SFX BJ's. Locations = slow, so you'll want to use local reals X and Y whenever you can (though sometimes you need a location). So, we'll create a unit variable and have these lines now: JASS:local unit U = GetTriggerUnit() local real X = GetUnitX(U) local real Y = GetUnitY(U) If we change that, now we've got to change our SFX actions and remove those BJ's because there's usually a native for them. In this case, we can eliminate one line of code by directly setting the effect when it's declared like this: local effect se = AddSpecialEffect("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl", X, Y). Alternatively, if the effect is able to be destroyed when it's created and still play its animation, you can use this: call DestroyEffect(AddSpecialEffect("Model file", X, Y)) Alltogether, the actions now look like this: JASS:function Trig_Frost_Mine_Actions takes nothing returns nothing local unit U = GetTriggerUnit() local real X = GetUnitX(U) local real Y = GetUnitY(U) local effect se = AddSpecialEffect("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl", X, Y) call ForGroupBJ( GetUnitsInRectMatching(GetPlayableMapRect(), Condition(function Trig_Frost_Mine_Func001001002)), function Trig_Frost_Mine_Func001A ) call PolledWait( 2.0 ) call DestroyEffect(se) set se = null set U = null endfunction Moving on to the line call ForGroupBJ( GetUnitsInRectMatching(GetPlayableMapRect(), Condition(function Trig_Frost_Mine_Func001001002)), function Trig_Frost_Mine_Func001A )... Once again, we can remove the BJ function and instead of replacing it with a new one, create a loop work-around that works just fine. Basically, we pick every unit we want in a group, then initiate a loop in which we set a variable to the first one of the group, do some actions with it, remove it from the group, and then loop over again until there are no more units in the group. Here's what that looks like: 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 To apply this, we'll first need to get our group. We'll use the GroupEnumUnitsInRange() native for this, which picks units that match a condition in a radius of Z from X and Y values. Our X and Y values are already present, our radius will be whatever you want (you made it affect every unit on the map; I'll say the radius is 300), and our condition (otherwise known as a boolexpr filter; here is an explaination of one) is function Trig_Frost_Mine_Func001001002. Before using GroupEnumUnitsInRange(), you must create a group. Thus, we will now have to add the following line to a variable declaration: local group G = CreateGroup(). After straigtening out the group mess, we'll need another unit variable U2, in this instance, and an application of the loop mentioned above. So let's just change the instances of GetEnumUnit() and mush the whole thing together. Now it'll look like this: JASS:function Trig_Frost_Mine_Actions takes nothing returns nothing local unit U = GetTriggerUnit() local real X = GetUnitX(U) local real Y = GetUnitY(U) local effect se = AddSpecialEffect("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl", X, Y) local group G = CreateGroup() local unit U2 call GroupEnumUnitsInRange(G, X, Y, 300.00, Conditon(function Trig_Frost_Mine_Func001001002)) loop set U2 = FirstOfGroup(G) //This MUST be before the exitwhen, else the loop will instantly end exitwhen U2 == null call PauseUnitBJ( true, GetEnumUnit() ) call AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathTargetArt.mdl", GetEnumUnit(), "origin" ) call PolledWait( 7.00 ) call PauseUnitBJ( false, GetEnumUnit() ) call DestroyEffectBJ(GetLastCreatedEffectBJ()) call GroupRemoveUnit(G, U2) endloop call PolledWait( 2.0 ) call DestroyEffect(se) set se = null set U = null call DestroyGroup(G) set G = null set U2 = null endfunction Immediately you should notice that the loop will now wait 7.00 seconds before switching to the next unit, that there are a few BJ's in there, and that "LastCreatedEffectBJ()" won't return the correct value. To fix the waiting problem we simply remove the wait, add those units to another unit group, add the wait back in after the loop, and loop once again through the second group to unpause/remove the effects. It's now going to look something like this: JASS:function Trig_Frost_Mine_Actions takes nothing returns nothing local unit U = GetTriggerUnit() local real X = GetUnitX(U) local real Y = GetUnitY(U) local effect se = AddSpecialEffect("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl", X, Y) local group G = CreateGroup() local unit U2 local group G2 = CreateGroup() call GroupEnumUnitsInRange(G, X, Y, 300.00, Conditon(function Trig_Frost_Mine_Func001001002)) loop set U2 = FirstOfGroup(G) exitwhen U2 == null call PauseUnit(U2, true) call AddSpecialEffectTarget("Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathTargetArt.mdl", U2, "origin") call GroupAddUnit(G2, U2) call GroupRemoveUnit(G, U2) endloop call PolledWait(7.00) loop set U2 = FirstOfGroup(G2) exitwhen U2 == null call PauseUnit(U2, false) call DestroyEffect(GetLastCreatedEffectBJ()) call GroupRemoveUnit(G2, U2) endloop call PolledWait(2.0) call DestroyEffect(se) set se = null set U = null call DestroyGroup(G) set G = null set U2 = null call DestroyGroup(G2) set G2 = null endfunction Once again, there is a problem with the SFX. I personally would have just made a dummy spell based off of storm bolt that had the freezing breath art as a buff for the stun, which would have eliminated any need for waits, SFX, and/or pausing units... but we can do it the hard way. For this, we will need a local integer I and a local effect array SFX. We're going to increment I with every iteration of the first loop, then set SFX's index equal to I each time. Next, we'll loop through all indexes of SFX until we've reached our last one. Here's how we'll go about doing this: JASS:function Trig_Frost_Mine_Actions takes nothing returns nothing local unit U = GetTriggerUnit() local real X = GetUnitX(U) local real Y = GetUnitY(U) local effect se = AddSpecialEffect("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl", X, Y) local group G = CreateGroup() local unit U2 local group G2 = CreateGroup() local integer I = 0 local effect array SFX call GroupEnumUnitsInRange(G, X, Y, 300.00, Conditon(function Trig_Frost_Mine_Func001001002)) loop set U2 = FirstOfGroup(G) exitwhen U2 == null set I = I+1 call PauseUnit(U2, true) set SFX[i] = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathTargetArt.mdl", U2, "origin") call GroupAddUnit(G2, U2) call GroupRemoveUnit(G, U2) endloop call PolledWait(7.00) set I = 0 loop set U2 = FirstOfGroup(G2) exitwhen U2 == null set I = I+1 call DestroyEffect(SFX[i]) //We know it will destroy every effect because each time I was incremented in the above loop, a unit was passed from G to G2 set SFX[i] = null call PauseUnit(U2, false) call DestroyEffect(GetLastCreatedEffectBJ()) call GroupRemoveUnit(G2, U2) endloop call DestroyEffect(se) set se = null set U = null call DestroyGroup(G) set G = null set U2 = null call DestroyGroup(G2) set G2 = null endfunction Notice that I removed the call PolledWait( 2.0 ). This is because there was a 7 second wait above it, and it doesn't matter when you destroy the effect, just as long as it gets done (unless you need to stop its animation or something funky like that). The last thing to notice is that while the units are paused, they will still move and look less "frozen". To fix this, we'll just add in the line SetUnitTimeScale(), which changes a unit's animation speed. All put together and given nice, orderly names, the code would look like this: JASS:function Trig_Frost_Mine_Conditions takes nothing returns boolean return GetUnitTypeId(GetTriggerUnit()) == 'n001' endfunction function Trig_Frost_Mine_Filter takes nothing returns boolean return IsUnitType(GetFilterUnit(), UNIT_TYPE_ANCIENT) == false endfunction function Trig_Frost_Mine_Actions takes nothing returns nothing local unit U = GetTriggerUnit() local real X = GetUnitX(U) local real Y = GetUnitY(U) local effect se = AddSpecialEffect("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl", X, Y) local group G = CreateGroup() local unit U2 local group G2 = CreateGroup() local integer I = 0 local effect array SFX call GroupEnumUnitsInRange(G, X, Y, 300.00, Conditon(function Trig_Frost_Mine_Filter)) loop set U2 = FirstOfGroup(G) exitwhen U2 == null set I = I+1 call PauseUnit(U2, true) call SetUnitTimeScale(U2, 0.00) set SFX[i] = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathTargetArt.mdl", U2, "origin") call GroupAddUnit(G2, U2) call GroupRemoveUnit(G, U2) endloop call PolledWait(7.00) set I = 0 loop set U2 = FirstOfGroup(G2) exitwhen U2 == null set I = I+1 call DestroyEffect(SFX[i]) set SFX[i] = null call PauseUnit(U2, false) call SetUnitTimeScale(U2, 1.00) call DestroyEffect(GetLastCreatedEffectBJ()) call GroupRemoveUnit(G2, U2) endloop call DestroyEffect(se) set se = null set U = null call DestroyGroup(G) set G = null set U2 = null call DestroyGroup(G2) set G2 = null endfunction Whew... hope that helps ![]() |
| 02-24-2007, 08:14 AM | #3 |
*Gaping Jaw* For christ's sake Pyrogasm... You completely... Wow. +Rep for you! |
| 02-24-2007, 08:20 AM | #4 | |
Quote:
You should take a look at some of Moyack's responses sometimes... he tends to do this too. And seeing a trigger as screwed up as that was, in a thread asking for help... I just couldn't resist. EDIT: ROFLS "Ninja-Style Kick-ass!" <3 |
| 02-24-2007, 08:25 AM | #5 |
*requests rep for pwnsome rep phrase* Well, he now has a fully fixed trigger and knows some extra things. If I felt like being so helpful I could pull this off... But damn, 2 1/2 hours? |
| 02-24-2007, 08:46 AM | #6 |
Very nice answer. I surpose you gave me rep for the answer i gave, so its only fair you recieve rep in return. GJ. EDIT: Offtopic: Ouch, you need 3 rep for your blue rep. |
| 02-24-2007, 08:49 AM | #7 | |
Quote:
2 1/2 hours give-or take. I'm not sure if that's actually a good time increment because I was doing other stuff at the time ![]() The)TideHunter( I tend to rep people for being helpful even if I'm not involved in the conversation ![]() Edit: So... a blue on is 120, is it? I thought it was around 100. So close... |
| 02-24-2007, 02:16 PM | #8 |
Omg pyrogasm you deserve 10,000,000 rep for that but i can only rep you with 1 =[ Thanks so frikken much, wow im still amazed! =] |
| 02-25-2007, 12:01 AM | #9 |
But does it work?... ![]() |
