| 01-20-2007, 08:04 PM | #1 |
Heres the problem, in a tower defense map: I order units to move to points. But if a unit becomes entangled, the unit stops. After becoming un-entangled, the unit no longer has the order to move to a certain point. I'm looking for a solution to solve this problem. Heres what I've tried: A) Keep track of all units that are on the map, and periodically force them to move if they are not moving. Didn't work because units that had no order and became damaged automatically would flee from the tower attacking it... Not only that but it seems unrealistic to have a timer that checks possibly 30-150 units' orders every so often. Was quite the lagg'er. B) Created a trigger, on player owned unit issued order of "stop". Simply force the unit to move again. Didn't work, entangling units does not order a unit to stop (infact, no order is issued at all). Open to any ideas anyone has. |
| 01-20-2007, 08:29 PM | #2 |
Create a tower, with slow attack speed and an ok range doing 0 damage, and every time a unit gets hit by the tower make a trigger for the attacked unit to move his ass. |
| 01-21-2007, 06:41 AM | #3 |
Detect when a unit begins casting your entangle ability (so it fires before the spell is actually cast), and save the target of the ability to a local variable. Then, wait until the unit no longer has the entangle buff, and order the unit to move (or attack move, if that's the case) to the point you specify. Unfortunately, you need a JASS trigger for this because you're using a local variable in a condition (which GUI can't handle). It'd look something like this: JASS:function Trig_Untitled_Trigger_001_Conditions takes nothing returns boolean if ( not ( GetSpellAbilityId() == 'AEer' ) ) then //set AEer to your entangle ability's raw data ID return false endif return true endfunction function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing local unit Entangle_Unit set Entangle_Unit = GetSpellTargetUnit() loop exitwhen ( UnitHasBuffBJ(Entangle_Unit, 'BEer') == false ) //set BEer to your entangle buff's raw data ID call TriggerSleepAction(RMaxBJ(bj_WAIT_FOR_COND_MIN_INTERVAL, 0.25)) endloop call IssuePointOrderLocBJ( Entangle_Unit, "move", udg_PointVar ) //set udg_PointVar equal to where the unit should move to, and if you need to make it attack move, change "move" to "attack move" set Entangle_Unit = null endfunction //=========================================================================== function InitTrig_Untitled_Trigger_001 takes nothing returns nothing set gg_trg_Untitled_Trigger_001 = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Untitled_Trigger_001, EVENT_PLAYER_UNIT_SPELL_CAST ) call TriggerAddCondition( gg_trg_Untitled_Trigger_001, Condition( function Trig_Untitled_Trigger_001_Conditions ) ) call TriggerAddAction( gg_trg_Untitled_Trigger_001, function Trig_Untitled_Trigger_001_Actions ) endfunction Now... if someone could clean up those nasty BJ's you'd be set... |
| 01-21-2007, 07:30 AM | #4 |
Here's an optimized version with removed BJ's and stuff. JASS:function Trig_Entangled_Move_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'AEer' //set AEer to your entangle ability's raw data ID endfunction function Trig_Entangled_Move_Actions takes nothing returns nothing local unit Entangled_Unit = GetSpellTargetUnit() local real targetX = GetLocationX( udg_PointVar ) //set udg_PointVar equal to where the unit should move to. I have converted it to real x/y values for optimization local real targetY = GetLocationY( udg_PointVar ) loop exitwhen ( GetUnitAbilityLevel( Entangled_Unit, 'BEer' ) == false ) //set BEer to your entangle buff's raw data ID call TriggerSleepAction( 0.25 ) endloop call IssuePointOrder( Entangled_Unit, "move", targetX, targetY ) , //if you need to make it attack move, change "move" to "attack move" set Entangled_Unit = null endfunction //=========================================================================== function InitTrig_Entangled_Move takes nothing returns nothing set gg_trg_Entangled_Move = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Entangled_Move, EVENT_PLAYER_UNIT_SPELL_CAST ) call TriggerAddCondition( gg_trg_Entangled_Move, Condition( function Entangled_Move_Conditions ) ) call TriggerAddAction( gg_trg_Entangled_Move, function Entangled_Move_Actions ) endfunction |
| 01-21-2007, 08:44 AM | #5 |
Is using X/Y values actually faster? It seems like you need more variables and lines of code. I understand that it's more precise, but why not just move the unit to the point if the point is constant (which it would be in this case)? EDIT: I don't mean to say that I am a great "jass-er" myself, but I think you misinterpreted my JASS:loop exitwhen ( UnitHasBuffBJ(Entangle_Unit, 'BEer') == false ) //set BEer to your entangle buff's raw data ID call TriggerSleepAction(RMaxBJ(bj_WAIT_FOR_COND_MIN_INTERVAL, 0.25)) endloop Trigger: Wait unitil (((Entangle_Unit) has buff Entangling Roots) equal to false), checking every 0.25 seconds JASS:loop exitwhen ( GetUnitAbilityLevel( Entangled_Unit, 'BEer' ) == false ) //set BEer to your entangle buff's raw data ID call TriggerSleepAction( 0.25 ) endloop Correct me if I'm wrong. |
| 01-21-2007, 09:00 AM | #6 |
zeroXD's code owns yours Pyrogasm. The UnitHasBuffBJ(u,'buff') is actually GetUnitAbilityLevel(u,'buff')>0 (Note: For buffs it will only return 0 or 1) Note: Maybe change the event to EVENT_PLAYER_UNIT_SPELL_EFFECT and decrease the TriggerSleepAction intervall to 0.0 (which is actually ~0.09) |
| 01-21-2007, 10:54 AM | #7 | |
Quote:
Yes, the event should be EVENT_PLAYER_UNIT_SPELL_EFECT, I had it as EVENT_PLAYER_UNIT_SPELL_CAST only because I was screwing around with trying to save and reissue its order earlier, in which case I needed the trigger to fire before the spell was cast. I would say, however, that a 0.25 interval is fairly accurate and still doesn't lag (something rain9441 said he was having trouble with), as opposed to a 0.00 (~0.09) second wait. It's really a matter of preference; I would leave it as is, but Bert knows more than I do, so I'd listen to him. |
| 01-21-2007, 12:26 PM | #8 |
A loop with a ~0.09 wait does not cause any lag. In my current project i use about 100 loops like that and it's stil running as smooth as a 1vs1 melee game. Another point is that 0.25s is noticeable amount of time for the human eye (, so you will see the "runner" standing there). Here I must say like the hp propaganda says: sense and simplicity. |
| 01-21-2007, 12:30 PM | #9 | |
Quote:
It feels like something close to 0.3... EDIT: What could be done is just put the wait as the same as the entangling roots duration, since this is apparently just for one spell. |
| 01-21-2007, 01:40 PM | #10 |
Yes, we could, but then we would have to use a timer for accuracy, and so have to take care about the timer set to null bug. Polled wait is no solution either. It hostages the handle index of a timer. So we could use a private polled wait and a timerstack, like Vex does, but I guess for rain9441's purposes this fits and is even scalable in case he creates another entangling ability with a diffrent duration. |
| 01-21-2007, 03:14 PM | #11 |
Actually, waiting in increments of 0.25 or even ranges of 0.40-0.60 wouldn't necessarily be that bad. The original idea I tried (timer that checks ALL units and moves them) was set at 0.50 seconds. The entangled unit may still have a short delay before moving, but since the animation for being unentangled also has delay, it is not noticable at all. To be honest it was actually more awkward looking if you time it to 0.10 seconds or less. What I think i'll do is create a trigger like the above that will order the entangled unit to stop as soon as the buff wears off. The reason is, I already have good triggers that detect unit stopped and make them move. They are reliable. |
| 01-21-2007, 04:03 PM | #12 |
Are you still GUI-centered >programmer<? |
