toontown-just-works/toontown/minigame/DistributedDivingGameAI.py
2024-07-07 18:08:39 -05:00

464 lines
14 KiB
Python

from DistributedMinigameAI import *
from direct.distributed.ClockDelta import *
from direct.interval.IntervalGlobal import *
from direct.fsm import ClassicFSM
from direct.fsm import State
from direct.actor import Actor
import DivingGameGlobals
import random
import random
import types
class DistributedDivingGameAI(DistributedMinigameAI):
fishProportions = []
for i in xrange(6):
fishProportions.append([])
n = 100
fishProportions[0]
fishProportions[0].append(([0, 0.8],
[0.8, 0.9],
[0.9, 1],
[n, n],
[n, n],
[n, n]))
fishProportions[0].append(([0, 0.8],
[0.8, 1],
[n, n],
[n, n],
[n, n],
[n, n]))
fishProportions[0].append(([0, 0.7],
[0.7, 1],
[n, n],
[n, n],
[n, n],
[n, n]))
fishProportions[0].append(([0, 0.7],
[0.7, 0.9],
[0.9, 1],
[n, n],
[n, n],
[n, n]))
fishProportions[0].append(([0, 0.5],
[0.5, 1],
[n, n],
[n, n],
[n, n],
[n, n]))
fishProportions[0].append(([n, 0.5],
[0.5, 1],
[n, n],
[n, n],
[n, n],
[n, n]))
fishProportions[1]
fishProportions[1].append(([0, 0.8],
[0.8, 0.9],
[0.9, 1],
[n, n],
[n, n],
[n, n]))
fishProportions[1].append(([0, 0.8],
[0.8, 1],
[n, n],
[n, n],
[n, n],
[n, n]))
fishProportions[1].append(([0, 0.7],
[0.7, 1],
[n, n],
[n, n],
[n, n],
[n, n]))
fishProportions[1].append(([0, 0.7],
[0.7, 0.9],
[n, n],
[n, n],
[n, n],
[0.9, 1]))
fishProportions[1].append(([0, 0.4],
[0.4, 0.8],
[n, n],
[n, n],
[n, n],
[0.8, 1]))
fishProportions[1].append(([n, 0.3],
[0.3, 0.6],
[n, n],
[n, n],
[n, n],
[0.6, 1]))
fishProportions[2]
fishProportions[2].append(([0, 0.7],
[0.7, 0.9],
[0.9, 1],
[n, n],
[n, n],
[n, n]))
fishProportions[2].append(([0, 0.6],
[0.6, 1],
[n, n],
[n, n],
[n, n],
[n, n]))
fishProportions[2].append(([0, 0.6],
[0.6, 0.8],
[n, n],
[0.8, 1],
[n, n],
[n, n]))
fishProportions[2].append(([0, 0.5],
[0.5, 0.7],
[n, n],
[0.7, 0.9],
[n, n],
[0.9, 1]))
fishProportions[2].append(([0, 0.2],
[0.2, 0.4],
[n, n],
[0.4, 0.75],
[n, n],
[0.75, 1]))
fishProportions[2].append(([n, 0.2],
[0.2, 0.6],
[n, n],
[0.6, 0.8],
[n, n],
[0.8, 1]))
fishProportions[3]
fishProportions[3].append(([0, 0.7],
[0.7, 0.9],
[0.9, 1],
[n, n],
[n, n],
[n, n]))
fishProportions[3].append(([0, 0.6],
[0.6, 1],
[n, n],
[n, n],
[n, n],
[n, n]))
fishProportions[3].append(([0, 0.6],
[0.6, 0.8],
[n, n],
[0.95, 1],
[n, n],
[n, n]))
fishProportions[3].append(([0, 0.5],
[0.5, 0.7],
[n, n],
[0.7, 0.85],
[0.9, 0.95],
[0.95, 1]))
fishProportions[3].append(([0, 0.2],
[0.2, 0.4],
[n, n],
[0.4, 0.75],
[0.75, 0.85],
[0.85, 1]))
fishProportions[3].append(([n, 0.2],
[0.2, 0.6],
[n, n],
[0.6, 0.8],
[n, n],
[0.8, 1]))
fishProportions[4]
fishProportions[4].append(([0, 0.7],
[0.7, 0.9],
[0.9, 1],
[n, n],
[n, n],
[n, n]))
fishProportions[4].append(([0, 0.45],
[0.45, 0.9],
[n, n],
[0.9, 1],
[n, n],
[n, n]))
fishProportions[4].append(([0, 0.2],
[0.2, 0.5],
[n, n],
[0.5, 0.95],
[0.95, 1],
[n, n]))
fishProportions[4].append(([0, 0.1],
[0.1, 0.3],
[n, n],
[0.3, 0.75],
[0.75, 0.8],
[0.8, 1]))
fishProportions[4].append(([n, n],
[0, 0.15],
[n, n],
[0.15, 0.4],
[n, n],
[0.4, 1]))
fishProportions[4].append(([n, n],
[n, n],
[n, n],
[0, 0.4],
[n, n],
[0.6, 1]))
fishProportions[5]
fishProportions[5].append(([0, 0.7],
[0.7, 0.9],
[0.9, 1],
[n, n],
[n, n],
[n, n]))
fishProportions[5].append(([0, 0.45],
[0.45, 0.9],
[n, n],
[0.9, 1],
[n, n],
[n, n]))
fishProportions[5].append(([0, 0.2],
[0.2, 0.5],
[n, n],
[0.5, 0.95],
[0.95, 1],
[n, n]))
fishProportions[5].append(([0, 0.1],
[0.1, 0.3],
[n, n],
[0.3, 0.75],
[0.75, 0.8],
[0.8, 1]))
fishProportions[5].append(([n, n],
[0, 0.15],
[n, n],
[0.15, 0.4],
[n, n],
[0.4, 1]))
fishProportions[5].append(([n, n],
[n, n],
[n, n],
[0, 0.4],
[n, n],
[0.6, 1]))
difficultyPatternsAI = {ToontownGlobals.ToontownCentral: [3.5, fishProportions[0], 1.5],
ToontownGlobals.DonaldsDock: [3.0, fishProportions[1], 1.8],
ToontownGlobals.DaisyGardens: [2.5, fishProportions[2], 2.1],
ToontownGlobals.MinniesMelodyland: [2.0, fishProportions[3], 2.4],
ToontownGlobals.TheBrrrgh: [2.0, fishProportions[4], 2.7],
ToontownGlobals.DonaldsDreamland: [1.5, fishProportions[5], 3.0]}
def __init__(self, air, minigameId):
try:
self.DistributedDivingGameAI_initialized
except:
self.DistributedDivingGameAI_initialized = 1
DistributedMinigameAI.__init__(self, air, minigameId)
self.gameFSM = ClassicFSM.ClassicFSM('DistributedDivingGameAI', [State.State('inactive', self.enterInactive, self.exitInactive, ['swimming']), State.State('swimming', self.enterSwimming, self.exitSwimming, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, ['inactive'])], 'inactive', 'inactive')
self.addChildGameFSM(self.gameFSM)
self.__timeBase = globalClockDelta.localToNetworkTime(globalClock.getRealTime())
def delete(self):
self.notify.debug('delete')
del self.gameFSM
DistributedMinigameAI.delete(self)
def setGameReady(self):
self.notify.debug('setGameReady')
self.sendUpdate('setTrolleyZone', [self.trolleyZone])
for avId in self.scoreDict.keys():
self.scoreDict[avId] = 0
self.treasureHolders = [0] * self.numPlayers
self.SPAWNTIME = self.difficultyPatternsAI[self.getSafezoneId()][0]
self.proportion = self.difficultyPatternsAI[self.getSafezoneId()][1]
self.REWARDMOD = self.difficultyPatternsAI[self.getSafezoneId()][2]
DistributedMinigameAI.setGameReady(self)
self.spawnings = []
for i in xrange(DivingGameGlobals.NUM_SPAWNERS):
self.spawnings.append(Sequence(Func(self.spawnFish, i), Wait(self.SPAWNTIME + random.random()), Func(self.spawnFish, i), Wait(self.SPAWNTIME - 0.5 + random.random())))
self.spawnings[i].loop()
def setGameStart(self, timestamp):
self.notify.debug('setGameStart')
DistributedMinigameAI.setGameStart(self, timestamp)
self.gameFSM.request('swimming')
self.scoreTracking = {}
for avId in self.scoreDict.keys():
self.scoreTracking[avId] = [0,
0,
0,
0,
0]
def getCrabMoving(self, crabId, crabX, dir):
timestamp = globalClockDelta.getFrameNetworkTime()
rand1 = int(random.random() * 10)
rand2 = int(random.random() * 10)
self.sendUpdate('setCrabMoving', [crabId,
timestamp,
rand1,
rand2,
crabX,
dir])
def treasureRecovered(self):
if not hasattr(self, 'scoreTracking'):
return
avId = self.air.getAvatarIdFromSender()
if avId not in self.avIdList:
self.air.writeServerEvent('suspicious', avId, 'DivingGameAI.treasureRecovered: invalid avId')
return
if avId not in self.treasureHolders:
self.air.writeServerEvent('suspicious', avId, 'DivingGameAI.treasureRecovered: tried to recover without holding treasure')
return
self.treasureHolders[self.treasureHolders.index(avId)] = 0
timestamp = globalClockDelta.getFrameNetworkTime()
newSpot = int(random.random() * 30)
self.scoreTracking[avId][4] += 1
for someAvId in self.scoreDict.keys():
if someAvId == avId:
self.scoreDict[avId] += 10 * (self.REWARDMOD * 0.25)
self.scoreDict[someAvId] += 10 * (self.REWARDMOD * 0.75 / float(len(self.scoreDict.keys())))
self.sendUpdate('incrementScore', [avId, newSpot, timestamp])
def hasScoreMult(self):
return 0
def setGameAbort(self):
self.notify.debug('setGameAbort')
taskMgr.remove(self.taskName('gameTimer'))
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)
trackingString = 'MiniGame Stats : Diving Game'
trackingString += '\nDistrict:%s' % self.getSafezoneId()
for avId in self.scoreTracking.keys():
trackingString = trackingString + '\navId:%s fishHits:%s crabHits:%s treasureCatches:%s treasureDrops:%s treasureRecoveries:%s Score: %s' % (avId,
self.scoreTracking[avId][0],
self.scoreTracking[avId][1],
self.scoreTracking[avId][2],
self.scoreTracking[avId][3],
self.scoreTracking[avId][4],
self.scoreDict[avId])
self.air.writeServerEvent('MiniGame Stats', None, trackingString)
return
def enterInactive(self):
self.notify.debug('enterInactive')
def exitInactive(self):
pass
def getTimeBase(self):
return self.__timeBase
def enterSwimming(self):
self.notify.debug('enterSwimming')
duration = 65.0
taskMgr.doMethodLater(duration, self.timerExpired, self.taskName('gameTimer'))
def timerExpired(self, task):
self.notify.debug('timer expired')
for avId in self.scoreDict.keys():
if self.scoreDict[avId] < 5:
self.scoreDict[avId] = 5
self.gameOver()
return Task.done
def exitSwimming(self):
for i in xrange(DivingGameGlobals.NUM_SPAWNERS):
self.spawnings[i].pause()
def enterCleanup(self):
self.notify.debug('enterCleanup')
for i in xrange(DivingGameGlobals.NUM_SPAWNERS):
self.spawnings[i].finish()
del self.spawnings
self.gameFSM.request('inactive')
def exitCleanup(self):
pass
def pickupTreasure(self, chestId):
if not hasattr(self, 'scoreTracking'):
return
timestamp = globalClockDelta.getFrameNetworkTime()
avId = self.air.getAvatarIdFromSender()
if avId not in self.avIdList:
self.air.writeServerEvent('suspicious', avId, 'DivingGameAI.pickupTreasure: invalid avId')
return
if avId in self.treasureHolders:
self.air.writeServerEvent('suspicious', avId, 'DivingGameAI.pickupTreasure: already holding treasure')
return
if not (0 <= chestId < len(self.treasureHolders)):
self.air.writeServerEvent('suspicious', avId, 'DivingGameAI.pickupTreasure: invalid chest requested (#%d)' % chestId)
return
if self.treasureHolders[chestId]:
# This chest is already held by someone else. Because this can happen
# during normal play (race conditions if two Toons swim into the treasure
# simultaneously) we do not log a suspicious event and silently ignore it.
return
self.scoreTracking[avId][2] += 1
self.treasureHolders[chestId] = avId
self.sendUpdate('setTreasureGrabbed', [avId, chestId])
def spawnFish(self, spawnerId):
timestamp = globalClockDelta.getFrameNetworkTime()
props = self.proportion[spawnerId]
num = random.random()
for i in xrange(len(props)):
prop = props[i]
low = prop[0]
high = prop[1]
if num > low and num <= high:
offset = int(10 * random.random())
self.sendUpdate('fishSpawn', [timestamp,
i,
spawnerId,
offset])
return
def handleCrabCollision(self, avId, status):
if avId not in self.avIdList:
self.air.writeServerEvent('suspicious', avId, 'DivingGameAI.handleCrabCollision: invalid avId')
return
timestamp = globalClockDelta.getFrameNetworkTime()
self.sendUpdate('setTreasureDropped', [avId, timestamp])
self.scoreTracking[avId][1] += 1
if status == 'normal' or status == 'treasure':
timestamp = globalClockDelta.getFrameNetworkTime()
self.sendUpdate('performCrabCollision', [avId, timestamp])
if status == 'treasure':
if avId in self.treasureHolders:
self.treasureHolders[self.treasureHolders.index(avId)] = 0
self.scoreTracking[avId][3] += 1
else:
self.air.writeServerEvent('suspicious', avId, 'DivingGameAI.handleCrabCollision: reported "treasure drop" without holding treasure')
def handleFishCollision(self, avId, spawnId, spawnerId, status):
if avId not in self.avIdList:
self.air.writeServerEvent('suspicious', avId, 'DivingGameAI.handleFishCollision: invalid avId')
return
timestamp = globalClockDelta.getFrameNetworkTime()
self.sendUpdate('setTreasureDropped', [avId, timestamp])
timestamp = globalClockDelta.getFrameNetworkTime()
self.scoreTracking[avId][0] += 1
if status == 'treasure':
if avId in self.treasureHolders:
self.treasureHolders[self.treasureHolders.index(avId)] = 0
self.scoreTracking[avId][3] += 1
else:
self.air.writeServerEvent('suspicious', avId, 'DivingGameAI.handleFishCollision: reported "treasure drop" without holding treasure')
self.sendUpdate('performFishCollision', [avId,
spawnId,
spawnerId,
timestamp])