oldschool-toontown/toontown/minigame/OrthoDrive.py

155 lines
5.1 KiB
Python
Raw Normal View History

2023-04-23 22:18:37 -05:00
from panda3d.core import Point3, Vec3
from direct.directnotify.DirectNotifyGlobal import directNotify
from direct.interval.IntervalGlobal import LerpHprInterval
from direct.showbase.PythonUtil import fitSrcAngle2Dest
from direct.task.TaskManagerGlobal import taskMgr
2019-11-02 17:27:54 -05:00
from otp.otpbase import OTPGlobals
2023-04-23 22:18:37 -05:00
from toontown.minigame.ArrowKeys import ArrowKeys
from toontown.toonbase.ToonBaseGlobal import base
2019-11-02 17:27:54 -05:00
class OrthoDrive:
2023-04-23 22:18:37 -05:00
notify = directNotify.newCategory('OrthoDrive')
2019-11-02 17:27:54 -05:00
TASK_NAME = 'OrthoDriveTask'
SET_ATREST_HEADING_TASK = 'setAtRestHeadingTask'
def __init__(self, speed, maxFrameMove = None, customCollisionCallback = None, priority = 0, setHeading = 1, upHeading = 0, instantTurn = False, wantSound = False):
self.wantSound = wantSound
self.speed = speed
self.maxFrameMove = maxFrameMove
self.customCollisionCallback = customCollisionCallback
self.priority = priority
self.setHeading = setHeading
self.upHeading = upHeading
2023-04-23 22:18:37 -05:00
self.arrowKeys = ArrowKeys()
2019-11-02 17:27:54 -05:00
self.lt = base.localAvatar
self.instantTurn = instantTurn
def destroy(self):
self.arrowKeys.destroy()
del self.arrowKeys
del self.customCollisionCallback
def start(self):
self.notify.debug('start')
self.__placeToonHOG(self.lt.getPos())
taskMgr.add(self.__update, OrthoDrive.TASK_NAME, priority=self.priority)
self.lastAction = None
def __placeToonHOG(self, pos, h = None):
if h == None:
h = self.lt.getH()
2023-04-23 23:12:43 -05:00
2019-11-02 17:27:54 -05:00
self.lt.setPos(pos)
self.lt.setH(h)
self.lastPos = pos
self.atRestHeading = h
self.lastXVel = 0
self.lastYVel = 0
def stop(self):
self.notify.debug('stop')
self.lt.stopSound()
taskMgr.remove(OrthoDrive.TASK_NAME)
taskMgr.remove(OrthoDrive.SET_ATREST_HEADING_TASK)
if hasattr(self, 'turnLocalToonIval'):
if self.turnLocalToonIval.isPlaying():
self.turnLocalToonIval.pause()
2023-04-23 23:12:43 -05:00
2019-11-02 17:27:54 -05:00
del self.turnLocalToonIval
2023-04-23 23:12:43 -05:00
2019-11-02 17:27:54 -05:00
base.localAvatar.setSpeed(0, 0)
def __update(self, task):
vel = Vec3(0, 0, 0)
xVel = 0
yVel = 0
if self.arrowKeys.upPressed():
yVel += 1
2023-04-23 23:12:43 -05:00
2019-11-02 17:27:54 -05:00
if self.arrowKeys.downPressed():
yVel -= 1
2023-04-23 23:12:43 -05:00
2019-11-02 17:27:54 -05:00
if self.arrowKeys.leftPressed():
xVel -= 1
2023-04-23 23:12:43 -05:00
2019-11-02 17:27:54 -05:00
if self.arrowKeys.rightPressed():
xVel += 1
2023-04-23 23:12:43 -05:00
2019-11-02 17:27:54 -05:00
vel.setX(xVel)
vel.setY(yVel)
vel.normalize()
vel *= self.speed
speed = vel.length()
action = self.lt.setSpeed(speed, 0)
if action != self.lastAction:
self.lastAction = action
if self.wantSound:
if action == OTPGlobals.WALK_INDEX or action == OTPGlobals.REVERSE_INDEX:
self.lt.walkSound()
elif action == OTPGlobals.RUN_INDEX:
self.lt.runSound()
else:
self.lt.stopSound()
2023-04-23 23:12:43 -05:00
2019-11-02 17:27:54 -05:00
if self.setHeading:
self.__handleHeading(xVel, yVel)
2023-04-23 23:12:43 -05:00
2019-11-02 17:27:54 -05:00
toonPos = self.lt.getPos()
2023-04-23 22:18:37 -05:00
dt = base.clock.getDt()
2019-11-02 17:27:54 -05:00
posOffset = vel * dt
posOffset += toonPos - self.lastPos
toonPos = self.lastPos
if self.maxFrameMove:
posOffsetLen = posOffset.length()
if posOffsetLen > self.maxFrameMove:
posOffset *= self.maxFrameMove
posOffset /= posOffsetLen
2023-04-23 23:12:43 -05:00
2019-11-02 17:27:54 -05:00
if self.customCollisionCallback:
toonPos = self.customCollisionCallback(toonPos, toonPos + posOffset)
else:
toonPos = toonPos + posOffset
2023-04-23 23:12:43 -05:00
2019-11-02 17:27:54 -05:00
self.lt.setPos(toonPos)
self.lastPos = toonPos
2023-04-23 22:18:37 -05:00
return task.cont
2019-11-02 17:27:54 -05:00
def __handleHeading(self, xVel, yVel):
def getHeading(xVel, yVel):
angTab = [[None, 0, 180], [-90, -45, -135], [90, 45, 135]]
return angTab[xVel][yVel] + self.upHeading
def orientToon(angle, self = self):
startAngle = self.lt.getH()
startAngle = fitSrcAngle2Dest(startAngle, angle)
dur = 0.1 * abs(startAngle - angle) / 90
self.turnLocalToonIval = LerpHprInterval(self.lt, dur, Point3(angle, 0, 0), startHpr=Point3(startAngle, 0, 0), name='OrthoDriveLerpHpr')
if self.instantTurn:
self.turnLocalToonIval.finish()
else:
self.turnLocalToonIval.start()
if xVel != self.lastXVel or yVel != self.lastYVel:
taskMgr.remove(OrthoDrive.SET_ATREST_HEADING_TASK)
if not (xVel or yVel):
orientToon(self.atRestHeading)
else:
curHeading = getHeading(xVel, yVel)
if ((self.lastXVel and self.lastYVel) and not (xVel and yVel)):
def setAtRestHeading(task, self = self, angle = curHeading):
self.atRestHeading = angle
2023-04-23 22:18:37 -05:00
return task.done
2019-11-02 17:27:54 -05:00
taskMgr.doMethodLater(0.05, setAtRestHeading, OrthoDrive.SET_ATREST_HEADING_TASK)
else:
self.atRestHeading = curHeading
2023-04-23 23:12:43 -05:00
2019-11-02 17:27:54 -05:00
orientToon(curHeading)
2023-04-23 23:12:43 -05:00
2019-11-02 17:27:54 -05:00
self.lastXVel = xVel
self.lastYVel = yVel