(include "sci.sh")
(use "Obj")
(script 992)



(class Cycle of Obj
    (properties
        client 0
        caller 0
        cycleDir 1
        cycleCnt 0
    )

    (method (init theClient)
        = client theClient
        = cycleCnt 0
        (send client:setCel(-1))
        (send client:startUpd())
    )


    (method (nextCel)
        ++cycleCnt
        (if (> cycleCnt (send client:cycleSpeed()))
            = cycleCnt 0
            (if (& (send client:signal()) $1000)
                (send client:cel())
            )(else
                + (send client:cel()) cycleDir
            )
        )(else
            (send client:cel())
        )
    )


    (method (cycleDone)
    )

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

    (method (doit)
        (var FwdNextCel)
        (if (> (= FwdNextCel (self:nextCel())) (send client:lastCel()))
            (self:cycleDone())
        )(else
            (send client:cel(FwdNextCel))
        )
    )


    (method (cycleDone)
        (send client:cel(0))
    )

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

    (method (doit)
        (var temp0)
        (if (not (send client:isStopped()))
            (super:doit())
        )
    )

)
(class Rev of Cycle
    (properties
        client 0
        caller 0
        cycleDir -1
        cycleCnt 0
    )

    (method (doit)
        (var RevNextCel)
        (if (< (= RevNextCel (self:nextCel())) 0)
            (self:cycleDone())
        )(else
            (send client:cel(RevNextCel))
        )
    )


    (method (cycleDone)
        (send client:cel((send client:lastCel())))
    )

)
(class CT of Cycle
    (properties
        client 0
        caller 0
        cycleDir 1
        cycleCnt 0
        endCel 0
    )

    (method (init param1 param2 param3 param4)
        (var temp0)
        (asm
            pushi   #init
            pushi   1
            lsp     param1
            super   Cycle, 6
            lap     param3
            aTop    cycleDir
            lsp     paramTotal
            ldi     4
            eq?     
            bnt     code_01f1
            lap     param4
            aTop    caller
code_01f1:  pushi   #lastCel
            pushi   0
            pToa    client
            send    4
            sat     temp0
            lsp     param2
            gt?     
            bnt     code_0206
            lat     temp0
            jmp     code_0208
code_0206:  lap     param2
code_0208:  aTop    endCel
            pTos    endCel
            pushi   #cel
            pushi   0
            pToa    client
            send    4
            eq?     
            bnt     code_0246
            pTos    cycleDir
            pushi   #cel
            pushi   0
            pToa    client
            send    4
            add     
            sap     param2
            pushi   14
            pushi   1
            push    
            lat     temp0
            gt?     
            bnt     code_0232
            ldi     0
            jmp     code_0241
code_0232:  lsp     param2
            ldi     0
            lt?     
            bnt     code_023f
            lat     temp0
            jmp     code_0241
code_023f:  lap     param2
code_0241:  push    
            pToa    client
            send    6
code_0246:  ret     
        )
    )


    (method (doit)
        (var temp0, temp1)
        (asm
            pushi   #lastCel
            pushi   0
            pToa    client
            send    4
            sat     temp1
            pTos    endCel
            gt?     
            bnt     code_025d
            lat     temp1
            aTop    endCel
code_025d:  pTos    endCel
            pushi   #cel
            pushi   0
            pToa    client
            send    4
            eq?     
            bnt     code_0273
            pushi   #cycleDone
            pushi   0
            self    4
            jmp     code_029e
code_0273:  pushi   #nextCel
            pushi   0
            self    4
            sat     temp0
            pushi   14
            pushi   1
            push    
            lat     temp1
            gt?     
            bnt     code_028a
            ldi     0
            jmp     code_0299
code_028a:  lst     temp0
            ldi     0
            lt?     
            bnt     code_0297
            lat     temp1
            jmp     code_0299
code_0297:  lat     temp0
code_0299:  push    
            pToa    client
            send    6
code_029e:  ret     
        )
    )


    (method (cycleDone)
        (send client:cycler(0))
        (if (caller)
            (send caller:cue())
        )
        (self:dispose())
    )

)
(class End of CT
    (properties
        client 0
        caller 0
        cycleDir 1
        cycleCnt 0
        endCel 0
    )

    (method (init param1 param2)
        (super:init(param1 (send param1:lastCel()) 1 
            (if (== paramTotal 2)
                param2
            )(else
                0
            )
))
    )

)
(class Beg of CT
    (properties
        client 0
        caller 0
        cycleDir 1
        cycleCnt 0
        endCel 0
    )

    (method (init param1 param2)
        (super:init(param1 0 -1 
            (if (== paramTotal 2)
                param2
            )(else
                0
            )
))
    )

)
(class Motion of Obj
    (properties
        client 0
        caller 0
        x 0
        y 0
        dx 0
        dy 0
        {b-moveCnt} 0
        {b-i1} 0
        {b-i2} 0
        {b-di} 0
        {b-xAxis} 0
        {b-incr} 0
    )

    (method (init theClient theX theY theCaller)
        (var temp0[2])
        = client theClient
        = x theX
        = y theY
        (if (== paramTotal 4)
            = caller theCaller
        )
        = {b-moveCnt} 0
        (send theClient:heading(GetAngle((send theClient:x()) (send theClient:y()) theX theY)))
        (if ((send theClient:looper()))
            (send ((send theClient:looper())):doit(theClient (send theClient:heading())))
        )(else
            DirLoop(theClient (send theClient:heading()))
        )
        InitBresen(self)
    )


    (method (doit)
        (var temp0[6])
        (if ((== x (send client:x())) and (== y (send client:y())))
            (self:moveDone())
            return 
        )
        DoBresen(self)
    )


    (method (moveDone)
        (send client:mover(0))
        (if (caller)
            (send caller:cue())
        )
        (self:dispose())
    )


    (method (triedToMove)
        return == {b-moveCnt} 0
    )

)
(class MoveTo of Motion
    (properties
        client 0
        caller 0
        x 0
        y 0
        dx 0
        dy 0
        {b-moveCnt} 0
        {b-i1} 0
        {b-i2} 0
        {b-di} 0
        {b-xAxis} 0
        {b-incr} 0
    )

    (method (init param1)
        (super:init(rest param1))
        (super:doit())
    )

)
(class Wander of Motion
    (properties
        client 0
        caller 0
        x 0
        y 0
        dx 0
        dy 0
        {b-moveCnt} 0
        {b-i1} 0
        {b-i2} 0
        {b-di} 0
        {b-xAxis} 0
        {b-incr} 0
        distance 0
    )

    (method (init param1 param2)
        (var temp0, temp1, temp2)
        = distance 
            (if (== paramTotal 2)
                param2
            )(else
                30
            )
        = temp2 (* distance 2)
        = temp0 (+ (send param1:x()) (- distance Random(1 temp2)))
        = temp1 (+ (send param1:y()) (- distance Random(1 temp2)))
        (super:init(param1 temp0 temp1))
        (super:doit())
    )


    (method (doit)
        (super:doit())
        (if ((send client:isStopped()))
            (self:moveDone())
        )
    )


    (method (moveDone)
        (self:init(client distance))
    )

)
(class Follow of Motion
    (properties
        client 0
        caller 0
        x 0
        y 0
        dx 0
        dy 0
        {b-moveCnt} 0
        {b-i1} 0
        {b-i2} 0
        {b-di} 0
        {b-xAxis} 0
        {b-incr} 0
        who 0
        distance 0
    )

    (method (init theClient theWho param3)
        = who theWho
        = client theClient
        = distance 
            (if (< paramTotal 3)
                20
            )(else
                param3
            )
        (if (> (send theClient:distanceTo(who)) distance)
            (super:init(theClient (send who:x()) (send who:y())))
            (super:doit())
        )
    )


    (method (doit)
        (var temp0)
        (if (> (send client:distanceTo(who)) distance)
            (super:doit())
            (if (== {b-moveCnt} 0)
                (super:init(client (send who:x()) (send who:y())))
            )
        )(else
            = temp0 GetAngle((send client:x()) (send client:y()) (send who:x()) (send who:y()))
            (if ((send client:looper()))
                (send ((send client:looper())):doit(client temp0))
            )(else
                DirLoop(client temp0)
            )
        )
    )

)
(class Chase of Motion
    (properties
        client 0
        caller 0
        x 0
        y 0
        dx 0
        dy 0
        {b-moveCnt} 0
        {b-i1} 0
        {b-i2} 0
        {b-di} 0
        {b-xAxis} 0
        {b-incr} 0
        who 0
        distance 0
    )

    (method (init theClient theWho theDistance theCaller)
        = client theClient
        = who theWho
        = distance theDistance
        (if (== paramTotal 4)
            = caller theCaller
        )
        (super:init(client (send who:x()) (send who:y()) caller))
        (super:doit())
    )


    (method (doit)
        (if (<= (send client:distanceTo(who)) distance)
            (self:moveDone())
        )(else
            (super:doit())
            (if (== {b-moveCnt} 0)
                (super:init(client (send who:x()) (send who:y()) caller))
            )
        )
    )

)
(class Avoid of Obj
    (properties
        client 0
        heading -1
        oldDir 0
        olderDir 0
        impulse 0
    )

    (method (init)
        = heading -1
        = oldDir 65534
        = olderDir 65533
        = impulse 0
    )


    (method (doit)
        (var temp0[40], clientMover, theOldDir, temp42)
        = theOldDir DoAvoider(self)
        (if ((send client:mover()))
            = temp42 0
            (while ((== theOldDir olderDir) and (<= ++temp42 1))
                = heading -1
                = theOldDir DoAvoider(self)
            )
            (if (== theOldDir oldDir)
                = impulse (+ impulse 1)
            )(else
                (if ((> impulse 0) and not (send client:isBlocked()))
                    = theOldDir oldDir
                    --impulse
                )(else
                    = olderDir oldDir
                    = oldDir theOldDir
                    = impulse 1
                )
            )
        )
        (if (<> theOldDir -1)
            (if ((= clientMover (send client:mover())) and (send clientMover:isMemberOf(MoveTo)))
                (send client:setMotion(MoveTo (send clientMover:x()) (send clientMover:y()) (send clientMover:caller())))
            )
            (if ((send client:looper()))
                (send ((send client:looper())):doit(client theOldDir))
            )(else
                DirLoop(client theOldDir)
            )
            (if (not (send client:canBeHere()))
                (send client:findPosn())
            )
        )
    )

)
