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

1080 lines
16 KiB
Python

from direct.showbase.RandomNumGen import RandomNumGen
import CatchGameGlobals
import DropScheduler
from toontown.parties.PartyGlobals import CatchActivityDuration as PartyCatchDuration
class DropPlacer:
def __init__(self, game, numPlayers, dropTypes, startTime = None):
self.game = game
self.numPlayers = numPlayers
self.dropTypes = dropTypes
self.dtIndex = 0
self._createScheduler(startTime)
self._createRng()
def _createScheduler(self, startTime):
self.scheduler = DropScheduler.DropScheduler(CatchGameGlobals.GameDuration, self.game.FirstDropDelay, self.game.DropPeriod, self.game.MaxDropDuration, self.game.FasterDropDelay, self.game.FasterDropPeriodMult, startTime=startTime)
def _createRng(self):
self.rng = self.game.randomNumGen
def skipPercent(self, percent):
numSkips = self.scheduler.skipPercent(percent)
self.dtIndex += numSkips
return numSkips
def doneDropping(self, continuous = None):
return self.scheduler.doneDropping(continuous)
def getDuration(self):
return self.scheduler.getDuration()
def getT(self):
return self.scheduler.getT()
def stepT(self):
self.scheduler.stepT()
def getNextDropTypeName(self):
if self.dtIndex >= len(self.dropTypes):
self.game.notify.debug('warning: defaulting to anvil')
typeName = 'anvil'
else:
typeName = self.dropTypes[self.dtIndex]
self.dtIndex += 1
return typeName
def getRandomColRow(self):
col = self.rng.randrange(0, self.game.DropColumns)
row = self.rng.randrange(0, self.game.DropRows)
return [col, row]
def getNextDrop(self):
raise RuntimeError, 'DropPlacer.getNextDrop should never be called'
class RandomDropPlacer(DropPlacer):
def __init__(self, game, numPlayers, dropTypes, startTime = None):
DropPlacer.__init__(self, game, numPlayers, dropTypes, startTime=startTime)
def getNextDrop(self):
col, row = self.getRandomColRow()
drop = [self.getT(), self.getNextDropTypeName(), [col, row]]
self.stepT()
return drop
class RegionDropPlacer(DropPlacer):
DropRegionTables = [[[1,
1,
2,
3,
3],
[1,
1,
2,
3,
3],
[0,
1,
2,
3,
4],
[0,
1,
2,
3,
4],
[0,
1,
2,
3,
4]],
[[1,
2,
2,
3,
3,
4],
[1,
1,
2,
3,
4,
4],
[1,
1,
2,
3,
4,
4],
[0,
1,
2,
3,
4,
5],
[0,
1,
2,
3,
4,
5],
[0,
1,
2,
3,
4,
5]],
[[1,
1,
2,
2,
2,
3,
3],
[1,
1,
2,
2,
2,
3,
3],
[0,
1,
2,
2,
2,
3,
4],
[0,
1,
2,
2,
2,
3,
4],
[0,
1,
2,
2,
2,
3,
4],
[0,
1,
2,
2,
2,
3,
4],
[0,
1,
2,
2,
2,
3,
4]],
[[1,
2,
2,
5,
6,
7,
7,
3],
[1,
1,
2,
5,
6,
7,
3,
3],
[0,
1,
2,
5,
6,
7,
3,
4],
[0,
1,
2,
5,
6,
7,
3,
4],
[0,
1,
2,
5,
6,
7,
3,
4],
[0,
1,
2,
5,
6,
7,
3,
4],
[0,
1,
2,
5,
6,
7,
3,
4],
[0,
0,
1,
5,
6,
3,
4,
4]],
[[1,
2,
2,
5,
8,
6,
7,
7,
3],
[1,
1,
2,
5,
8,
6,
7,
3,
3],
[0,
1,
2,
5,
8,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
6,
7,
3,
4],
[0,
0,
1,
5,
8,
6,
3,
4,
4]],
[[1,
2,
2,
5,
8,
8,
6,
7,
7,
3],
[1,
1,
2,
5,
8,
8,
6,
7,
3,
3],
[0,
1,
2,
5,
8,
8,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
8,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
8,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
8,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
8,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
8,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
8,
6,
7,
3,
4],
[0,
0,
1,
5,
8,
8,
6,
3,
4,
4]],
[[1,
2,
2,
5,
8,
10,
9,
6,
7,
7,
3],
[1,
1,
2,
5,
8,
10,
9,
6,
7,
3,
3],
[0,
1,
2,
5,
8,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
9,
6,
7,
3,
4],
[0,
0,
1,
5,
8,
10,
9,
6,
3,
4,
4]],
[[1,
2,
2,
5,
8,
10,
10,
9,
6,
7,
7,
3],
[1,
1,
2,
5,
8,
10,
10,
9,
6,
7,
3,
3],
[0,
1,
2,
5,
8,
10,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
10,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
10,
9,
6,
7,
3,
4],
[0,
0,
1,
5,
8,
10,
10,
9,
6,
3,
4,
4]],
[[1,
2,
2,
5,
8,
10,
11,
12,
9,
6,
7,
7,
3],
[1,
1,
2,
5,
8,
10,
11,
12,
9,
6,
7,
3,
3],
[0,
1,
2,
5,
8,
10,
11,
12,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
11,
12,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
11,
12,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
11,
12,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
11,
12,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
11,
12,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
11,
12,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
11,
12,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
11,
12,
9,
6,
7,
3,
4],
[0,
1,
2,
5,
8,
10,
11,
12,
9,
6,
7,
3,
4],
[0,
0,
1,
5,
8,
10,
11,
12,
9,
6,
3,
4,
4]]]
Players2dropTable = [DropRegionTables[0],
DropRegionTables[0],
DropRegionTables[0],
DropRegionTables[1],
DropRegionTables[1],
DropRegionTables[2],
DropRegionTables[3],
DropRegionTables[3],
DropRegionTables[4],
DropRegionTables[4],
DropRegionTables[5],
DropRegionTables[5],
DropRegionTables[5],
DropRegionTables[6],
DropRegionTables[6],
DropRegionTables[7],
DropRegionTables[7],
DropRegionTables[7],
DropRegionTables[8],
DropRegionTables[8]]
@classmethod
def getDropRegionTable(cls, numPlayers):
return cls.Players2dropTable[min(len(cls.Players2dropTable) - 1, numPlayers)]
def __init__(self, game, numPlayers, dropTypes, startTime = None):
DropPlacer.__init__(self, game, numPlayers, dropTypes, startTime=startTime)
self.DropRegionTable = self.getDropRegionTable(self.numPlayers)
self.DropRegion2GridCoordList = {}
for row in xrange(len(self.DropRegionTable)):
rowList = self.DropRegionTable[row]
for column in xrange(len(rowList)):
region = rowList[column]
if region not in self.DropRegion2GridCoordList:
self.DropRegion2GridCoordList[region] = []
self.DropRegion2GridCoordList[region].append([row, column])
self.DropRegions = self.DropRegion2GridCoordList.keys()
self.DropRegions.sort()
self.emptyDropRegions = self.DropRegions[:]
self.fallingObjs = []
def getNextDrop(self):
t = self.getT()
while len(self.fallingObjs):
landTime, dropRegion = self.fallingObjs[0]
if landTime > t:
break
self.fallingObjs = self.fallingObjs[1:]
if dropRegion not in self.emptyDropRegions:
self.emptyDropRegions.append(dropRegion)
candidates = self.emptyDropRegions
if len(candidates) == 0:
candidates = self.DropRegions
dropRegion = self.rng.choice(candidates)
row, col = self.rng.choice(self.DropRegion2GridCoordList[dropRegion])
dropTypeName = self.getNextDropTypeName()
drop = [t, dropTypeName, [row, col]]
duration = self.game.BaselineDropDuration
self.fallingObjs.append([t + duration, dropRegion])
if dropRegion in self.emptyDropRegions:
self.emptyDropRegions.remove(dropRegion)
self.stepT()
return drop
class PartyRegionDropPlacer(RegionDropPlacer):
def __init__(self, game, numPlayers, generationId, dropTypes, startTime = None):
self.generationId = generationId
RegionDropPlacer.__init__(self, game, numPlayers, dropTypes, startTime=startTime)
def _createRng(self):
self.rng = RandomNumGen(self.generationId + self.game.doId)
def _createScheduler(self, startTime):
self.scheduler = DropScheduler.ThreePhaseDropScheduler(PartyCatchDuration, self.game.FirstDropDelay, self.game.DropPeriod, self.game.MaxDropDuration, self.game.SlowerDropPeriodMult, self.game.NormalDropDelay, self.game.FasterDropDelay, self.game.FasterDropPeriodMult, startTime=startTime)
class PathDropPlacer(DropPlacer):
def __init__(self, game, numPlayers, dropTypes, startTime = None):
DropPlacer.__init__(self, game, numPlayers, dropTypes, startTime=startTime)
self.moves = [[0, -1],
[1, -1],
[1, 0],
[1, 1],
[0, 1],
[-1, 1],
[-1, 0],
[-1, -1]]
self.paths = []
for i in xrange(self.numPlayers):
dir = self.rng.randrange(0, len(self.moves))
col, row = self.getRandomColRow()
path = {'direction': dir,
'location': [col, row]}
self.paths.append(path)
self.curPathIndex = 0
def getValidDirection(self, col, row, dir):
redirectTop = [(6, 2),
2,
2,
3,
4,
5,
6,
6]
redirectRight = [0,
0,
(0, 4),
4,
4,
5,
6,
7]
redirectBottom = [0,
1,
2,
2,
(2, 6),
6,
6,
7]
redirectLeft = [0,
1,
2,
3,
4,
4,
(4, 0),
0]
redirectTopRight = [6,
(6, 4),
4,
4,
4,
5,
6,
6]
redirectBottomRight = [0,
0,
0,
(0, 6),
6,
6,
6,
7]
redirectBottomLeft = [0,
1,
2,
2,
2,
(2, 0),
0,
0]
redirectTopLeft = [2,
2,
2,
3,
4,
4,
4,
(4, 2)]
tables = [None,
redirectTop,
redirectBottom,
None,
redirectLeft,
redirectTopLeft,
redirectBottomLeft,
None,
redirectRight,
redirectTopRight,
redirectBottomRight]
if col == 0:
colIndex = 1
elif col == self.game.DropColumns - 1:
colIndex = 2
else:
colIndex = 0
if row == 0:
rowIndex = 1
elif row == self.game.DropRows - 1:
rowIndex = 2
else:
rowIndex = 0
index = (colIndex << 2) + rowIndex
redirectTable = tables[index]
if not redirectTable:
return dir
newDir = redirectTable[dir]
if type(newDir) != type(1):
newDir = self.rng.choice(newDir)
return newDir
def getNextDrop(self):
path = self.paths[self.curPathIndex]
col, row = path['location']
dir = path['direction']
turns = [-1,
0,
0,
1]
turn = self.rng.choice(turns)
if turn:
dir = (dir + turn) % len(self.moves)
dir = self.getValidDirection(col, row, dir)
dCol, dRow = self.moves[dir]
col += dCol
row += dRow
col = min(max(col, 0), self.game.DropColumns - 1)
row = min(max(row, 0), self.game.DropRows - 1)
path['location'] = [col, row]
path['direction'] = dir
self.curPathIndex = (self.curPathIndex + 1) % len(self.paths)
drop = [self.getT(), self.getNextDropTypeName(), [col, row]]
self.stepT()
return drop