oldschool-toontown/toontown/building/DistributedElevatorAI.py
2019-12-30 01:07:56 -05:00

318 lines
10 KiB
Python

from otp.ai.AIBase import *
from toontown.toonbase import ToontownGlobals
from direct.distributed.ClockDelta import *
from .ElevatorConstants import *
from direct.distributed import DistributedObjectAI
from direct.fsm import ClassicFSM, State
from direct.fsm import State
from direct.task import Task
from direct.directnotify import DirectNotifyGlobal
from toontown.toonbase import ToontownAccessAI
class DistributedElevatorAI(DistributedObjectAI.DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedElevatorAI')
def __init__(self, air, bldg, numSeats=4, antiShuffle=0, minLaff=0, fSkipOpening=False):
DistributedObjectAI.DistributedObjectAI.__init__(self, air)
self.fSkipOpening = fSkipOpening
self.type = ELEVATOR_NORMAL
self.countdownTime = ElevatorData[self.type]['countdown']
self.bldg = bldg
self.bldgDoId = bldg.getDoId()
self.seats = []
self.setAntiShuffle(antiShuffle)
self.setMinLaff(minLaff)
if self.antiShuffle:
if not hasattr(simbase.air, 'elevatorTripId'):
simbase.air.elevatorTripId = 1
self.elevatorTripId = simbase.air.elevatorTripId
simbase.air.elevatorTripId += 1
else:
self.elevatorTripId = 0
for seat in range(numSeats):
self.seats.append(None)
self.accepting = 0
self.fsm = ClassicFSM.ClassicFSM('DistributedElevatorAI', [
State.State('off', self.enterOff, self.exitOff, [
'opening', 'closed', 'waitEmpty']),
State.State('opening', self.enterOpening, self.exitOpening, [
'waitEmpty', 'waitCountdown']),
State.State('waitEmpty', self.enterWaitEmpty, self.exitWaitEmpty, [
'waitCountdown']),
State.State('waitCountdown', self.enterWaitCountdown, self.exitWaitCountdown, [
'waitEmpty', 'allAboard']),
State.State('allAboard', self.enterAllAboard, self.exitAllAboard, [
'closing', 'waitEmpty']),
State.State('closing', self.enterClosing, self.exitClosing, [
'closed', 'waitEmpty']),
State.State('closed', self.enterClosed, self.exitClosed, [
'opening'])], 'off', 'off')
self.fsm.enterInitialState()
self.boardingParty = None
return
def delete(self):
self.fsm.requestFinalState()
del self.fsm
del self.bldg
self.ignoreAll()
DistributedObjectAI.DistributedObjectAI.delete(self)
def setBoardingParty(self, party):
self.boardingParty = party
def generate(self):
if not self.fSkipOpening:
self.start()
else:
self.fsm.request('waitEmpty')
DistributedObjectAI.DistributedObjectAI.generate(self)
def getBldgDoId(self):
return self.bldgDoId
def findAvailableSeat(self):
for i in range(len(self.seats)):
if self.seats[i] == None:
return i
return
def findAvatar(self, avId):
for i in range(len(self.seats)):
if self.seats[i] == avId:
return i
return None
def countFullSeats(self):
avCounter = 0
for i in self.seats:
if i:
avCounter += 1
return avCounter
def countOpenSeats(self):
openSeats = 0
for i in range(len(self.seats)):
if self.seats[i] == None:
openSeats += 1
return openSeats
def rejectingBoardersHandler(self, avId, reason=0, wantBoardingShow=0):
self.rejectBoarder(avId, reason)
def rejectBoarder(self, avId, reason=0):
self.sendUpdateToAvatarId(avId, 'rejectBoard', [avId, reason])
def acceptingBoardersHandler(self, avId, reason=0, wantBoardingShow=0):
self.notify.debug('acceptingBoardersHandler')
seatIndex = self.findAvailableSeat()
if seatIndex == None:
self.rejectBoarder(avId, REJECT_NOSEAT)
else:
self.acceptBoarder(avId, seatIndex, wantBoardingShow)
return
def acceptBoarder(self, avId, seatIndex, wantBoardingShow=0):
self.notify.debug('acceptBoarder')
if self.findAvatar(avId) != None:
return
self.seats[seatIndex] = avId
self.timeOfBoarding = globalClock.getRealTime()
if wantBoardingShow:
self.timeOfGroupBoarding = globalClock.getRealTime()
self.sendUpdate('fillSlot' + str(seatIndex), [avId, wantBoardingShow])
return
def rejectingExitersHandler(self, avId):
self.rejectExiter(avId)
def rejectExiter(self, avId):
pass
def acceptingExitersHandler(self, avId):
self.acceptExiter(avId)
def clearEmptyNow(self, seatIndex):
self.sendUpdate('emptySlot' + str(seatIndex), [
0, 0, globalClockDelta.getRealNetworkTime(), 0])
def clearFullNow(self, seatIndex):
avId = self.seats[seatIndex]
if avId == None:
self.notify.warning('Clearing an empty seat index: ' + str(seatIndex) + ' ... Strange...')
else:
self.seats[seatIndex] = None
self.sendUpdate('fillSlot' + str(seatIndex), [0, 0])
self.ignore(self.air.getAvatarExitEvent(avId))
return
def d_setState(self, state):
self.sendUpdate('setState', [state, globalClockDelta.getRealNetworkTime()])
def getState(self):
return self.fsm.getCurrentState().getName()
def avIsOKToBoard(self, av):
return av.hp > self.minLaff and self.accepting
def checkBoard(self, av):
if av.hp < self.minLaff:
return REJECT_MINLAFF
return 0
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
av = self.air.doId2do.get(avId)
if av:
boardResponse = self.checkBoard(av)
newArgs = (avId,) + args + (boardResponse,)
if not ToontownAccessAI.canAccess(avId, self.zoneId, 'DistributedElevatorAI.requestBoard'):
self.notify.warning('Toon %s does not have access to the eleavtor.' % avId)
self.rejectingBoardersHandler(*newArgs)
return
if self.boardingParty and self.boardingParty.hasActiveGroup(avId) and self.boardingParty.getGroupLeader(avId) != avId:
self.notify.warning('Rejecting %s from boarding the elevator because he is already part of a Boarding Group.' % avId)
self.rejectingBoardersHandler(*newArgs)
return
if boardResponse == 0:
self.acceptingBoardersHandler(*newArgs)
else:
self.rejectingBoardersHandler(*newArgs)
else:
self.notify.warning('avid: %s does not exist, but tried to board an elevator' % avId)
return
def partyAvatarBoard(self, avatar, wantBoardingShow=0):
av = avatar
avId = avatar.doId
if self.findAvatar(avId) != None:
self.notify.warning('Ignoring multiple requests from %s to board.' % avId)
return
if av:
boardResponse = self.checkBoard(av)
newArgs = (avId,) + (boardResponse,) + (wantBoardingShow,)
if boardResponse == 0:
self.acceptingBoardersHandler(*newArgs)
else:
self.rejectingBoardersHandler(*newArgs)
else:
self.notify.warning('avid: %s does not exist, but tried to board an elevator' % avId)
return
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 an elevator' % avId)
def start(self):
self.open()
def enterOff(self):
self.accepting = 0
self.timeOfBoarding = None
self.timeOfGroupBoarding = None
if hasattr(self, 'doId'):
for seatIndex in range(len(self.seats)):
taskMgr.remove(self.uniqueName('clearEmpty-' + str(seatIndex)))
return
def exitOff(self):
self.accepting = 0
def open(self):
self.fsm.request('opening')
def enterOpening(self):
self.d_setState('opening')
self.accepting = 0
for seat in self.seats:
seat = None
return
def exitOpening(self):
self.accepting = 0
taskMgr.remove(self.uniqueName('opening-timer'))
def enterWaitCountdown(self):
self.d_setState('waitCountdown')
self.accepting = 1
def exitWaitCountdown(self):
print('exit wait countdown')
self.accepting = 0
taskMgr.remove(self.uniqueName('countdown-timer'))
self.newTrip()
def enterAllAboard(self):
self.accepting = 0
def exitAllAboard(self):
self.accepting = 0
taskMgr.remove(self.uniqueName('waitForAllAboard'))
def enterClosing(self):
self.d_setState('closing')
self.accepting = 0
def exitClosing(self):
self.accepting = 0
taskMgr.remove(self.uniqueName('closing-timer'))
def enterClosed(self):
self.d_setState('closed')
def exitClosed(self):
pass
def enterWaitEmpty(self):
self.d_setState('waitEmpty')
self.accepting = 1
def exitWaitEmpty(self):
self.accepting = 0
def setElevatorTripId(self, id):
self.elevatorTripId = id
def getElevatorTripId(self):
return self.elevatorTripId
def newTrip(self):
if self.antiShuffle:
self.elevatorTripId = simbase.air.elevatorTripId
if simbase.air.elevatorTripId > 2100000000:
simbase.air.elevatorTripId = 1
simbase.air.elevatorTripId += 1
self.sendUpdate('setElevatorTripId', [self.elevatorTripId])
def setAntiShuffle(self, antiShuffle):
self.antiShuffle = antiShuffle
def getAntiShuffle(self):
return self.antiShuffle
def setMinLaff(self, minLaff):
self.minLaff = minLaff
def getMinLaff(self):
return self.minLaff