from direct.showbase.InputStateGlobal import inputState
from direct.showbase.MessengerGlobal import messenger
#from DirectGui import *
#from PythonUtil import *
#from IntervalGlobal import *
#from otp.avatar import Avatar
from direct.directnotify import DirectNotifyGlobal
#import GhostWalker
#import GravityWalker
#import NonPhysicsWalker
#import PhysicsWalker
#if __debug__:
# import DevWalker
from direct.task import Task
from panda3d.core import ConfigVariableBool
# This is a hack, it may be better to use a line instead of a ray.
CollisionHandlerRayStart = 4000.0
[docs]class ControlManager:
notify = DirectNotifyGlobal.directNotify.newCategory("ControlManager")
wantWASD = ConfigVariableBool('want-WASD', False)
[docs] def __init__(self, enable=True, passMessagesThrough = False):
assert self.notify.debug("init control manager %s" % (passMessagesThrough))
assert self.notify.debugCall(id(self))
self.passMessagesThrough = passMessagesThrough
self.inputStateTokens = []
# Used to switch between strafe and turn. We will reset to whatever was last set.
self.WASDTurnTokens = []
self.__WASDTurn = True
self.controls = {}
self.currentControls = None
self.currentControlsName = None
self.isEnabled = 0
if enable:
self.enable()
#self.monitorTask = taskMgr.add(self.monitor, "ControlManager-%s"%(id(self)), priority=-1)
self.forceAvJumpToken = None
if self.passMessagesThrough: # for not breaking toontown
ist=self.inputStateTokens
ist.append(inputState.watchWithModifiers("forward", "arrow_up", inputSource=inputState.ArrowKeys))
ist.append(inputState.watchWithModifiers("reverse", "arrow_down", inputSource=inputState.ArrowKeys))
ist.append(inputState.watchWithModifiers("turnLeft", "arrow_left", inputSource=inputState.ArrowKeys))
ist.append(inputState.watchWithModifiers("turnRight", "arrow_right", inputSource=inputState.ArrowKeys))
def __str__(self):
return 'ControlManager: using \'%s\'' % self.currentControlsName
[docs] def add(self, controls, name="basic"):
"""Add a control instance to the list of available control systems.
Args:
controls: an avatar control system.
name (str): any key that you want to use to refer to the controls
later (e.g. using the use(<name>) call).
See also: :meth:`use()`.
"""
assert self.notify.debugCall(id(self))
assert controls is not None
oldControls = self.controls.get(name)
if oldControls is not None:
assert self.notify.debug("Replacing controls: %s" % name)
oldControls.disableAvatarControls()
oldControls.setCollisionsActive(0)
oldControls.delete()
controls.disableAvatarControls()
controls.setCollisionsActive(0)
self.controls[name] = controls
[docs] def get(self, name):
return self.controls.get(name)
[docs] def remove(self, name):
"""Remove a control instance from the list of available control
systems.
Args:
name: any key that was used to refer to the controls when they were
added (e.g. using the add(<controls>, <name>) call).
See also: :meth:`add()`.
"""
assert self.notify.debugCall(id(self))
oldControls = self.controls.pop(name,None)
if oldControls is not None:
assert self.notify.debug("Removing controls: %s" % name)
oldControls.disableAvatarControls()
oldControls.setCollisionsActive(0)
if __debug__:
[docs] def lockControls(self):
self.ignoreUse=True
[docs] def unlockControls(self):
if hasattr(self, "ignoreUse"):
del self.ignoreUse
[docs] def use(self, name, avatar):
"""
name is a key (string) that was previously passed to add().
Use a previously added control system.
See also: :meth:`add()`.
"""
assert self.notify.debugCall(id(self))
if __debug__ and hasattr(self, "ignoreUse"):
return
controls = self.controls.get(name)
if controls is not None:
if controls is not self.currentControls:
if self.currentControls is not None:
self.currentControls.disableAvatarControls()
self.currentControls.setCollisionsActive(0)
self.currentControls.setAvatar(None)
self.currentControls = controls
self.currentControlsName = name
self.currentControls.setAvatar(avatar)
self.currentControls.setCollisionsActive(1)
if self.isEnabled:
self.currentControls.enableAvatarControls()
messenger.send('use-%s-controls'%(name,), [avatar])
#else:
# print "Controls are already", name
else:
assert self.notify.debug("Unkown controls: %s" % name)
[docs] def setSpeeds(self, forwardSpeed, jumpForce,
reverseSpeed, rotateSpeed, strafeLeft=0, strafeRight=0):
assert self.notify.debugCall(id(self))
for controls in self.controls.values():
controls.setWalkSpeed(
forwardSpeed, jumpForce, reverseSpeed, rotateSpeed)
[docs] def delete(self):
assert self.notify.debugCall(id(self))
self.disable()
for controls in list(self.controls.keys()):
self.remove(controls)
del self.controls
del self.currentControls
for token in self.inputStateTokens:
token.release()
for token in self.WASDTurnTokens:
token.release()
self.WASDTurnTokens = []
#self.monitorTask.remove()
[docs] def getSpeeds(self):
if self.currentControls:
return self.currentControls.getSpeeds()
return None
[docs] def getIsAirborne(self):
if self.currentControls:
return self.currentControls.getIsAirborne()
return False
[docs] def setTag(self, key, value):
assert self.notify.debugCall(id(self))
for controls in self.controls.values():
controls.setTag(key, value)
[docs] def deleteCollisions(self):
assert self.notify.debugCall(id(self))
for controls in self.controls.values():
controls.deleteCollisions()
[docs] def collisionsOn(self):
assert self.notify.debugCall(id(self))
if self.currentControls:
self.currentControls.setCollisionsActive(1)
[docs] def collisionsOff(self):
assert self.notify.debugCall(id(self))
if self.currentControls:
self.currentControls.setCollisionsActive(0)
[docs] def placeOnFloor(self):
assert self.notify.debugCall(id(self))
if self.currentControls:
self.currentControls.placeOnFloor()
[docs] def enable(self):
assert self.notify.debugCall(id(self))
if self.isEnabled:
assert self.notify.debug('already isEnabled')
return
self.isEnabled = 1
# keep track of what we do on the inputState so we can undo it later on
#self.inputStateTokens = []
ist = self.inputStateTokens
ist.append(inputState.watch("run", 'runningEvent', "running-on", "running-off"))
ist.append(inputState.watchWithModifiers("forward", "arrow_up", inputSource=inputState.ArrowKeys))
ist.append(inputState.watch("forward", "force-forward", "force-forward-stop"))
ist.append(inputState.watchWithModifiers("reverse", "arrow_down", inputSource=inputState.ArrowKeys))
ist.append(inputState.watchWithModifiers("reverse", "mouse4", inputSource=inputState.Mouse))
if self.wantWASD:
ist.append(inputState.watchWithModifiers("turnLeft", "arrow_left", inputSource=inputState.ArrowKeys))
ist.append(inputState.watch("turnLeft", "mouse-look_left", "mouse-look_left-done"))
ist.append(inputState.watch("turnLeft", "force-turnLeft", "force-turnLeft-stop"))
ist.append(inputState.watchWithModifiers("turnRight", "arrow_right", inputSource=inputState.ArrowKeys))
ist.append(inputState.watch("turnRight", "mouse-look_right", "mouse-look_right-done"))
ist.append(inputState.watch("turnRight", "force-turnRight", "force-turnRight-stop"))
ist.append(inputState.watchWithModifiers("forward", "w", inputSource=inputState.WASD))
ist.append(inputState.watchWithModifiers("reverse", "s", inputSource=inputState.WASD))
ist.append(inputState.watchWithModifiers("slideLeft", "q", inputSource=inputState.QE))
ist.append(inputState.watchWithModifiers("slideRight", "e", inputSource=inputState.QE))
self.setWASDTurn(self.__WASDTurn)
else:
ist.append(inputState.watchWithModifiers("turnLeft", "arrow_left", inputSource=inputState.ArrowKeys))
ist.append(inputState.watch("turnLeft", "mouse-look_left", "mouse-look_left-done"))
ist.append(inputState.watch("turnLeft", "force-turnLeft", "force-turnLeft-stop"))
ist.append(inputState.watchWithModifiers("turnRight", "arrow_right", inputSource=inputState.ArrowKeys))
ist.append(inputState.watch("turnRight", "mouse-look_right", "mouse-look_right-done"))
ist.append(inputState.watch("turnRight", "force-turnRight", "force-turnRight-stop"))
# Jump controls
if self.wantWASD:
ist.append(inputState.watchWithModifiers("jump", "space"))
else:
ist.append(inputState.watch("jump", "control", "control-up"))
if self.currentControls:
self.currentControls.enableAvatarControls()
[docs] def disable(self):
assert self.notify.debugCall(id(self))
self.isEnabled = 0
for token in self.inputStateTokens:
token.release()
self.inputStateTokens = []
for token in self.WASDTurnTokens:
token.release()
self.WASDTurnTokens = []
if self.currentControls:
self.currentControls.disableAvatarControls()
if self.passMessagesThrough: # for not breaking toontown
ist=self.inputStateTokens
ist.append(inputState.watchWithModifiers("forward", "arrow_up", inputSource=inputState.ArrowKeys))
ist.append(inputState.watchWithModifiers("reverse", "arrow_down", inputSource=inputState.ArrowKeys))
ist.append(inputState.watchWithModifiers("turnLeft", "arrow_left", inputSource=inputState.ArrowKeys))
ist.append(inputState.watchWithModifiers("turnRight", "arrow_right", inputSource=inputState.ArrowKeys))
[docs] def stop(self):
self.disable()
if self.currentControls:
self.currentControls.setCollisionsActive(0)
self.currentControls.setAvatar(None)
self.currentControls = None
[docs] def disableAvatarJump(self):
"""
prevent
"""
assert self.forceAvJumpToken is None
self.forceAvJumpToken=inputState.force(
"jump", 0, 'ControlManager.disableAvatarJump')
[docs] def enableAvatarJump(self):
"""
Stop forcing the ctrl key to return 0's
"""
assert self.forceAvJumpToken is not None
self.forceAvJumpToken.release()
self.forceAvJumpToken = None
[docs] def monitor(self, _):
#assert self.debugPrint("monitor()")
#if 1:
# airborneHeight=self.avatar.getAirborneHeight()
# onScreenDebug.add("airborneHeight", "% 10.4f"%(airborneHeight,))
#if 0:
# onScreenDebug.add("InputState forward", "%d"%(inputState.isSet("forward")))
# onScreenDebug.add("InputState reverse", "%d"%(inputState.isSet("reverse")))
# onScreenDebug.add("InputState turnLeft", "%d"%(inputState.isSet("turnLeft")))
# onScreenDebug.add("InputState turnRight", "%d"%(inputState.isSet("turnRight")))
# onScreenDebug.add("InputState slideLeft", "%d"%(inputState.isSet("slideLeft")))
# onScreenDebug.add("InputState slideRight", "%d"%(inputState.isSet("slideRight")))
return Task.cont
[docs] def setWASDTurn(self, turn):
self.__WASDTurn = turn
if not self.isEnabled:
return
turnLeftWASDSet = inputState.isSet("turnLeft", inputSource=inputState.WASD)
turnRightWASDSet = inputState.isSet("turnRight", inputSource=inputState.WASD)
slideLeftWASDSet = inputState.isSet("slideLeft", inputSource=inputState.WASD)
slideRightWASDSet = inputState.isSet("slideRight", inputSource=inputState.WASD)
for token in self.WASDTurnTokens:
token.release()
if turn:
self.WASDTurnTokens = (
inputState.watchWithModifiers("turnLeft", "a", inputSource=inputState.WASD),
inputState.watchWithModifiers("turnRight", "d", inputSource=inputState.WASD),
)
inputState.set("turnLeft", slideLeftWASDSet, inputSource=inputState.WASD)
inputState.set("turnRight", slideRightWASDSet, inputSource=inputState.WASD)
inputState.set("slideLeft", False, inputSource=inputState.WASD)
inputState.set("slideRight", False, inputSource=inputState.WASD)
else:
self.WASDTurnTokens = (
inputState.watchWithModifiers("slideLeft", "a", inputSource=inputState.WASD),
inputState.watchWithModifiers("slideRight", "d", inputSource=inputState.WASD),
)
inputState.set("slideLeft", turnLeftWASDSet, inputSource=inputState.WASD)
inputState.set("slideRight", turnRightWASDSet, inputSource=inputState.WASD)
inputState.set("turnLeft", False, inputSource=inputState.WASD)
inputState.set("turnRight", False, inputSource=inputState.WASD)