HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Trigger-based movement?

05-25-2010, 07:49 AM#1
rednek
Hi
So, in some maps, units are not moving normally. For example: Warlock or Hungry Hungry Fellhounds. They start slow, but their speed increases as they go. Also, when they are ordered to go in the opposite direction, they don't turn right away, but slide a while in the direction they were going at first, because of momentum.
It's like they're on ice or some slick surface.

Do you know what I mean? I usually suck at explaining things, so if it's not clear, just tell and I'll try to specify.

So, how would I do something like that? You don't have to write the whole thing, it'll be enough if you just explain the basic logic behind it.
Thanks for any reply!
05-25-2010, 08:27 AM#2
Bribe
Sorry, grammar nazi intervention:

because of friction
should be:
because of momentum, as there is a lack of friction.

Are you looking for real code for this, or are you looking for a GUI workaround?
05-25-2010, 09:00 AM#3
rednek
Grammar fixed~

The real code is allright with me, if you can post it that is :)

But it should be enough if you just explain the system it works on, and I'll code it myself :D
05-25-2010, 10:10 AM#4
TheKid
If they change directions suddenly do they still slide?
05-25-2010, 10:22 AM#5
rednek
Yes, that's the point :P
05-25-2010, 04:31 PM#6
Bribe
Collapse JASS:
scope Momentum initializer Init
    
globals
    group Group=CreateGroup()
    hashtable hash=InitHashtable()
    unit EnumUnit
endglobals
    
    private function SlipLoop takes nothing returns nothing
        local string Order
        local integer id
        local integer i
        local real f
        
        set EnumUnit=GetEnumUnit()
        set Order=OrderId2String(GetUnitCurrentOrder(EnumUnit))
        set id=GetHandleId(EnumUnit)
        set i=LoadInteger(hash,id,0)+1
        call SaveInteger(hash,id,0,i)
        
        if Order!="attack" and Order!="stop" and Order!="holdposition" then
            call SaveReal(hash,id,i*2,GetUnitFacing(EnumUnit)*bj_DEGTORAD)
            call SaveBoolean(hash,id,i*2+1,true)
        else
            call SaveBoolean(hash,id,i*2+1,false)
        endif
        
        if i>40 and LoadBoolean(hash,id,(i-40)*2) then
            set f=LoadReal(hash,id,(i-40)*2)
            
            call SetUnitX(EnumUnit,GetWidgetX(EnumUnit)+5*Cos(f))
            call SetUnitY(EnumUnit,GetWidgetY(EnumUnit)+5*Sin(f))
        endif
        call RemoveSavedReal(hash,id,(i-40)*2)
        call RemoveSavedBoolean(hash,id,(i-40)*2+1)
    endfunction
    
    private function SlipEnum takes nothing returns nothing
        call ForGroup(Group,function SlipLoop)
    endfunction
    
    private function Add2 takes nothing returns nothing
        if not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) then
            call GroupAddUnit(Group,GetFilterUnit())
        endif
    endfunction
    private function Add takes nothing returns nothing
        if not IsUnitType(GetTriggerUnit(),UNIT_TYPE_STRUCTURE) then
            call GroupAddUnit(Group,GetTriggerUnit())
        endif
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t=CreateTrigger()
        call GroupEnumUnitsInRect(Group,bj_mapInitialPlayableArea,Filter(function Add2))
        call TimerStart(CreateTimer(),0.035,true,function SlipEnum)
        
        call TriggerRegisterEnterRectSimple(t,bj_mapInitialPlayableArea)
        call TriggerAddCondition(t,Condition(function Add))
    endfunction
    
endscope
05-25-2010, 05:57 PM#7
rednek
Thanks! That's a little more than I hoped for : D

I still don't get some parts of it though
Collapse JASS:
call SetUnitX(EnumUnit,GetWidgetX(EnumUnit)+5*Cos(f))
05-25-2010, 06:10 PM#8
Bribe
That sets the x-coordinate of the unit (to slide it) and the one below it sets the y-coordinate. The math is polar projection math, and the unit slides in the direction it was facing 1.5 seconds prior.
05-25-2010, 09:21 PM#9
0zyx0
I believe a vector-based approach would be better for this, because of versatility, realism, and speed. Just store a velocity vector for each unit, and have an acceleration depending on the user's input. At least that's how I would have done it. And the relatively slow hashtable calls could be replaced by array + unit indexing. That is, if speed is an issue.
05-25-2010, 10:54 PM#10
rednek
Shouldn't be a problem, since I only have like 6 units moving on the map.

Anyway, I've got a different problem!
Now that the units are moving like this, they can't use any abilities! It's because they need some time to cast them, and their cast is disrupted when I change their location.

They fixed this in Warlock somehow, does anyone know how?
Also, should I create a new thread? :D

edit: nah, since I asked already... Or dunno, I'll create a new thread if I wont get answered in this one :S
05-26-2010, 03:50 AM#11
Bribe
SetUnitX and SetUnitY shouldn't disrupt channeling spells; that's only SetUnitPosition that does that I thought??
05-26-2010, 07:01 AM#12
TheKid
That is correct.
05-26-2010, 08:06 AM#13
rednek
Tested - Hmmm, it really does not.
Damn, must be something different

edit: fixed - it was facing angle... -.-