(include "sci.sh")
(use "Main")
(use "PolyPath")
(use "Cycle")
(use "User")
(use "Obj")
(script 809)


(local
    local0[18] = (359 338 22 0 67 23 112 68 157 113 202 158 247 203 292 248 337 293 )
    theXOff[18] = (0 65535 0 65535 1 65535 1 0 1 1 0 1 65535 1 65535 0 65535 65535 )

)
(class Inertia of Code
    (properties
        client 0
        inertia 0
        maxInertia 0
        oldDir 0
        oldSpeed 0
        oldMover 0
        swimCnt 0
        xOff 0
        yOff 0
        inertizing 0
    )

    (method (init theClient)
        (if (paramTotal)
            = client theClient
        )(else
            = client gEgo
        )
        = xOff (= yOff (= inertia (= swimCnt (= inertizing (= oldMover 0)))))
        = oldDir (send client:heading)
        (if ((send client:mover))
            = oldMover (send client:mover)
        )
        (if (== client gEgo)
            (send client:setScript(inertiaScript))
        )
        (send client:code(self))
    )


    (method (doit)
        (var temp0)
        (if ((send client:isBlocked()))
            (self:moveDone())
        )(else
            (if (inertizing)
                (if ((== (send client:heading) oldDir) and (send client:mover))
                    (self:moveDone())
                )(else
                    (if (> swimCnt 0)
                        (self:doMove())
                        --swimCnt
                    )(else
                        (if (> inertia 0)
                            (self:doMove())
                            --inertia
                            = swimCnt inertia
                        )(else
                            (self:moveDone())
                        )
                    )
                )
            )(else
                (if (((< inertia maxInertia) and (>= ++swimCnt (send client:moveSpeed))) and (send client:mover))
                    = oldMover (send client:mover)
                    = swimCnt 0
                    ++inertia
                )(else
                    (if ((<> (send client:heading) oldDir) or (not (send client:mover) and oldMover))
                        = temp0 0
                        (while (< temp0 17)
                            (if ((>= local0[temp0] oldDir) and (>= oldDir local0[(+ temp0 1)]))
                                = xOff theXOff[temp0]
                                = yOff theXOff[(+ temp0 1)]
                                = temp0 17
                            )
                            = temp0 (+ temp0 2)
                        )
                        = inertizing 1
                        = swimCnt inertia
                        = oldSpeed (send client:moveSpeed)
                        (self:doMove())
                    )
                )
            )
        )
    )


    (method (dispose)
        (send client:
            moveSpeed(oldSpeed)
            code(0)
        )
        (if (== client gEgo)
            (send client:setScript(0))
        )
        = client 0
        (super:dispose())
    )


    (method (doMove)
        (send client:
            moveSpeed(inertia)
            x(+ (send client:x) (* (send client:xStep) xOff))
            y(+ (send client:y) (* (send client:yStep) yOff))
        )
    )


    (method (moveDone)
        (send client:moveSpeed(oldSpeed))
        = oldDir (send client:heading)
        = xOff (= yOff (= inertia (= swimCnt (= inertizing (= oldMover 0)))))
    )

)
(class Swim of Fwd
    (properties
        client 0
        caller 0
        cycleDir 1
        cycleCnt 0
        completed 0
    )

    (method (doit)
        (if ((send client:mover) and not (send client:isBlocked()))
            (super:doit())
        )
    )

)
(instance InertTo of Motion
    (properties)

    (method (doit)
        (var temp0)
        (if ((self:onTarget()))
            (self:moveDone())
        )(else
            (if (<> (send client:heading) GetAngle((send client:x) (send client:y) x y))
                InitBresen(self)
            )
            (super:doit())
        )
    )


    (method (onTarget)
        return 
            (if (((>= (+ x 10) (send client:x)) and (>= (send client:x) (- x 10))) and (>= (+ y 10) (send client:y)))
                >= (send client:y) (- y 10)
            )(else
                0
            )
    )

)
(instance inertiaScript of Script
    (properties)

    (method (handleEvent pEvent)
        (if ((send pEvent:claimed))
            return 
        )(else
            (if ((((<> (send gIconBar:curIcon) (send gIconBar:at(0))) or not (User:controls)) or (<> (send pEvent:type) 16384)) or (send pEvent:modifiers))
                (super:handleEvent(pEvent))
            )(else
                (send client:setMotion(
                    (if (global87)
                        PolyPath
                    )(else
                        InertTo
                    )
 (send pEvent:x) (send pEvent:y)))
                (User:prevDir(0))
                (send pEvent:claimed(1))
            )
        )
    )

)
