Poodletooth-iLand/toontown/safezone/DistributedGolfKartAI.py
2015-11-14 14:28:53 -05:00

320 lines
11 KiB
Python

import random
from TrolleyConstants import *
from direct.directnotify import DirectNotifyGlobal
from direct.distributed import DistributedObjectAI
from direct.distributed.ClockDelta import *
from direct.fsm import ClassicFSM, State
from otp.ai.AIBase import *
from toontown.golf import GolfGlobals
from toontown.golf import GolfManagerAI
from toontown.toonbase.ToontownGlobals import *
class DistributedGolfKartAI(DistributedObjectAI.DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedGolfKartAI')
def __init__(self, air, golfCourse, x, y, z, h, p, r):
DistributedObjectAI.DistributedObjectAI.__init__(self, air)
self.seats = [None, None, None, None]
self.golfCourse = golfCourse
self.posHpr = (x, y, z, h, p, r)
self.chooseColor()
self.accepting = 0
self.trolleyCountdownTime = simbase.config.GetFloat(
'trolley-countdown-time', TROLLEY_COUNTDOWN_TIME)
self.fsm = ClassicFSM.ClassicFSM(
'DistributedGolfKartAI',
[
State.State('off', self.enterOff, self.exitOff, ['entering']),
State.State('entering', self.enterEntering, self.exitEntering, ['waitEmpty']),
State.State('waitEmpty', self.enterWaitEmpty, self.exitWaitEmpty, ['waitCountdown']),
State.State('waitCountdown', self.enterWaitCountdown, self.exitWaitCountdown, ['waitEmpty', 'allAboard']),
State.State('allAboard', self.enterAllAboard, self.exitAllAboard, ['leaving', 'waitEmpty']),
State.State('leaving', self.enterLeaving, self.exitLeaving, ['entering'])
], 'off', 'off')
self.fsm.enterInitialState()
def delete(self):
self.fsm.requestFinalState()
del self.fsm
DistributedObjectAI.DistributedObjectAI.delete(self)
def findAvailableSeat(self):
for i in xrange(len(self.seats)):
if self.seats[i] is None:
return i
def findAvatar(self, avId):
for i in xrange(len(self.seats)):
if self.seats[i] == avId:
return i
def countFullSeats(self):
avCounter = 0
for i in self.seats:
if i:
avCounter += 1
return avCounter
def rejectingBoardersHandler(self, avId):
self.rejectBoarder(avId)
def rejectBoarder(self, avId):
self.sendUpdateToAvatarId(avId, 'rejectBoard', [avId])
def acceptingBoardersHandler(self, avId):
self.notify.debug('acceptingBoardersHandler')
seatIndex = self.findAvailableSeat()
if seatIndex is None:
self.rejectBoarder(avId)
else:
self.acceptBoarder(avId, seatIndex)
def acceptBoarder(self, avId, seatIndex):
self.notify.debug('acceptBoarder')
if self.findAvatar(avId) is not None:
return
self.seats[seatIndex] = avId
self.acceptOnce(
self.air.getAvatarExitEvent(avId),
self.__handleUnexpectedExit, extraArgs=[avId])
self.timeOfBoarding = globalClock.getRealTime()
self.sendUpdate('fillSlot' + str(seatIndex), [avId])
self.waitCountdown()
def __handleUnexpectedExit(self, avId):
self.notify.warning('Avatar: ' + str(avId) + ' has exited unexpectedly')
seatIndex = self.findAvatar(avId)
if seatIndex is None:
return
self.clearFullNow(seatIndex)
self.clearEmptyNow(seatIndex)
if self.countFullSeats() == 0:
self.waitEmpty()
def rejectingExitersHandler(self, avId):
self.rejectExiter(avId)
def rejectExiter(self, avId):
pass
def acceptingExitersHandler(self, avId):
self.acceptExiter(avId)
def acceptExiter(self, avId):
seatIndex = self.findAvatar(avId)
if seatIndex is None:
return
self.clearFullNow(seatIndex)
self.sendUpdate('emptySlot' + str(seatIndex), [avId, globalClockDelta.getRealNetworkTime()])
if self.countFullSeats() == 0:
self.waitEmpty()
taskMgr.doMethodLater(
TOON_EXIT_TIME, self.clearEmptyNow,
self.uniqueName('clearEmpty-%s' % seatIndex),
extraArgs=(seatIndex,))
def clearEmptyNow(self, seatIndex):
self.sendUpdate('emptySlot' + str(seatIndex), [0, globalClockDelta.getRealNetworkTime()])
def clearFullNow(self, seatIndex):
avId = self.seats[seatIndex]
if avId == 0:
self.notify.warning('Clearing an empty seat index: ' + str(seatIndex) + ' ... Strange...')
else:
self.seats[seatIndex] = None
self.sendUpdate('fillSlot' + str(seatIndex), [0])
if avId:
self.ignore(self.air.getAvatarExitEvent(avId))
def d_setState(self, state):
self.sendUpdate('setState', [state, globalClockDelta.getRealNetworkTime()])
def getState(self):
return self.fsm.getCurrentState().getName()
def requestBoard(self, *args):
self.notify.debug('requestBoard')
avId = self.air.getAvatarIdFromSender()
if self.findAvatar(avId) != None:
self.notify.warning('Ignoring multiple requests from %s to board.' % avId)
return None
av = self.air.doId2do.get(avId)
if av:
newArgs = (avId,) + args
if av.hp > 0 and self.accepting:
self.acceptingBoardersHandler(*newArgs)
else:
self.rejectingBoardersHandler(*newArgs)
else:
self.notify.warning('avid: %s does not exist, but tried to board a trolley' % avId)
def requestExit(self, *args):
self.notify.debug('requestExit')
avId = self.air.getAvatarIdFromSender()
av = self.air.doId2do.get(avId)
if av:
newArgs = (avId,) + args
if self.accepting:
self.acceptingExitersHandler(*newArgs)
else:
self.rejectingExitersHandler(*newArgs)
else:
self.notify.warning('avId: %s does not exist, but tried to exit a trolley' % avId)
def start(self):
self.enter()
def enterOff(self):
self.accepting = 0
if hasattr(self, 'doId'):
for seatIndex in xrange(4):
taskMgr.remove(self.uniqueName('clearEmpty-' + str(seatIndex)))
def exitOff(self):
self.accepting = 0
def enter(self):
self.fsm.request('entering')
def enterEntering(self):
self.d_setState('entering')
self.accepting = 0
self.seats = [None, None, None, None]
taskMgr.doMethodLater(
TROLLEY_ENTER_TIME, self.waitEmptyTask,
self.uniqueName('entering-timer'))
def exitEntering(self):
self.accepting = 0
taskMgr.remove(self.uniqueName('entering-timer'))
def waitEmptyTask(self, task):
self.waitEmpty()
return Task.done
def waitEmpty(self):
self.fsm.request('waitEmpty')
def enterWaitEmpty(self):
self.d_setState('waitEmpty')
self.accepting = 1
def exitWaitEmpty(self):
self.accepting = 0
def waitCountdown(self):
self.fsm.request('waitCountdown')
def enterWaitCountdown(self):
self.d_setState('waitCountdown')
self.accepting = 1
taskMgr.doMethodLater(
self.trolleyCountdownTime, self.timeToGoTask,
self.uniqueName('countdown-timer'))
def timeToGoTask(self, task):
if self.countFullSeats() > 0:
self.allAboard()
else:
self.waitEmpty()
return Task.done
def exitWaitCountdown(self):
self.accepting = 0
taskMgr.remove(self.uniqueName('countdown-timer'))
def allAboard(self):
self.fsm.request('allAboard')
def enterAllAboard(self):
self.accepting = 0
currentTime = globalClock.getRealTime()
elapsedTime = currentTime - self.timeOfBoarding
self.notify.debug('elapsed time: ' + str(elapsedTime))
waitTime = max(TOON_BOARD_TIME - elapsedTime, 0)
taskMgr.doMethodLater(
waitTime, self.leaveTask, self.uniqueName('waitForAllAboard'))
def exitAllAboard(self):
self.accepting = 0
taskMgr.remove(self.uniqueName('waitForAllAboard'))
def leaveTask(self, task):
if self.countFullSeats() > 0:
self.leave()
else:
self.waitEmpty()
return Task.done
def leave(self):
self.fsm.request('leaving')
def enterLeaving(self):
self.d_setState('leaving')
self.accepting = 0
taskMgr.doMethodLater(
TROLLEY_EXIT_TIME, self.trolleyLeftTask,
self.uniqueName('leaving-timer'))
def trolleyLeftTask(self, task):
self.trolleyLeft()
return Task.done
def trolleyLeft(self):
numPlayers = self.countFullSeats()
avIdList = []
if numPlayers > 0:
for seatIndex in xrange(len(self.seats)):
avId = self.seats[seatIndex]
avIdList.append(avId)
self.clearFullNow(seatIndex)
golfManager = GolfManagerAI.GolfManagerAI()
golfZone = golfManager.readyGolfCourse(avIdList, self.golfCourse)
for avId in avIdList:
if avId:
self.sendUpdateToAvatarId(avId, 'setGolfZone', [golfZone, 0])
else:
self.notify.warning('The trolley left, but was empty.')
self.enter()
def exitLeaving(self):
self.accepting = 0
self.chooseColor()
self.sendUpdate('setColor', [self.color[0], self.color[1], self.color[2]])
taskMgr.remove(self.uniqueName('leaving-timer'))
def getGolfCourse(self):
return self.golfCourse
def getPosHpr(self):
return self.posHpr
def getColor(self):
return self.color
def chooseColor(self):
self.color = (
random.randint(
GolfGlobals.KartColors[self.golfCourse][0][0],
GolfGlobals.KartColors[self.golfCourse][0][1]
),
random.randint(
GolfGlobals.KartColors[self.golfCourse][1][0],
GolfGlobals.KartColors[self.golfCourse][1][1]
),
random.randint(
GolfGlobals.KartColors[self.golfCourse][2][0],
GolfGlobals.KartColors[self.golfCourse][2][1]
)
)
if self.golfCourse == 1:
if self.color[0] + self.color[1] <= 255:
self.color = (
self.color[0],
self.color[0] + self.color[1],
self.color[2]
)
else:
self.color = (self.color[0], 255, self.color[2])