from DistributedMinigameAI import * from direct.distributed.ClockDelta import * from direct.fsm import ClassicFSM, State from direct.fsm import State import TargetGameGlobals import random import types def checkPlace(placeX, placeY, fillSize, placeList): goodPlacement = 1 for place in placeList: distance = math.sqrt((place[0] - placeX) * (place[0] - placeX) + (place[1] - placeY) * (place[1] - placeY)) distance = distance - (fillSize + place[2]) if distance <= 0.0: goodPlacement = 0 break return goodPlacement class DistributedTargetGameAI(DistributedMinigameAI): def __init__(self, air, minigameId): try: self.DistributedTargetGameAI_initialized except: self.DistributedTargetGameAI_initialized = 1 DistributedMinigameAI.__init__(self, air, minigameId) self.gameFSM = ClassicFSM.ClassicFSM('DistributedTargetGameAI', [State.State('inactive', self.enterInactive, self.exitInactive, ['fly']), State.State('fly', self.enterFly, self.exitFly, ['cleanup', 'resetRound']), State.State('resetRound', self.enterResetRound, self.exitResetRound, ['cleanup', 'fly']), State.State('cleanup', self.enterCleanup, self.exitCleanup, ['inactive'])], 'inactive', 'inactive') self.addChildGameFSM(self.gameFSM) self.__timeBase = globalClockDelta.localToNetworkTime(globalClock.getRealTime()) self.round = 2 self.barrierScore = None self.scoreTrack = [] return def delete(self): self.notify.debug('delete') del self.gameFSM del self.scoreTrack if hasattr(self, 'barrierScore'): if self.barrierScore: self.barrierScore.cleanup() del self.barrierScore DistributedMinigameAI.delete(self) def setGameReady(self): self.notify.debug('setGameReady') self.sendUpdate('setTrolleyZone', [self.trolleyZone]) DistributedMinigameAI.setGameReady(self) import time random.seed(time.time()) seed = int(random.random() * 4000.0) self.sendUpdate('setTargetSeed', [seed]) random.seed(seed) self.setupTargets() def setupTargets(self): fieldWidth = TargetGameGlobals.ENVIRON_WIDTH * 3 fieldLength = TargetGameGlobals.ENVIRON_LENGTH * 3.7 self.pattern = TargetGameGlobals.difficultyPatterns[self.getSafezoneId()] self.targetList = self.pattern[0] self.targetValue = self.pattern[1] self.targetSize = self.pattern[2] self.targetColors = self.pattern[3] self.targetSubParts = self.pattern[4] highestValue = 0 for value in self.targetValue: if value > highestValue: highestValue = value self.placeValue = highestValue * 0.5 self.targetsPlaced = [] placeList = [] for typeIndex in range(len(self.targetList)): for targetIndex in range(self.targetList[typeIndex]): goodPlacement = 0 while not goodPlacement: placeX = random.random() * (fieldWidth * 0.6) - fieldWidth * 0.6 * 0.5 placeY = (random.random() * 0.6 + (0.0 + 0.4 * (self.placeValue * 1.0 / (highestValue * 1.0)))) * fieldLength fillSize = self.targetSize[typeIndex] goodPlacement = checkPlace(placeX, placeY, fillSize, placeList) placeList.append((placeX, placeY, fillSize)) subIndex = self.targetSubParts[typeIndex] while subIndex: combinedIndex = typeIndex + subIndex - 1 self.targetsPlaced.append((placeX, placeY, combinedIndex)) subIndex -= 1 def setGameStart(self, timestamp): self.notify.debug('setGameStart') for avId in self.scoreDict.keys(): self.scoreDict[avId] = 0 DistributedMinigameAI.setGameStart(self, timestamp) self.gameFSM.request('fly') def setScore(self, scoreX, scoreY, other = None): avId = self.air.getAvatarIdFromSender() if avId not in self.avIdList: self.air.writeServerEvent('suspicious', avId, 'RingGameAI.setScore: invalid avId') return topValue = 0 hitTarget = None for target in self.targetsPlaced: radius = self.targetSize[target[2]] value = self.targetValue[target[2]] posX = target[0] posY = target[1] dx = posX - scoreX dy = posY - scoreY distance = math.sqrt(dx * dx + dy * dy) if distance < radius and topValue < value: topValue = value hitTarget = target hitX = posX hitY = posY if self.scoreDict[avId] < topValue: self.scoreDict[avId] = topValue self.sendUpdate('setSingleScore', [topValue, avId]) return def setGameAbort(self): self.notify.debug('setGameAbort') if self.gameFSM.getCurrentState(): self.gameFSM.request('cleanup') DistributedMinigameAI.setGameAbort(self) def gameOver(self): self.notify.debug('gameOver') self.gameFSM.request('cleanup') DistributedMinigameAI.gameOver(self) def enterInactive(self): self.notify.debug('enterInactive') def exitInactive(self): pass def getTimeBase(self): return self.__timeBase def enterFly(self): self.notify.debug('enterFly') self.barrierScore = ToonBarrier('waitClientsScore', self.uniqueName('waitClientsScore'), self.avIdList, 120, self.allAvatarsScore, self.handleTimeout) def exitFly(self): pass def handleTimeout(self, other = None): pass def allAvatarsScore(self, other = None): if self.round == 0: self.gameOver() else: self.round -= 1 self.gameFSM.request('resetRound') def getScoreList(self): scoreList = [0, 0, 0, 0] avList = [0, 0, 0, 0] scoreIndex = 0 for avId in self.scoreDict.keys(): scoreList[scoreIndex] = self.scoreDict[avId] avList[scoreIndex] = avId scoreIndex += 1 return scoreList def enterResetRound(self): scoreList = self.getScoreList() self.scoreTrack.append(scoreList) self.sendUpdate('setRoundDone', []) self.barrierScore.cleanup() del self.barrierScore taskMgr.doMethodLater(0.1, self.gotoFly, self.taskName('roundReset')) def exitResetRound(self): pass def gotoFly(self, extra = None): if hasattr(self, 'gameFSM'): self.gameFSM.request('fly') def enterCleanup(self): self.notify.debug('enterCleanup') self.gameFSM.request('inactive') def exitCleanup(self): pass def setPlayerDone(self, other = None): if not hasattr(self, 'barrierScore') or self.barrierScore == None: return avId = self.air.getAvatarIdFromSender() self.barrierScore.clear(avId) for avId in self.stateDict.keys(): if self.stateDict[avId] == EXITED: self.barrierScore.clear(avId) return def gameOver(self): self.notify.debug('gameOver') for entry in self.scoreDict: if self.scoreDict[entry] == 0: self.scoreDict[entry] = 1 self.scoreTrack.append(self.getScoreList()) statMessage = 'MiniGame Stats : Target Game' + '\nScores' + '%s' % self.scoreTrack + '\nAvIds' + '%s' % self.scoreDict.keys() + '\nSafeZone' + '%s' % self.getSafezoneId() self.air.writeServerEvent('MiniGame Stats', None, statMessage) self.sendUpdate('setGameDone', []) self.gameFSM.request('cleanup') DistributedMinigameAI.gameOver(self) return def hasScoreMult(self): return 0