343 lines
11 KiB
Python
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
|