panda3d/direct/src/level/DistributedInteractiveEntityAI.py

141 lines
5.0 KiB
Python

""" DistributedInteractiveEntityAI module: contains the DistributedInteractiveEntityAI
class, the server side representation of a simple, animated, interactive
prop."""
from AIBaseGlobal import *
from ClockDelta import *
import DirectNotifyGlobal
import ClassicFSM
import DistributedEntityAI
import State
class DistributedInteractiveEntityAI(DistributedEntityAI.DistributedEntityAI):
"""
DistributedInteractiveEntityAI class: The server side representation of
an animated prop. This is the object that remembers what the
prop is doing. The child of this object, the DistributedAnimatedProp
object, is the client side version and updates the display that
client's display based on the state of the prop.
"""
if __debug__:
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedInteractiveEntityAI')
def __init__(self, level, entId):
"""entId: a unique identifier for this prop."""
DistributedEntityAI.DistributedEntityAI.__init__(self, level, entId)
assert(self.debugPrint(
"DistributedInteractiveEntityAI(entId=%s)"
%(entId)))
self.fsm = ClassicFSM.ClassicFSM('DistributedInteractiveEntityAI',
[State.State('off',
self.enterOff,
self.exitOff,
['playing']),
# Attract is an idle mode. It is named attract
# because the prop is not interacting with an
# avatar, and is therefore trying to attract an
# avatar.
State.State('attract',
self.enterAttract,
self.exitAttract,
['playing']),
# Playing is for when an avatar is interacting
# with the prop.
State.State('playing',
self.enterPlaying,
self.exitPlaying,
['attract'])],
# Initial State
'off',
# Final State
'off',
)
self.fsm.enterInitialState()
self.avatarId=0
def delete(self):
del self.fsm
DistributedEntityAI.DistributedEntityAI.delete(self)
def getAvatarInteract(self):
assert(self.debugPrint("getAvatarInteract() returning: %s"%(self.avatarId,)))
return self.avatarId
#def getOwnerDoId(self):
# assert(self.debugPrint("getOwnerDoId() returning: %s"%(self.ownerDoId,)))
# return self.ownerDoId
def requestInteract(self):
assert(self.debugPrint("requestInteract()"))
avatarId = self.air.msgSender
assert(self.notify.debug(" avatarId:%s"%(avatarId,)))
stateName = self.fsm.getCurrentState().getName()
if stateName != 'playing':
self.sendUpdate("setAvatarInteract", [avatarId])
self.avatarId=avatarId
self.fsm.request('playing')
else:
self.sendUpdateToAvatarId(avatarId, "rejectInteract", [])
def requestExit(self):
assert(self.debugPrint("requestExit()"))
avatarId = self.air.msgSender
assert(self.notify.debug(" avatarId:%s"%(avatarId,)))
if avatarId==self.avatarId:
stateName = self.fsm.getCurrentState().getName()
if stateName == 'playing':
self.sendUpdate("avatarExit", [avatarId])
self.fsm.request('attract')
else:
assert(self.notify.debug(" requestExit: invalid avatarId"))
def getState(self):
r = [
self.fsm.getCurrentState().getName(),
globalClockDelta.getRealNetworkTime()]
assert(self.debugPrint("getState() returning %s"%(r,)))
return r
def sendState(self):
assert(self.debugPrint("sendState()"))
self.sendUpdate('setState', self.getState())
##### off state #####
def enterOff(self):
assert(self.debugPrint("enterOff()"))
#self.setState('off')
def exitOff(self):
assert(self.debugPrint("exitOff()"))
##### attract state #####
def enterAttract(self):
assert(self.debugPrint("enterAttract()"))
self.sendState()
def exitAttract(self):
assert(self.debugPrint("exitAttract()"))
##### open state #####
def enterPlaying(self):
assert(self.debugPrint("enterPlaying()"))
self.sendState()
def exitPlaying(self):
assert(self.debugPrint("exitPlaying()"))
if __debug__:
def debugPrint(self, message):
"""for debugging"""
return self.notify.debug(
str(self.__dict__.get('entId', '?'))+' '+message)