toontown-just-works/toontown/safezone/DistributedPicnicTableAI.py
2024-07-07 18:08:39 -05:00

343 lines
11 KiB
Python

from direct.distributed.DistributedNodeAI import DistributedNodeAI
from direct.distributed.ClockDelta import *
from direct.fsm import ClassicFSM, State
from direct.fsm import State
from direct.fsm import StateData
from toontown.safezone import DistributedChineseCheckersAI
from toontown.safezone import DistributedCheckersAI
from toontown.safezone import DistributedFindFourAI
from toontown.safezone import GameGlobals
class DistributedPicnicTableAI(DistributedNodeAI):
def __init__(self, air, zone, name, x, y, z, h, p, r):
DistributedNodeAI.__init__(self, air)
self.name = name
self.zoneId = zone
self.air = air
self.seats = [
None,
None,
None,
None,
None,
None]
self.setPos(x, y, z)
self.setHpr(h, p, r)
self.playersSitting = 0
self.playerIdList = []
self.checkersZoneId = None
self.observers = []
self.allowPickers = []
self.hasPicked = False
self.game = None
self.gameDoId = None
self.isAccepting = True
def announceGenerate(self):
pass
def delete(self):
DistributedNodeAI.delete(self)
self.game = None
self.gameDoId = None
def setGameDoId(self, doId):
self.gameDoId = doId
self.game = self.air.doId2do.get(doId)
def requestTableState(self):
avId = self.air.getAvatarIdFromSender()
self.getTableState()
def getTableState(self):
tableStateList = []
for x in self.seats:
if x == None:
tableStateList.append(0)
continue
tableStateList.append(x)
if self.game and self.game.fsm.getCurrentState().getName() == 'playing':
self.sendUpdate('setTableState', [
tableStateList,
1])
else:
self.sendUpdate('setTableState', [
tableStateList,
0])
def sendIsPlaying(self):
if self.game.fsm.getCurrentState().getName() == 'playing':
self.sendUpdate('setIsPlaying', [
1])
else:
self.sendUpdate('setIsPlaying', [
0])
def announceWinner(self, gameName, avId):
self.sendUpdate('announceWinner', [
gameName,
avId])
self.gameDoId = None
self.game = None
def requestJoin(self, si, x, y, z, h, p, r):
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:
if av.hp > 0 and self.isAccepting and self.seats[si] == None:
self.notify.debug('accepting boarder %d' % avId)
self.acceptBoarder(avId, si, x, y, z, h, p, r)
else:
self.notify.debug('rejecting boarder %d' % avId)
self.sendUpdateToAvatarId(avId, 'rejectJoin', [])
else:
self.notify.warning('avid: %s does not exist, but tried to board a picnicTable' % avId)
def acceptBoarder(self, avId, seatIndex, x, y, z, h, p, r):
self.notify.debug('acceptBoarder %d' % avId)
if self.findAvatar(avId) != None:
return None
isEmpty = True
for xx in self.seats:
if xx != None:
isEmpty = False
break
continue
if isEmpty == True or self.hasPicked == False:
self.sendUpdateToAvatarId(avId, 'allowPick', [])
self.allowPickers.append(avId)
if self.hasPicked == True:
self.sendUpdateToAvatarId(avId, 'setZone', [
self.game.zoneId])
self.seats[seatIndex] = avId
self.acceptOnce(self.air.getAvatarExitEvent(avId), self._DistributedPicnicTableAI__handleUnexpectedExit, extraArgs = [
avId])
self.timeOfBoarding = globalClock.getRealTime()
if self.game:
self.game.informGameOfPlayer()
self.sendUpdate('fillSlot', [
avId,
seatIndex,
x,
y,
z,
h,
p,
r,
globalClockDelta.localToNetworkTime(self.timeOfBoarding),
self.doId])
self.getTableState()
def requestPickedGame(self, gameNum):
avId = self.air.getAvatarIdFromSender()
if self.hasPicked == False and avId in self.allowPickers:
self.hasPicked = True
numPickers = len(self.allowPickers)
self.allowPickers = []
self.pickGame(gameNum)
if self.game:
for x in xrange(numPickers):
self.game.informGameOfPlayer()
def pickGame(self, gameNum):
if self.game:
return
x = 0
for x in self.seats:
if x != None:
x += 1
continue
if gameNum == GameGlobals.ChineseCheckersGameIndex:
if simbase.config.GetBool('want-chinese', 1):
self.game = DistributedChineseCheckersAI.DistributedChineseCheckersAI(self.air, self.doId, 'chinese', self.getX(), self.getY(), self.getZ() + 2.8300000000000001, self.getH(), self.getP(), self.getR())
self.sendUpdate('setZone', [
self.game.zoneId])
elif gameNum == GameGlobals.CheckersGameIndex:
if x <= 2:
if simbase.config.GetBool('want-checkers', 1):
self.game = DistributedCheckersAI.DistributedCheckersAI(self.air, self.doId, 'checkers', self.getX(), self.getY(), self.getZ() + 2.8300000000000001, self.getH(), self.getP(), self.getR())
self.sendUpdate('setZone', [
self.game.zoneId])
elif gameNum == GameGlobals.FindFourGameIndex:
if x <= 2:
if simbase.config.GetBool('want-findfour', 1):
self.game = DistributedFindFourAI.DistributedFindFourAI(self.air, self.doId, 'findFour', self.getX(), self.getY(), self.getZ() + 2.8300000000000001, self.getH(), self.getP(), self.getR())
self.sendUpdate('setZone', [
self.game.zoneId])
def requestZone(self):
if not self.game:
return
avId = self.air.getAvatarIdFromSender()
self.sendUpdateToAvatarId(avId, 'setZone', [
self.game.zoneId])
def requestGameZone(self):
if self.hasPicked == True:
avId = self.air.getAvatarIdFromSender()
if self.game:
self.game.playersObserving.append(avId)
self.observers.append(avId)
self.acceptOnce(self.air.getAvatarExitEvent(avId), self.handleObserverExit, extraArgs = [
avId])
if self.game:
if self.game.fsm.getCurrentState().getName() == 'playing':
self.sendUpdateToAvatarId(avId, 'setGameZone', [
self.checkersZoneId,
1])
else:
self.sendUpdateToAvatarId(avId, 'setGameZone', [
self.checkersZoneId,
0])
def leaveObserve(self):
avId = self.air.getAvatarIdFromSender()
if self.game:
if avId in self.game.playersObserving:
self.game.playersObserving.remove(avId)
def handleObserverExit(self, avId):
if self.game and avId in self.game.playersObserving:
if self.game:
self.game.playersObserving.remove(avId)
self.ignore(self.air.getAvatarExitEvent(avId))
def requestExit(self):
self.notify.debug('requestExit')
avId = self.air.getAvatarIdFromSender()
av = self.air.doId2do.get(avId)
if av:
if self.countFullSeats() > 0:
self.acceptExiter(avId)
else:
self.notify.debug('Player tried to exit after AI already kicked everyone out')
else:
self.notify.warning('avId: %s does not exist, but tried to exit picnicTable' % avId)
def acceptExiter(self, avId):
seatIndex = self.findAvatar(avId)
if seatIndex == None:
if avId in self.observers:
self.sendUpdateToAvatarId(avId, 'emptySlot', [
avId,
255,
globalClockDelta.getRealNetworkTime()])
else:
self.seats[seatIndex] = None
self.ignore(self.air.getAvatarExitEvent(avId))
self.sendUpdate('emptySlot', [
avId,
seatIndex,
globalClockDelta.getRealNetworkTime()])
self.getTableState()
numActive = 0
for x in self.seats:
if x != None:
numActive = numActive + 1
continue
if self.game:
self.game.informGameOfPlayerLeave()
self.game.handlePlayerExit(avId)
if numActive == 0:
self.isAccepting = True
if self.game:
self.game.handleEmptyGame()
self.game.requestDelete()
self.game = None
self.hasPicked = False
def _DistributedPicnicTableAI__handleUnexpectedExit(self, avId):
self.notify.warning('Avatar: ' + str(avId) + ' has exited unexpectedly')
seatIndex = self.findAvatar(avId)
if seatIndex == None:
pass
self.seats[seatIndex] = None
self.ignore(self.air.getAvatarExitEvent(avId))
if self.game:
self.game.informGameOfPlayerLeave()
self.game.handlePlayerExit(avId)
self.hasPicked = False
self.getTableState()
numActive = 0
for x in self.seats:
if x != None:
numActive = numActive + 1
continue
if numActive == 0 and self.game:
simbase.air.deallocateZone(self.game.zoneId)
self.game.requestDelete()
self.game = None
self.gameDoId = None
def informGameOfPlayerExit(self, avId):
self.game.handlePlayerExit(avId)
def handleGameOver(self):
for x in self.observers:
self.acceptExiter(x)
self.observers.remove(x)
if self.game:
self.game.playersObserving = []
for x in self.seats:
if x != None:
self.acceptExiter(x)
continue
self.game = None
self.gameDoId = None
self.hasPicked = False
def findAvatar(self, avId):
for i in xrange(len(self.seats)):
if self.seats[i] == avId:
return i
continue
def countFullSeats(self):
avCounter = 0
for i in self.seats:
if i:
avCounter += 1
continue
return avCounter
def findAvailableSeat(self):
for i in xrange(len(self.seats)):
if self.seats[i] == None:
return i
continue
def setCheckersZoneId(self, zoneId):
self.checkersZoneId = zoneId
def setTableIndex(self, index):
self._tableIndex = index
def getTableIndex(self):
return self._tableIndex