1463 lines
58 KiB
Python
1463 lines
58 KiB
Python
from panda3d.core import *
|
|
from direct.interval.IntervalGlobal import *
|
|
from direct.particles import ParticleEffect
|
|
from StomperGlobals import *
|
|
from direct.distributed import ClockDelta
|
|
from direct.showbase.PythonUtil import lerp
|
|
from otp.level import DistributedEntity
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
from pandac.PandaModules import NodePath
|
|
from otp.level import BasicEntities
|
|
from direct.task import Task
|
|
from toontown.toonbase import ToontownGlobals
|
|
from toontown.coghq import BattleBlocker
|
|
from toontown.toonbase import TTLocalizer
|
|
from toontown.toonbase import ToontownBattleGlobals
|
|
from direct.distributed.ClockDelta import *
|
|
from toontown.golf import BuildGeometry
|
|
from direct.gui.DirectGui import *
|
|
from direct.showbase import RandomNumGen
|
|
from toontown.distributed import DelayDelete
|
|
from toontown.toon import ToonHeadFrame
|
|
from toontown.battle import BattleParticles
|
|
from toontown.battle import MovieUtil
|
|
from toontown.toonbase import ToontownTimer
|
|
from math import pi
|
|
import GameSprite3D, math, random
|
|
|
|
class DistributedGolfGreenGame(BattleBlocker.BattleBlocker):
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedGolfGreenGame')
|
|
|
|
def __init__(self, cr):
|
|
BattleBlocker.BattleBlocker.__init__(self, cr)
|
|
self.blankColor = Vec4(1.0, 1.0, 1.0, 1.0)
|
|
self.fullColor = Vec4(0.6, 0.6, 0.6, 1.0)
|
|
self.neighborColor = Vec4(0.8, 0.8, 0.8, 1.0)
|
|
self.outColor = Vec4(0.0, 0.0, 0.0, 0.0)
|
|
self.blackColor = Vec4(0.0, 0.0, 0.0, 1.0)
|
|
self.acceptErrorDialog = None
|
|
self.doneEvent = 'game Done'
|
|
self.sprites = []
|
|
self.controlSprite = None
|
|
self.standbySprite = None
|
|
self.setupFlag = 0
|
|
self.colorGridFlag = 0
|
|
self.boardIndex = None
|
|
self.board = None
|
|
self.attackPattern = None
|
|
self.tooLowFlag = 0
|
|
self.toonPoints = (Point3(3.0, 13.0, 0.0),
|
|
Point3(6.0, 13.0, 0.0),
|
|
Point3(-3.0, 13.0, 0.0),
|
|
Point3(-6.0, 13.0, 0.0))
|
|
self.joinedToons = []
|
|
self.everJoinedToons = []
|
|
self.flagNextLevel = 0
|
|
self.wildIndex = 8
|
|
self.bombIndex = 7
|
|
self.sizeMult = 1.4
|
|
self.cellSizeX = 1.0 * self.sizeMult
|
|
self.cellSizeZ = self.cellSizeX * 0.8
|
|
self.radiusBall = 0.5 * self.cellSizeX
|
|
self.gridDimX = 9
|
|
self.gridDimZ = 15
|
|
self.minX = -1.0 * (self.gridDimX + 0.3751) * 0.5 * self.cellSizeX
|
|
self.minZ = -self.gridDimZ * 0.1 * self.cellSizeZ
|
|
self.newBallX = 0.0
|
|
self.newBallZ = self.minZ + 0.1 * self.sizeMult
|
|
self.rangeX = (self.gridDimX + 0.5) * self.cellSizeX
|
|
self.rangeZ = self.gridDimZ * self.cellSizeZ
|
|
self.maxX = self.minX + self.rangeX
|
|
self.maxZ = self.minZ + self.rangeZ
|
|
self.sizeX = self.rangeX
|
|
self.sizeZ = self.rangeZ
|
|
self.isActive = 0
|
|
self.boardsLeft = 0
|
|
self.timeLeft = 0
|
|
self.timeStart = None
|
|
self.timeTotal = None
|
|
self.timerTask = None
|
|
self.timerTaskName = 'golfgreengame timer task'
|
|
self.giftId = None
|
|
self.holdGiftId = None
|
|
self.rollTrack = None
|
|
self.zGap = 0.092
|
|
self.screenSizeX = base.a2dRight - base.a2dLeft
|
|
self.screenSizeZ = base.a2dTop - base.a2dBottom
|
|
self.XtoZ = self.screenSizeX / (self.screenSizeZ * (1.0 - self.zGap * 1.0))
|
|
self.countTimeOld = None
|
|
self.countDownRunning = 0
|
|
self.timer = None
|
|
self.hasEntered = 0
|
|
self.trackClosed = 0
|
|
self.running = 0
|
|
self.finished = 0
|
|
self.__toonTracks = {}
|
|
return
|
|
|
|
def disable(self):
|
|
self.unload()
|
|
self.clearToonTracks()
|
|
BattleBlocker.BattleBlocker.disable(self)
|
|
|
|
def updateSpritePos(self):
|
|
if self.spriteNode.isEmpty():
|
|
return
|
|
self.spriteNode.setZ(-self.spriteNotchPos * self.cellSizeZ)
|
|
if self.controlSprite:
|
|
if not self.controlSprite.isActive:
|
|
pass
|
|
self.colorGridFlag = 1
|
|
|
|
def lerpSpritePos(self):
|
|
if self.spriteNode.isEmpty():
|
|
return
|
|
x = self.spriteNode.getX()
|
|
y = self.spriteNode.getY()
|
|
self.rollTrack = Sequence(LerpPosInterval(self.spriteNode, 0.5, Point3(x, y, -self.spriteNotchPos * self.cellSizeZ)))
|
|
if self.controlSprite:
|
|
if not self.controlSprite.isActive:
|
|
pass
|
|
self.colorGridFlag = 1
|
|
self.rollTrack.start()
|
|
if self.soundMove:
|
|
self.soundMove.play()
|
|
messenger.send('wakeup')
|
|
|
|
def findLowestSprite(self):
|
|
lowest = 100
|
|
for sprite in self.sprites:
|
|
if sprite.gridPosZ:
|
|
if sprite.gridPosZ < lowest:
|
|
lowest = sprite.gridPosZ
|
|
|
|
return lowest
|
|
|
|
def setup(self):
|
|
if not self.setupFlag:
|
|
self.setupFlag = 1
|
|
else:
|
|
return
|
|
self.updateSpritePos()
|
|
self.spriteNode.setY(self.radiusBall)
|
|
thing = self.model.find('**/item_board')
|
|
self.block = self.model1.find('**/minnieCircle')
|
|
self.colorRed = (1, 0, 0, 1)
|
|
self.colorBlue = (0, 0, 1, 1)
|
|
self.colorGreen = (0, 1, 0, 1)
|
|
self.colorGhostRed = (1, 0, 0, 0.5)
|
|
self.colorGhostBlue = (0, 0, 1, 0.5)
|
|
self.colorGhostGreen = (0, 1, 0, 0.5)
|
|
self.colorWhite = (1, 1, 1, 1)
|
|
self.colorBlack = (0, 0, 0, 1.0)
|
|
self.colorShadow = (0, 0, 0, 0.5)
|
|
self.lastTime = None
|
|
self.running = 0
|
|
self.massCount = 0
|
|
self.foundCount = 0
|
|
self.controlOffsetX = 0.0
|
|
self.controlOffsetZ = 0.0
|
|
self.grid = []
|
|
for countX in xrange(0, self.gridDimX):
|
|
newRow = []
|
|
for countZ in xrange(self.gridDimZ):
|
|
offset = 0
|
|
margin = self.cellSizeX * 0.4375
|
|
if countZ % 2 == 0:
|
|
offset = self.cellSizeX * 0.5
|
|
newCell = [None,
|
|
countX * self.cellSizeX + self.minX + offset + margin,
|
|
countZ * self.cellSizeZ + self.minZ,
|
|
countX,
|
|
countZ,
|
|
None]
|
|
groundCircle = loader.loadModel('phase_12/models/bossbotHQ/bust_a_cog_hole')
|
|
groundCircle.reparentTo(self.spriteNode)
|
|
groundCircle.setTransparency(TransparencyAttrib.MAlpha)
|
|
groundCircle.setPos(newCell[1], -self.radiusBall, newCell[2])
|
|
groundCircle.setScale(1.2)
|
|
groundCircle.setR(90)
|
|
groundCircle.setH(-90)
|
|
newCell[5] = groundCircle
|
|
newCell[5].setColorScale(self.blankColor)
|
|
newRow.append(newCell)
|
|
|
|
self.grid.append(newRow)
|
|
|
|
self.cogSprite = self.addUnSprite(self.block, posX=0.25, posZ=0.5)
|
|
self.cogSprite.setColor(self.colorShadow)
|
|
self.cogSprite.nodeObj.hide()
|
|
self.standbySprite = self.addUnSprite(self.block, posX=0.0, posZ=-3.0)
|
|
self.standbySprite.setColor(self.colorShadow)
|
|
self.standbySprite.spriteBase.reparentTo(self.frame)
|
|
self.standbySprite.spriteBase.setY(self.radiusBall)
|
|
self.standbySprite.nodeObj.hide()
|
|
self.boardData = [((1, 0, 0),
|
|
(4, 0, 1),
|
|
(6, 0, 2),
|
|
(1, 1, 0)), ((1, 0, 1),
|
|
(4, 0, 1),
|
|
(6, 0, 1),
|
|
(1, 1, 1)), ((1, 0, 2),
|
|
(4, 0, 2),
|
|
(6, 0, 2),
|
|
(1, 1, 2))]
|
|
self.attackPatterns = [(0, 1, 2), (0, 0, 1, 1, 2, 2), (0, 1, 0, 2)]
|
|
self.winCounter = 0
|
|
self.matchList = []
|
|
self.newBallTime = 5.0
|
|
self.newBallCountUp = 0.0
|
|
self.cogX = 0
|
|
self.cogZ = 0
|
|
self.aimRadian = 0.0
|
|
self.ballLoaded = 0.0
|
|
self.countTime = 10
|
|
self.countDown = self.countTime
|
|
return
|
|
|
|
def printGrid(self):
|
|
printout = ' '
|
|
for columnIndex in xrange(self.gridDimX - 1, -1, -1):
|
|
if columnIndex < 10:
|
|
printout += '%s ' % columnIndex
|
|
else:
|
|
printout += '%s ' % columnIndex
|
|
|
|
print printout
|
|
for rowIndex in xrange(self.gridDimZ - 1, -1, -1):
|
|
if rowIndex < 10:
|
|
printout = 'row %s ' % rowIndex
|
|
else:
|
|
printout = 'row %s ' % rowIndex
|
|
for columnIndex in xrange(self.gridDimX - 1, -1, -1):
|
|
hasSprite = '_'
|
|
if self.grid[columnIndex][rowIndex][0]:
|
|
hasSprite = 'X'
|
|
if rowIndex < 10:
|
|
printout += '%s ' % hasSprite
|
|
else:
|
|
printout += '%s ' % hasSprite
|
|
|
|
print printout
|
|
|
|
count = 0
|
|
for sprite in self.sprites:
|
|
print 'count %s X %s Z %s Color %s' % (count,
|
|
sprite.gridPosX,
|
|
sprite.gridPosZ,
|
|
sprite.colorType)
|
|
count += 1
|
|
|
|
def pickLevelPattern(self):
|
|
self.boardIndex = random.choice(range(0, len(self.boardData)))
|
|
self.board = self.boardData[self.boardIndex]
|
|
self.attackPattern = self.attackPatterns[self.boardIndex]
|
|
self.attackCounter = 0
|
|
self.spriteNotchPos = 0
|
|
for ball in self.board:
|
|
newSprite = self.addSprite(self.block, found=1, color=ball[2])
|
|
self.placeIntoGrid(newSprite, ball[0], self.gridDimZ - 1 - ball[1])
|
|
|
|
self.colorGridFlag = 1
|
|
self.updateSpritePos()
|
|
|
|
def load(self):
|
|
BattleParticles.loadParticles()
|
|
model = loader.loadModel('phase_5.5/models/gui/package_delivery_panel')
|
|
model1 = loader.loadModel('phase_3.5/models/gui/matching_game_gui')
|
|
self.invModel = loader.loadModel('phase_3.5/models/gui/inventory_icons')
|
|
self.model = model
|
|
self.model1 = model1
|
|
self.soundFire = base.loadSfx('phase_6/audio/sfx/Golf_Hit_Ball.ogg')
|
|
self.soundLand = base.loadSfx('phase_4/audio/sfx/MG_maze_pickup.ogg')
|
|
self.soundBurst = base.loadSfx('phase_5/audio/sfx/Toon_bodyfall_synergy.ogg')
|
|
self.soundBomb = base.loadSfx('phase_4/audio/sfx/MG_cannon_fire_alt.ogg')
|
|
self.soundLose = base.loadSfx('phase_11/audio/sfx/LB_capacitor_discharge_3.ogg')
|
|
self.soundWin = base.loadSfx('phase_4/audio/sfx/MG_pairing_match_bonus_both.ogg')
|
|
self.soundDone = base.loadSfx('phase_3/audio/sfx/GUI_create_toon_back.ogg')
|
|
self.soundMove = base.loadSfx('phase_3.5/audio/sfx/SA_shred.ogg')
|
|
background = model.find('**/bg')
|
|
itemBoard = model.find('**/item_board')
|
|
self.focusPoint = self.baseNode.attachNewNode('GolfGreenGameFrame')
|
|
self.frame2D = DirectFrame(scale=1.1, relief=DGG.FLAT, frameSize=(-0.1,
|
|
0.1,
|
|
-0.1,
|
|
-0.1), frameColor=(0.737, 0.573, 0.345, 0.3))
|
|
gui2 = loader.loadModel('phase_3/models/gui/quit_button')
|
|
self.quitButton = DirectButton(parent=self.frame2D, relief=None, image=(gui2.find('**/QuitBtn_UP'), gui2.find('**/QuitBtn_DN'), gui2.find('**/QuitBtn_RLVR')), pos=(0.95, 1.3, -0.69), image_scale=(0.9, 1.0, 1.0), text=TTLocalizer.BustACogExit, text_font=ToontownGlobals.getSignFont(), text0_fg=(1, 1, 1, 1), text0_shadow=(0, 0, 0, 1), text1_fg=(1, 1, 1, 1), text2_fg=(1, 1, 1, 1), text_scale=TTLocalizer.DGGGquitButton, text_pos=(0, -0.01), command=self.__leaveGame)
|
|
self.quitButton.hide()
|
|
self.instructions = DirectFrame(parent=self.frame2D, relief=None, image=DGG.getDefaultDialogGeom(), image_color=ToontownGlobals.GlobalDialogColor, image_scale=(1.2, 1.0, 1.0), text=TTLocalizer.GolfGreenGameDirections, text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ALeft, text_wordwrap=16, text_scale=0.06, text_pos=(-0.5, 0.3), pos=(0.0, 0, -0.0))
|
|
self.instructions.hide()
|
|
imageCogBall = loader.loadModel('phase_12/models/bossbotHQ/bust_a_cog_ball_cog')
|
|
imageCogBall.setHpr(0, 90, 0)
|
|
self.instCogBall = DirectFrame(parent=self.instructions, relief=None, image=imageCogBall, image_color=ToontownGlobals.GlobalDialogColor, image_scale=(0.12, 0.12, 0.12), pos=(0.0, 0, -0.2))
|
|
buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui')
|
|
cancelImageList = (buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr'))
|
|
self.doneButton = DirectButton(parent=self.instructions, relief=None, image=cancelImageList, command=self.instructions.hide, pos=(0, 0, -0.4))
|
|
self.howToButton = DirectButton(parent=self.frame2D, relief=None, image=(gui2.find('**/QuitBtn_UP'), gui2.find('**/QuitBtn_DN'), gui2.find('**/QuitBtn_RLVR')), pos=(0.95, 1.3, -0.82), image_scale=(0.9, 1.0, 1.0), text=TTLocalizer.BustACogHowto, text_font=ToontownGlobals.getSignFont(), text0_fg=(1, 1, 1, 1), text0_shadow=(0, 0, 0, 1), text1_fg=(1, 1, 1, 1), text2_fg=(1, 1, 1, 1), text_scale=TTLocalizer.DGGGhowToButton, text_pos=(0, -0.01), command=self.instructions.show)
|
|
self.howToButton.hide()
|
|
self.timerLabel = DirectLabel(parent=self.frame2D, relief=None, image=gui2.find('**/QuitBtn_UP'), pos=(0.9, 1.3, -0.42), image_scale=(0.5, 1.0, 1.0), text='Timer', text_font=ToontownGlobals.getSignFont(), text0_fg=(1, 1, 1, 1), text_scale=0.045, text_pos=(0, -0.01))
|
|
self.timerLabel.hide()
|
|
self.headPanel = loader.loadModel('phase_6/models/golf/headPanel')
|
|
self.scoreBoard = DirectFrame(scale=1.0, pos=(0.0, 0, 0.9), relief=DGG.FLAT, parent=aspect2d, frameSize=(-0.35,
|
|
0.35,
|
|
-0.05,
|
|
0.05), frameColor=(0.737, 0.573, 0.345, 0.3))
|
|
self.scoreLabel = DirectLabel(parent=self.scoreBoard, relief=None, pos=(0, 0, 0), scale=1.0, text='', text_font=ToontownGlobals.getSignFont(), text0_fg=(1, 1, 1, 1), text0_shadow=(0.0, 0.0, 0.0, 1), text_scale=TTLocalizer.DGGGscoreLabel, text_pos=(0, -0.02))
|
|
self.scoreBoard.hide()
|
|
self.bonusBoard = DirectFrame(parent=self.frame2D, relief=None, image_pos=(0, 0, 0.0), image_scale=(0.4, 1, 0.4), image_color=(1, 1, 1, 1), pos=(0.0, 1.5, 0.67), scale=1.0, text='You gotsa bonus fool!', text_font=ToontownGlobals.getSignFont(), text0_fg=(1, 1, 1, 1), text0_shadow=(0.0, 0.0, 0.0, 1), text_scale=0.055, text_pos=(0, -0.1), textMayChange=1)
|
|
self.bonusBoard.hide()
|
|
self.backBoard = loader.loadModel('phase_12/models/bossbotHQ/bust_a_cog_background')
|
|
self.backBoard.setCollideMask(BitMask32.allOff())
|
|
self.backBoard.reparentTo(self.frame)
|
|
self.backBoard.setScale(0.3, 0.2, 0.25)
|
|
self.backBoard.setHpr(0, -90, 0)
|
|
self.backBoard.setPos(0, -1.5, 8.0)
|
|
self.backBoard.hide()
|
|
base.bb = self.backBoard
|
|
self.aimbase = loader.loadModel('phase_12/models/bossbotHQ/bust_a_cog_shooter')
|
|
self.aimbase.setHpr(90, 0, 90)
|
|
self.aimbase.setScale(0.3, 0.3, 0.15)
|
|
self.aimbase.reparentTo(self.frame)
|
|
self.aimbase.setPos(0.0, 0.0, self.minZ + 0.1)
|
|
self.aimer = self.aimbase.attachNewNode('GolfGreenGameBase')
|
|
aimer = self.aimbase.find('**/moving*')
|
|
aimer.reparentTo(self.aimer)
|
|
aimer.setPos(0.0, 0.0, 0.0)
|
|
base.gi = aimer
|
|
self.aimbase.hide()
|
|
self.toonPanels = {}
|
|
return
|
|
|
|
def addToonHeadPanel(self, toon):
|
|
tPanels = ToonHeadFrame.ToonHeadFrame(toon, (0.4, 0.4, 0.4, 0.6), self.headPanel)
|
|
tPanels.extraData['text_fg'] = (1.0, 1.0, 1.0, 1.0)
|
|
tPanels.extraData['text_shadow'] = (0.0, 0.0, 0.0, 1.0)
|
|
tPanels.extraData.show()
|
|
tPanels.setScale(0.3, 1, 0.7)
|
|
tPanels.head.setPos(0, 10, 0.18)
|
|
tPanels.head.setScale(0.47, 0.2, 0.2)
|
|
tPanels.tag1.setPos(0.3, 10, 0.18)
|
|
tPanels.tag1.setScale(0.1283, 0.055, 0.055)
|
|
tPanels.tag2.setPos(0, 10, 0.43)
|
|
tPanels.tag2.setScale(0.117, 0.05, 0.05)
|
|
tPanels.hide()
|
|
self.toonPanels[toon.doId] = tPanels
|
|
self.arrangeToonHeadPanels()
|
|
|
|
def removeToonHeadPanel(self, avId):
|
|
if avId in self.toonPanels:
|
|
self.toonPanels[avId].destroy()
|
|
del self.toonPanels[avId]
|
|
self.arrangeToonHeadPanels()
|
|
|
|
def arrangeToonHeadPanels(self):
|
|
toonPanelsStart = 0.0
|
|
whichToon = 0
|
|
color = 0
|
|
tpDiff = -0.45
|
|
for panelKey in self.toonPanels:
|
|
panel = self.toonPanels[panelKey]
|
|
if self.isActive:
|
|
panel.show()
|
|
else:
|
|
panel.hide()
|
|
if whichToon <= 1:
|
|
panel.setPos(-1, 0, toonPanelsStart + whichToon * tpDiff)
|
|
else:
|
|
panel.setPos(1, 0, toonPanelsStart + (whichToon - 2) * tpDiff)
|
|
whichToon += 1
|
|
|
|
def unload(self):
|
|
self.cleanupTimer()
|
|
for panelKey in self.toonPanels:
|
|
self.toonPanels[panelKey].destroy()
|
|
|
|
self.headPanel.removeNode()
|
|
self.toonPanels = None
|
|
self.soundFire = None
|
|
self.soundLand = None
|
|
self.soundBurst = None
|
|
self.soundBomb = None
|
|
self.soundLose = None
|
|
self.soundWin = None
|
|
self.soundDone = None
|
|
self.soundMove = None
|
|
self.scoreBoard.destroy()
|
|
self.instructions.destroy()
|
|
self.frame2D.destroy()
|
|
self.baseNode.removeNode()
|
|
del self.baseNode
|
|
if self.acceptErrorDialog:
|
|
self.acceptErrorDialog.cleanup()
|
|
self.acceptErrorDialog = None
|
|
self.stopCountDown()
|
|
self.__stop()
|
|
self.ignoreAll()
|
|
return
|
|
|
|
def show(self):
|
|
self.frame.show()
|
|
|
|
def hide(self):
|
|
self.frame.hide()
|
|
|
|
def __handleExit(self):
|
|
self.__acceptExit()
|
|
|
|
def __startGame(self):
|
|
if not self.setupFlag:
|
|
self.setup()
|
|
self.quitButton.show()
|
|
self.howToButton.show()
|
|
self.backBoard.show()
|
|
self.aimbase.show()
|
|
self.squareNode.show()
|
|
self.scoreBoard.show()
|
|
self.standbySprite.nodeObj.show()
|
|
self.groundFlag.hide()
|
|
self.isActive = 1
|
|
self.__setCamera()
|
|
self.spriteNode.show()
|
|
base.setCellsAvailable([base.bottomCells[1], base.bottomCells[2], base.bottomCells[3]], 0)
|
|
self.setupFlag = 1
|
|
|
|
def startBoard(self, board, attackPattern):
|
|
if self.finished:
|
|
return
|
|
self.clearGrid()
|
|
self.board = board
|
|
self.attackPattern = attackPattern
|
|
self.attackCounter = 0
|
|
self.spriteNotchPos = 0
|
|
self.countDown = self.countTime
|
|
self.tooLowFlag = 0
|
|
for ball in self.board:
|
|
newSprite = self.addSprite(self.block, found=1, color=ball[2])
|
|
self.placeIntoGrid(newSprite, ball[0], self.gridDimZ - 1 - ball[1])
|
|
|
|
self.colorGridFlag = 1
|
|
self.tooLowFlag = 0
|
|
self.startCountDown()
|
|
self.updateSpritePos()
|
|
self.killSprite(self.controlSprite)
|
|
self.accept('mouse1', self.__handleMouseClick)
|
|
self.__run()
|
|
|
|
def startCountDown(self):
|
|
if self.countDownRunning == 0:
|
|
taskMgr.add(self.doCountDown, 'GolfGreenGame countdown')
|
|
self.countDownRunning = 1
|
|
|
|
def stopCountDown(self):
|
|
taskMgr.remove('GolfGreenGame countdown')
|
|
self.countDownRunning = 0
|
|
self.countTimeOld = None
|
|
return
|
|
|
|
def doCountDown(self, task):
|
|
currentTime = globalClock.getFrameTime()
|
|
if self.countTimeOld == None:
|
|
self.countTimeOld = currentTime
|
|
if currentTime - self.countTimeOld < 1.0:
|
|
return task.cont
|
|
else:
|
|
self.countTimeOld = currentTime
|
|
self.countDown -= 1
|
|
if self.countDown in [3, 2, 1]:
|
|
for sprite in self.sprites:
|
|
sprite.warningBump()
|
|
|
|
elif self.countDown == 0:
|
|
self.countDown = self.countTime
|
|
self.spriteNotchPos += 1
|
|
self.lerpSpritePos()
|
|
self.checkForTooLow()
|
|
self.timerLabel['text'] = '%s' % self.countDown
|
|
return task.cont
|
|
return
|
|
|
|
def checkForTooLow(self):
|
|
low = self.findLowestSprite()
|
|
if low <= self.spriteNotchPos:
|
|
self.doFail()
|
|
|
|
def doFail(self):
|
|
self.tooLowFlag = 1
|
|
taskMgr.doMethodLater(1.0, self.failBoard, 'finishing Failure')
|
|
for sprite in self.sprites:
|
|
sprite.setColorType(4)
|
|
|
|
self.__stop()
|
|
self.ignore('mouse1')
|
|
|
|
def failBoard(self, task = None):
|
|
self.__finishBoard(0)
|
|
|
|
def __handleWin(self):
|
|
self.__handleExit()
|
|
|
|
def __finishBoard(self, success = 1):
|
|
if self.rollTrack:
|
|
self.rollTrack.finish()
|
|
self.countDown = self.countTime
|
|
if success:
|
|
if self.soundWin:
|
|
self.soundWin.play()
|
|
elif self.soundLose:
|
|
self.soundLose.play()
|
|
self.giftId = None
|
|
self.attackPattern = None
|
|
self.stopCountDown()
|
|
self.clearGrid()
|
|
self.spriteNotchPos = 0
|
|
self.updateSpritePos()
|
|
self.__stop()
|
|
self.ignore('mouse1')
|
|
if not self.tooLowFlag or 1:
|
|
self.sendUpdate('requestBoard', [success])
|
|
return
|
|
|
|
def __acceptExit(self, buttonValue = None):
|
|
if hasattr(self, 'frame'):
|
|
self.hide()
|
|
self.unload()
|
|
messenger.send(self.doneEvent)
|
|
camera.reparentTo(base.localAvatar)
|
|
base.localAvatar.startUpdateSmartCamera()
|
|
|
|
def __removeGame(self):
|
|
self.spriteNode.removeNode()
|
|
self.setupFlag = 0
|
|
|
|
def __leaveGame(self):
|
|
taskMgr.remove('GolfGreenGameTask')
|
|
self.stopCountDown()
|
|
taskMgr.remove(self.timerTaskName)
|
|
self.ignore('mouse1')
|
|
camera.reparentTo(base.localAvatar)
|
|
base.localAvatar.startUpdateSmartCamera()
|
|
base.cr.playGame.getPlace().fsm.request('walk')
|
|
for sprite in self.sprites:
|
|
sprite.delete()
|
|
|
|
self.sprites = []
|
|
if self.spriteNode:
|
|
self.spriteNode.hide()
|
|
self.controlSprite = None
|
|
self.running = 0
|
|
self.timerLabel.hide()
|
|
self.quitButton.hide()
|
|
self.howToButton.hide()
|
|
self.backBoard.hide()
|
|
self.aimbase.hide()
|
|
self.squareNode.hide()
|
|
self.groundFlag.show()
|
|
self.instructions.hide()
|
|
self.isActive = 0
|
|
if self.standbySprite:
|
|
self.standbySprite.nodeObj.hide()
|
|
base.setCellsAvailable([base.bottomCells[1], base.bottomCells[2], base.bottomCells[3]], 1)
|
|
self.sendUpdate('leaveGame', [])
|
|
return
|
|
|
|
def findGrid(self, x, z, force = 0):
|
|
currentClosest = None
|
|
currentDist = 10000000
|
|
for countX in xrange(self.gridDimX):
|
|
for countZ in xrange(self.gridDimZ):
|
|
testDist = self.testPointDistanceSquare(x, z, self.grid[countX][countZ][1], self.grid[countX][countZ][2])
|
|
if self.grid[countX][countZ][0] == None and testDist < currentDist and (force or self.hasNeighbor(countX, countZ) != None):
|
|
currentClosest = self.grid[countX][countZ]
|
|
self.closestX = countX
|
|
self.closestZ = countZ
|
|
currentDist = testDist
|
|
|
|
return currentClosest
|
|
|
|
def hasNeighbor(self, cellX, cellZ):
|
|
gotNeighbor = None
|
|
if cellZ % 2 == 0:
|
|
if self.testGridfull(self.getValidGrid(cellX - 1, cellZ)):
|
|
gotNeighbor = cellZ
|
|
elif self.testGridfull(self.getValidGrid(cellX + 1, cellZ)):
|
|
gotNeighbor = cellZ
|
|
elif self.testGridfull(self.getValidGrid(cellX, cellZ + 1)):
|
|
gotNeighbor = cellZ + 1
|
|
elif self.testGridfull(self.getValidGrid(cellX + 1, cellZ + 1)):
|
|
gotNeighbor = cellZ + 1
|
|
elif self.testGridfull(self.getValidGrid(cellX, cellZ - 1)):
|
|
gotNeighbor = cellZ - 1
|
|
elif self.testGridfull(self.getValidGrid(cellX + 1, cellZ - 1)):
|
|
gotNeighbor = cellZ - 1
|
|
elif self.testGridfull(self.getValidGrid(cellX - 1, cellZ)):
|
|
gotNeighbor = cellZ
|
|
elif self.testGridfull(self.getValidGrid(cellX + 1, cellZ)):
|
|
gotNeighbor = cellZ
|
|
elif self.testGridfull(self.getValidGrid(cellX, cellZ + 1)):
|
|
gotNeighbor = cellZ + 1
|
|
elif self.testGridfull(self.getValidGrid(cellX - 1, cellZ + 1)):
|
|
gotNeighbor = cellZ + 1
|
|
elif self.testGridfull(self.getValidGrid(cellX, cellZ - 1)):
|
|
gotNeighbor = cellZ - 1
|
|
elif self.testGridfull(self.getValidGrid(cellX - 1, cellZ - 1)):
|
|
gotNeighbor = cellZ - 1
|
|
return gotNeighbor
|
|
|
|
def clearFloaters(self):
|
|
self.grounded = []
|
|
self.unknown = []
|
|
groundZ = self.gridDimZ - 1
|
|
for indexX in xrange(0, self.gridDimX):
|
|
gridCell = self.grid[indexX][groundZ]
|
|
if gridCell[0]:
|
|
self.grounded.append((indexX, groundZ))
|
|
|
|
for column in self.grid:
|
|
for cell in column:
|
|
if cell[0] != None:
|
|
cellData = (cell[3], cell[4])
|
|
if cellData not in self.grounded:
|
|
self.unknown.append(cellData)
|
|
|
|
lastUnknownCount = 0
|
|
while len(self.unknown) != lastUnknownCount:
|
|
lastUnknownCount = len(self.unknown)
|
|
for cell in self.unknown:
|
|
if self.hasGroundedNeighbor(cell[0], cell[1]):
|
|
self.unknown.remove(cell)
|
|
self.grounded.append(cell)
|
|
|
|
for entry in self.unknown:
|
|
gridEntry = self.grid[entry[0]][entry[1]]
|
|
sprite = gridEntry[0]
|
|
self.killSprite(sprite)
|
|
|
|
return
|
|
|
|
def explodeBombs(self):
|
|
didBomb = 0
|
|
for column in self.grid:
|
|
for cell in column:
|
|
if cell[0] != None:
|
|
if cell[0].colorType == self.bombIndex:
|
|
self.killSprite(cell[0])
|
|
didBomb += 1
|
|
|
|
if didBomb:
|
|
self.soundBomb.play()
|
|
return
|
|
|
|
def hasGroundedNeighbor(self, cellX, cellZ):
|
|
gotNeighbor = None
|
|
if cellZ % 2 == 0:
|
|
if (cellX - 1, cellZ) in self.grounded:
|
|
gotNeighbor = cellZ
|
|
elif (cellX + 1, cellZ) in self.grounded:
|
|
gotNeighbor = cellZ
|
|
elif (cellX, cellZ + 1) in self.grounded:
|
|
gotNeighbor = cellZ + 1
|
|
elif (cellX + 1, cellZ + 1) in self.grounded:
|
|
gotNeighbor = cellZ + 1
|
|
elif (cellX, cellZ - 1) in self.grounded:
|
|
gotNeighbor = cellZ - 1
|
|
elif (cellX + 1, cellZ - 1) in self.grounded:
|
|
gotNeighbor = cellZ - 1
|
|
elif (cellX - 1, cellZ) in self.grounded:
|
|
gotNeighbor = cellZ
|
|
elif (cellX + 1, cellZ) in self.grounded:
|
|
gotNeighbor = cellZ
|
|
elif (cellX, cellZ + 1) in self.grounded:
|
|
gotNeighbor = cellZ + 1
|
|
elif (cellX - 1, cellZ + 1) in self.grounded:
|
|
gotNeighbor = cellZ + 1
|
|
elif (cellX, cellZ - 1) in self.grounded:
|
|
gotNeighbor = cellZ - 1
|
|
elif (cellX - 1, cellZ - 1) in self.grounded:
|
|
gotNeighbor = cellZ - 1
|
|
return gotNeighbor
|
|
|
|
def clearMatchList(self, typeClear = 0):
|
|
self.soundBurst.play()
|
|
for entry in self.matchList:
|
|
gridEntry = self.grid[entry[0]][entry[1]]
|
|
sprite = gridEntry[0]
|
|
if typeClear == self.wildIndex:
|
|
self.questionSprite(sprite)
|
|
elif typeClear == 0:
|
|
pass
|
|
self.killSprite(sprite)
|
|
|
|
def shakeList(self, neighbors):
|
|
for entry in neighbors:
|
|
gridEntry = self.grid[entry[0]][entry[1]]
|
|
sprite = gridEntry[0]
|
|
self.shakeSprite(sprite)
|
|
|
|
def createMatchList(self, x, z):
|
|
self.matchList = []
|
|
self.fillMatchList(x, z)
|
|
|
|
def matchWild(self, x, z, color):
|
|
spriteType = self.getColorType(x, z)
|
|
if not self.getBreakable(x, z):
|
|
return 0
|
|
elif spriteType != -1 and spriteType == self.wildIndex:
|
|
return 1
|
|
elif spriteType != -1 and color == self.wildIndex:
|
|
return 1
|
|
else:
|
|
return 0
|
|
|
|
def bombNeighbors(self, cellX, cellZ):
|
|
self.soundBomb.play()
|
|
self.matchList = []
|
|
if cellZ % 2 == 0:
|
|
if self.getColorType(cellX - 1, cellZ) != -1:
|
|
self.addToMatchList(cellX - 1, cellZ)
|
|
if self.getColorType(cellX + 1, cellZ) != -1:
|
|
self.addToMatchList(cellX + 1, cellZ)
|
|
if self.getColorType(cellX, cellZ + 1) != -1:
|
|
self.addToMatchList(cellX, cellZ + 1)
|
|
if self.getColorType(cellX + 1, cellZ + 1) != -1:
|
|
self.addToMatchList(cellX + 1, cellZ + 1)
|
|
if self.getColorType(cellX, cellZ - 1) != -1:
|
|
self.addToMatchList(cellX, cellZ - 1)
|
|
if self.getColorType(cellX + 1, cellZ - 1) != -1:
|
|
self.addToMatchList(cellX + 1, cellZ - 1)
|
|
else:
|
|
if self.getColorType(cellX - 1, cellZ) != -1:
|
|
self.addToMatchList(cellX - 1, cellZ)
|
|
if self.getColorType(cellX + 1, cellZ) != -1:
|
|
self.addToMatchList(cellX + 1, cellZ)
|
|
if self.getColorType(cellX, cellZ + 1) != -1:
|
|
self.addToMatchList(cellX, cellZ + 1)
|
|
if self.getColorType(cellX - 1, cellZ + 1) != -1:
|
|
self.addToMatchList(cellX - 1, cellZ + 1)
|
|
if self.getColorType(cellX, cellZ - 1) != -1:
|
|
self.addToMatchList(cellX, cellZ - 1)
|
|
if self.getColorType(cellX - 1, cellZ - 1) != -1:
|
|
self.addToMatchList(cellX - 1, cellZ - 1)
|
|
|
|
def addToMatchList(self, posX, posZ):
|
|
if self.getBreakable(posX, posZ) > 0:
|
|
self.matchList.append((posX, posZ))
|
|
|
|
def getNeighbors(self, cellX, cellZ):
|
|
neighborList = []
|
|
if cellZ % 2 == 0:
|
|
if self.getColorType(cellX - 1, cellZ) != -1:
|
|
neighborList.append((cellX - 1, cellZ))
|
|
if self.getColorType(cellX + 1, cellZ) != -1:
|
|
neighborList.append((cellX + 1, cellZ))
|
|
if self.getColorType(cellX, cellZ + 1) != -1:
|
|
neighborList.append((cellX, cellZ + 1))
|
|
if self.getColorType(cellX + 1, cellZ + 1) != -1:
|
|
neighborList.append((cellX + 1, cellZ + 1))
|
|
if self.getColorType(cellX, cellZ - 1) != -1:
|
|
neighborList.append((cellX, cellZ - 1))
|
|
if self.getColorType(cellX + 1, cellZ - 1) != -1:
|
|
neighborList.append((cellX + 1, cellZ - 1))
|
|
else:
|
|
if self.getColorType(cellX - 1, cellZ) != -1:
|
|
neighborList.append((cellX - 1, cellZ))
|
|
if self.getColorType(cellX + 1, cellZ) != -1:
|
|
neighborList.append((cellX + 1, cellZ))
|
|
if self.getColorType(cellX, cellZ + 1) != -1:
|
|
neighborList.append((cellX, cellZ + 1))
|
|
if self.getColorType(cellX - 1, cellZ + 1) != -1:
|
|
neighborList.append((cellX - 1, cellZ + 1))
|
|
if self.getColorType(cellX, cellZ - 1) != -1:
|
|
neighborList.append((cellX, cellZ - 1))
|
|
if self.getColorType(cellX - 1, cellZ - 1) != -1:
|
|
neighborList.append((cellX - 1, cellZ - 1))
|
|
return neighborList
|
|
|
|
def fillMatchList(self, cellX, cellZ):
|
|
if (cellX, cellZ) in self.matchList:
|
|
return
|
|
self.matchList.append((cellX, cellZ))
|
|
colorType = self.grid[cellX][cellZ][0].colorType
|
|
if colorType == 4:
|
|
return
|
|
if cellZ % 2 == 0:
|
|
if self.getColorType(cellX - 1, cellZ) == colorType or self.matchWild(cellX - 1, cellZ, colorType):
|
|
self.fillMatchList(cellX - 1, cellZ)
|
|
if self.getColorType(cellX + 1, cellZ) == colorType or self.matchWild(cellX + 1, cellZ, colorType):
|
|
self.fillMatchList(cellX + 1, cellZ)
|
|
if self.getColorType(cellX, cellZ + 1) == colorType or self.matchWild(cellX, cellZ + 1, colorType):
|
|
self.fillMatchList(cellX, cellZ + 1)
|
|
if self.getColorType(cellX + 1, cellZ + 1) == colorType or self.matchWild(cellX + 1, cellZ + 1, colorType):
|
|
self.fillMatchList(cellX + 1, cellZ + 1)
|
|
if self.getColorType(cellX, cellZ - 1) == colorType or self.matchWild(cellX, cellZ - 1, colorType):
|
|
self.fillMatchList(cellX, cellZ - 1)
|
|
if self.getColorType(cellX + 1, cellZ - 1) == colorType or self.matchWild(cellX + 1, cellZ - 1, colorType):
|
|
self.fillMatchList(cellX + 1, cellZ - 1)
|
|
else:
|
|
if self.getColorType(cellX - 1, cellZ) == colorType or self.matchWild(cellX - 1, cellZ, colorType):
|
|
self.fillMatchList(cellX - 1, cellZ)
|
|
if self.getColorType(cellX + 1, cellZ) == colorType or self.matchWild(cellX + 1, cellZ, colorType):
|
|
self.fillMatchList(cellX + 1, cellZ)
|
|
if self.getColorType(cellX, cellZ + 1) == colorType or self.matchWild(cellX, cellZ + 1, colorType):
|
|
self.fillMatchList(cellX, cellZ + 1)
|
|
if self.getColorType(cellX - 1, cellZ + 1) == colorType or self.matchWild(cellX - 1, cellZ + 1, colorType):
|
|
self.fillMatchList(cellX - 1, cellZ + 1)
|
|
if self.getColorType(cellX, cellZ - 1) == colorType or self.matchWild(cellX, cellZ - 1, colorType):
|
|
self.fillMatchList(cellX, cellZ - 1)
|
|
if self.getColorType(cellX - 1, cellZ - 1) == colorType or self.matchWild(cellX - 1, cellZ - 1, colorType):
|
|
self.fillMatchList(cellX - 1, cellZ - 1)
|
|
|
|
def testGridfull(self, cell):
|
|
if not cell:
|
|
return 0
|
|
elif cell[0] != None:
|
|
return 1
|
|
else:
|
|
return 0
|
|
return
|
|
|
|
def getValidGrid(self, x, z):
|
|
if x < 0 or x >= self.gridDimX:
|
|
return None
|
|
elif z < 0 or z >= self.gridDimZ:
|
|
return None
|
|
else:
|
|
return self.grid[x][z]
|
|
return None
|
|
|
|
def getColorType(self, x, z):
|
|
if x < 0 or x >= self.gridDimX:
|
|
return -1
|
|
elif z < 0 or z >= self.gridDimZ:
|
|
return -1
|
|
elif self.grid[x][z][0] == None:
|
|
return -1
|
|
else:
|
|
return self.grid[x][z][0].colorType
|
|
return
|
|
|
|
def getBreakable(self, x, z):
|
|
if x < 0 or x >= self.gridDimX:
|
|
return -1
|
|
elif z < 0 or z >= self.gridDimZ:
|
|
return -1
|
|
elif self.grid[x][z][0] == None:
|
|
return -1
|
|
else:
|
|
return self.grid[x][z][0].breakable
|
|
return
|
|
|
|
def findGridCog(self):
|
|
self.cogX = 0
|
|
self.cogZ = 0
|
|
self.massCount = 0
|
|
for row in self.grid:
|
|
for cell in row:
|
|
if cell[0] != None:
|
|
self.cogX += cell[1]
|
|
self.cogZ += cell[2]
|
|
self.massCount += 1
|
|
|
|
if self.massCount > 0:
|
|
self.cogX = self.cogX / self.massCount
|
|
self.cogZ = self.cogZ / self.massCount
|
|
self.cogSprite.setX(self.cogX)
|
|
self.cogSprite.setZ(self.cogZ)
|
|
return
|
|
|
|
def doOnClearGrid(self):
|
|
self.winCounter += 1
|
|
self.clearGrid()
|
|
self.flagNextLevel = 1
|
|
if self.winCounter > 4:
|
|
self.__handleWin()
|
|
|
|
def clearGrid(self):
|
|
for row in self.grid:
|
|
for cell in row:
|
|
if cell[0] != None:
|
|
self.killSprite(cell[0])
|
|
cell[5].setColorScale(self.blankColor)
|
|
|
|
self.killSprite(self.controlSprite)
|
|
return
|
|
|
|
def killSprite(self, sprite):
|
|
if sprite == None:
|
|
return
|
|
if sprite.giftId != None:
|
|
self.giftId = sprite.giftId
|
|
if sprite.foundation:
|
|
self.foundCount -= 1
|
|
if self.controlSprite == sprite:
|
|
self.controlSprite = None
|
|
if sprite in self.sprites:
|
|
self.sprites.remove(sprite)
|
|
if sprite.gridPosX != None:
|
|
self.grid[sprite.gridPosX][sprite.gridPosZ][0] = None
|
|
self.grid[sprite.gridPosX][sprite.gridPosZ][5].setColorScale(self.blankColor)
|
|
sprite.deathEffect()
|
|
sprite.delete()
|
|
self.hasChanged = 1
|
|
return
|
|
|
|
def shakeSprite(self, sprite):
|
|
if sprite == None:
|
|
return
|
|
sprite.shake()
|
|
return
|
|
|
|
def questionSprite(self, sprite):
|
|
newSprite = self.addSprite(self.block, found=0, color=1)
|
|
newSprite.setX(sprite.getX())
|
|
newSprite.setZ(sprite.getZ())
|
|
newSprite.wildEffect()
|
|
|
|
def colorGrid(self):
|
|
for row in self.grid:
|
|
for cell in row:
|
|
if cell[0] != None:
|
|
if cell[0].colorType == 3:
|
|
cell[5].setColorScale(self.blackColor)
|
|
else:
|
|
cell[5].setColorScale(self.fullColor)
|
|
elif cell[4] <= self.spriteNotchPos:
|
|
cell[5].setColorScale(self.outColor)
|
|
elif self.hasNeighbor(cell[3], cell[4]):
|
|
cell[5].setColorScale(self.neighborColor)
|
|
else:
|
|
cell[5].setColorScale(self.blankColor)
|
|
|
|
return
|
|
|
|
def findPos(self, x, z):
|
|
return (self.grid[x][z][1], self.grid[x][z][2])
|
|
|
|
def placeIntoGrid(self, sprite, x, z):
|
|
if self.grid[x][z][0] == None:
|
|
self.grid[x][z][0] = sprite
|
|
sprite.gridPosX = x
|
|
sprite.gridPosZ = z
|
|
sprite.setActive(0)
|
|
newX, newZ = self.findPos(x, z)
|
|
sprite.setX(newX)
|
|
sprite.setZ(newZ)
|
|
if sprite == self.controlSprite:
|
|
self.controlSprite = None
|
|
self.colorGridFlag = 1
|
|
self.hasChanged = 1
|
|
self.findGridCog()
|
|
self.checkForTooLow()
|
|
else:
|
|
self.placeIntoGrid(sprite, x + 1, z - 1)
|
|
return
|
|
|
|
def stickInGrid(self, sprite, force = 0):
|
|
if sprite.isActive:
|
|
gridCell = self.findGrid(sprite.getX(), sprite.getZ(), force)
|
|
if gridCell:
|
|
colorType = sprite.colorType
|
|
sprite.setActive(0)
|
|
self.soundLand.play()
|
|
self.placeIntoGrid(sprite, gridCell[3], gridCell[4])
|
|
if colorType == self.bombIndex:
|
|
kapow = MovieUtil.createKapowExplosionTrack(render, sprite.nodeObj.getPos(render))
|
|
kapow.start()
|
|
self.bombNeighbors(self.closestX, self.closestZ)
|
|
allNeighbors = []
|
|
for entry in self.matchList:
|
|
neighbors = self.getNeighbors(entry[0], entry[1])
|
|
for neighbor in neighbors:
|
|
if neighbor not in allNeighbors and neighbor not in self.matchList:
|
|
allNeighbors.append(neighbor)
|
|
|
|
self.shakeList(allNeighbors)
|
|
self.clearMatchList()
|
|
else:
|
|
self.createMatchList(self.closestX, self.closestZ)
|
|
if len(self.matchList) >= 3:
|
|
clearType = 0
|
|
self.clearMatchList(colorType)
|
|
else:
|
|
neighbors = self.getNeighbors(self.closestX, self.closestZ)
|
|
self.shakeList(neighbors)
|
|
|
|
def addSprite(self, image, size = 3.0, posX = 0, posZ = 0, found = 0, color = None):
|
|
spriteBase = self.spriteNode.attachNewNode('sprite base')
|
|
size = self.radiusBall * 2.0
|
|
facing = 1
|
|
if color == None:
|
|
colorChoice = random.choice(range(0, 3))
|
|
else:
|
|
colorChoice = color
|
|
newSprite = GameSprite3D.GameSprite(spriteBase, size, colorChoice, found, facing)
|
|
newSprite.setX(posX)
|
|
newSprite.setZ(posZ)
|
|
self.sprites.append(newSprite)
|
|
if found:
|
|
self.foundCount += 1
|
|
return newSprite
|
|
|
|
def addControlSprite(self, x = 0.0, z = 0.0, color = None):
|
|
newSprite = self.addSprite(self.block, posX=x, posZ=z, color=color, found=1)
|
|
newSprite.spriteBase.reparentTo(self.frame)
|
|
newSprite.spriteBase.setPos(0.0, 0.7, -1.54)
|
|
self.controlSprite = newSprite
|
|
|
|
def addUnSprite(self, image, size = 3.0, posX = 0, posZ = 0):
|
|
size = self.radiusBall * 2.0
|
|
spriteBase = self.spriteNode.attachNewNode('sprite base')
|
|
newSprite = GameSprite3D.GameSprite(spriteBase, size)
|
|
newSprite.setX(posX)
|
|
newSprite.setZ(posZ)
|
|
return newSprite
|
|
|
|
def __handleMouseClick(self):
|
|
if self.ballLoaded == 2:
|
|
pass
|
|
if self.ballLoaded and self.controlSprite:
|
|
self.controlSprite.spriteBase.wrtReparentTo(self.spriteNode)
|
|
self.controlSprite.setAccel(14.0, pi * 0.0 - self.aimRadian)
|
|
self.controlSprite.setActive(1)
|
|
self.soundFire.play()
|
|
self.ballLoaded = 0
|
|
|
|
def __run(self, cont = 1):
|
|
if cont and not self.running:
|
|
taskMgr.add(self.__run, 'GolfGreenGameTask')
|
|
self.running = 1
|
|
if self.lastTime == None:
|
|
self.lastTime = globalClock.getRealTime()
|
|
timeDelta = globalClock.getRealTime() - self.lastTime
|
|
self.lastTime = globalClock.getRealTime()
|
|
self.newBallCountUp += timeDelta
|
|
if base.mouseWatcherNode.hasMouse():
|
|
inputX = base.mouseWatcherNode.getMouseX()
|
|
inputZ = base.mouseWatcherNode.getMouseY()
|
|
outputZ = inputZ + self.screenSizeZ * (0.5 - self.zGap)
|
|
if outputZ <= 0.0:
|
|
outputZ = 0.0001
|
|
if inputX > 0.0:
|
|
self.aimRadian = -1.0 * pi + math.atan(outputZ / (inputX * self.XtoZ))
|
|
elif inputX < 0.0:
|
|
self.aimRadian = math.atan(outputZ / (inputX * self.XtoZ))
|
|
else:
|
|
self.aimRadian = pi * -0.5
|
|
margin = 0.2
|
|
if self.aimRadian >= -margin:
|
|
self.aimRadian = -margin
|
|
elif self.aimRadian <= margin - pi:
|
|
self.aimRadian = margin - pi
|
|
degrees = self.__toDegrees(self.aimRadian)
|
|
self.aimer.setH(degrees)
|
|
self.wallMaxX = self.maxX - self.radiusBall
|
|
self.wallMinX = self.minX + self.radiusBall
|
|
self.wallMaxZ = self.maxZ - self.radiusBall
|
|
self.wallMinZ = self.minZ + self.radiusBall
|
|
if self.controlSprite and self.controlSprite.nodeObj.isEmpty():
|
|
self.controlSprite = None
|
|
if self.giftId:
|
|
self.ballLoaded = 2
|
|
self.updateSpritePos()
|
|
self.standbySprite.holdType = self.giftId
|
|
self.standbySprite.setBallType(self.giftId, 1)
|
|
self.standbySprite.face()
|
|
self.giftId = None
|
|
while self.controlSprite == None and self.attackPattern:
|
|
if self.attackCounter > len(self.attackPattern) - 1:
|
|
self.attackCounter = 0
|
|
print 'Pattern %s Place %s Type %s' % (self.attackPattern, self.attackCounter, self.attackPattern[self.attackCounter])
|
|
if self.standbySprite.holdType != None:
|
|
color = self.standbySprite.holdType
|
|
sprite = self.addControlSprite(self.newBallX, self.newBallZ + self.spriteNotchPos * self.cellSizeZ, color)
|
|
self.ballLoaded = 1
|
|
self.updateSpritePos()
|
|
newColor = self.predictAttackPattern(0)
|
|
self.standbySprite.holdType = newColor
|
|
self.standbySprite.setBallType(newColor, 1)
|
|
self.standbySprite.face()
|
|
self.attackCounter += 1
|
|
|
|
self.standbySprite.runColor()
|
|
for sprite in self.sprites:
|
|
if sprite.deleteFlag:
|
|
self.sprites.remove(sprite)
|
|
else:
|
|
sprite.run(timeDelta)
|
|
if sprite.getX() > self.wallMaxX:
|
|
sprite.setX(self.wallMaxX)
|
|
sprite.reflectX()
|
|
if sprite.getX() < self.wallMinX:
|
|
sprite.setX(self.wallMinX)
|
|
sprite.reflectX()
|
|
if sprite.getZ() > self.wallMaxZ:
|
|
self.stickInGrid(sprite, 1)
|
|
if sprite.getZ() < self.wallMinZ:
|
|
pass
|
|
|
|
self.__colTest()
|
|
if self.hasChanged and self.running:
|
|
self.clearFloaters()
|
|
self.explodeBombs()
|
|
self.findGridCog()
|
|
spriteCount = 0
|
|
whiteCount = 0
|
|
for row in self.grid:
|
|
for cell in row:
|
|
if cell[0] != None:
|
|
self.cogX += cell[1]
|
|
self.cogZ += cell[2]
|
|
spriteCount += 1
|
|
if cell[0].colorType == 3:
|
|
whiteCount += 1
|
|
|
|
if whiteCount == 0:
|
|
self.__finishBoard()
|
|
self.flagNextLevel = 0
|
|
self.killSprite(self.controlSprite)
|
|
self.standbySprite.holdType = None
|
|
self.colorGridFlag = 1
|
|
self.hasChanged = 0
|
|
if self.colorGridFlag:
|
|
self.colorGridFlag = 0
|
|
self.colorGrid()
|
|
return Task.cont
|
|
|
|
def predictAttackPattern(self, numSteps = 1):
|
|
predict = self.attackCounter + numSteps
|
|
predict = predict % len(self.attackPattern)
|
|
return self.attackPattern[predict]
|
|
|
|
def __stop(self):
|
|
taskMgr.remove('GolfGreenGameTask')
|
|
self.running = 0
|
|
|
|
def __testWin(self):
|
|
gridCount = 0
|
|
for column in self.grid:
|
|
for cell in column:
|
|
if cell[0]:
|
|
gridCount += 1
|
|
|
|
if gridCount == 0:
|
|
self.__handleWin()
|
|
|
|
def __toRadians(self, angle):
|
|
return angle * 2.0 * math.pi / 360.0
|
|
|
|
def __toDegrees(self, angle):
|
|
return angle * 360.0 / (2.0 * math.pi)
|
|
|
|
def __colTest(self):
|
|
if not hasattr(self, 'tick'):
|
|
self.tick = 0
|
|
self.tick += 1
|
|
if self.tick > 5:
|
|
self.tick = 0
|
|
sizeSprites = len(self.sprites)
|
|
for movingSpriteIndex in xrange(len(self.sprites)):
|
|
for testSpriteIndex in xrange(movingSpriteIndex, len(self.sprites)):
|
|
movingSprite = self.getSprite(movingSpriteIndex)
|
|
testSprite = self.getSprite(testSpriteIndex)
|
|
if testSprite and movingSprite:
|
|
if movingSpriteIndex != testSpriteIndex and (movingSprite.isActive or testSprite.isActive):
|
|
if self.testDistance(movingSprite.spriteBase, testSprite.spriteBase) < self.radiusBall * 1.65:
|
|
if not (movingSprite.isActive and testSprite.isActive):
|
|
if movingSprite.canCollide and testSprite.canCollide:
|
|
self.__collide(movingSprite, testSprite)
|
|
if self.tick == 5:
|
|
pass
|
|
|
|
def getSprite(self, spriteIndex):
|
|
if spriteIndex >= len(self.sprites) or self.sprites[spriteIndex].markedForDeath:
|
|
return None
|
|
else:
|
|
return self.sprites[spriteIndex]
|
|
return None
|
|
|
|
def testDistance(self, nodeA, nodeB):
|
|
if nodeA.isEmpty() or nodeB.isEmpty():
|
|
return 10000
|
|
distX = nodeA.getX() - nodeB.getX()
|
|
distZ = nodeA.getZ() - nodeB.getZ()
|
|
distC = distX * distX + distZ * distZ
|
|
dist = math.sqrt(distC)
|
|
return dist
|
|
|
|
def testPointDistance(self, x1, z1, x2, z2):
|
|
distX = x1 - x2
|
|
distZ = z1 - z2
|
|
distC = distX * distX + distZ * distZ
|
|
dist = math.sqrt(distC)
|
|
if dist == 0:
|
|
dist = 1e-10
|
|
return dist
|
|
|
|
def testPointDistanceSquare(self, x1, z1, x2, z2):
|
|
distX = x1 - x2
|
|
distZ = z1 - z2
|
|
distC = distX * distX + distZ * distZ
|
|
if distC == 0:
|
|
distC = 1e-10
|
|
return distC
|
|
|
|
def angleTwoSprites(self, sprite1, sprite2):
|
|
x1 = sprite1.getX()
|
|
z1 = sprite1.getZ()
|
|
x2 = sprite2.getX()
|
|
z2 = sprite2.getZ()
|
|
x = x2 - x1
|
|
z = z2 - z1
|
|
angle = math.atan2(-x, z)
|
|
return angle + pi * 0.5
|
|
|
|
def angleTwoPoints(self, x1, z1, x2, z2):
|
|
x = x2 - x1
|
|
z = z2 - z1
|
|
angle = math.atan2(-x, z)
|
|
return angle + pi * 0.5
|
|
|
|
def __collide(self, move, test):
|
|
test.velX = 0
|
|
test.velZ = 0
|
|
move.velX = 0
|
|
move.velZ = 0
|
|
test.collide()
|
|
move.collide()
|
|
self.stickInGrid(move)
|
|
self.stickInGrid(test)
|
|
|
|
def generateInit(self):
|
|
self.notify.debug('generateInit')
|
|
BattleBlocker.BattleBlocker.generateInit(self)
|
|
|
|
def generate(self):
|
|
self.notify.debug('generate')
|
|
BasicEntities.DistributedNodePathEntity.generate(self)
|
|
|
|
def announceGenerate(self):
|
|
self.notify.debug('announceGenerate')
|
|
BattleBlocker.BattleBlocker.announceGenerate(self)
|
|
self.baseNode = self.attachNewNode('GolfGreenGameBase')
|
|
self.frame = self.baseNode.attachNewNode('GolfGreenGameFrame')
|
|
self.spriteNode = self.frame.attachNewNode('GolfGreenGameSpriteNode')
|
|
self.frame.setScale(1.0)
|
|
self.frame.setP(90)
|
|
self.spriteNotchPos = 0
|
|
self.frame.setY(10.0)
|
|
self.frame.setZ(2.0)
|
|
self.spriteNode.setY(0.5)
|
|
self.hasChanged = 0
|
|
self.squareNode = self.frame.attachNewNode('GolfGreenGameBase')
|
|
groundCircle = loader.loadModel('phase_12/models/bossbotHQ/bust_a_cog_golf_green')
|
|
groundCircle.reparentTo(self.baseNode)
|
|
groundCircle.setScale(0.24)
|
|
self.groundFlag = loader.loadModel('phase_12/models/bossbotHQ/bust_a_cog_golf_flag')
|
|
self.groundFlag.reparentTo(self.baseNode)
|
|
self.groundFlag.setScale(0.5)
|
|
self.groundFlag.setH(-45)
|
|
self.groundFlag.setPos(3.0, 4.0, 0.0)
|
|
groundSquare = BuildGeometry.addSquareGeom(self.squareNode, self.sizeX, self.sizeZ, color=Vec4(0.4, 0.4, 0.4, 0.5))
|
|
self.centerZ = (self.minZ + self.maxZ) * 0.5
|
|
self.squareNode.setZ((self.minZ + self.maxZ) * 0.5)
|
|
self.squareNode.setP(-90)
|
|
groundCircle.setDepthWrite(False)
|
|
groundCircle.setDepthTest(True)
|
|
groundCircle.setBin('ground', 1)
|
|
groundSquare[0].setDepthWrite(False)
|
|
groundSquare[0].setDepthTest(False)
|
|
groundSquare[0].setBin('ground', 2)
|
|
self.squareNode.hide()
|
|
self.load()
|
|
|
|
def initCollisionGeom(self):
|
|
self.actSphere = CollisionSphere(0, 0, 0, 11.5)
|
|
self.actSphereNode = CollisionNode('gridgame-%s-%s' % (self.level.getLevelId(), self.entId))
|
|
self.actSphereNode.addSolid(self.actSphere)
|
|
self.actSphereNodePath = self.attachNewNode(self.actSphereNode)
|
|
self.actSphereNode.setCollideMask(ToontownGlobals.WallBitmask)
|
|
self.actSphere.setTangible(0)
|
|
self.enterEvent = 'enter' + self.actSphereNode.getName()
|
|
self.accept(self.enterEvent, self.__handleToonEnter)
|
|
|
|
def __handleToonEnter(self, collEntry):
|
|
self.sendUpdate('requestJoin', [])
|
|
|
|
def __setCamera(self):
|
|
camHeight = base.localAvatar.getClampedAvatarHeight()
|
|
heightScaleFactor = camHeight * 0.3333333333
|
|
defLookAt = Point3(0.0, 1.5, camHeight)
|
|
cameraPoint = Point3(0.0, -16.0, 16.0)
|
|
base.localAvatar.stopUpdateSmartCamera()
|
|
base.localAvatar.stopUpdateSmartCamera()
|
|
base.localAvatar.stopUpdateSmartCamera()
|
|
basePos = self.frame.getPos(render)
|
|
modPos = Point3(basePos[0] + 0.0, basePos[1] + 12.0, basePos[2] + 12.0)
|
|
camera.setPos(0, 0, 0)
|
|
camera.setH(0)
|
|
camera.setP(-70)
|
|
camera.reparentTo(self.focusPoint)
|
|
base.camLens.setMinFov(60/(4./3.))
|
|
self.focusPoint.setPos(0, 12, 27)
|
|
self.focusPoint.setH(180)
|
|
|
|
def acceptJoin(self, time, timeStamp, avIds):
|
|
self.timeStart = timeStamp
|
|
timePassed = globalClockDelta.localElapsedTime(self.timeStart)
|
|
timeleft = time - timePassed
|
|
self.timeTotal = time
|
|
if localAvatar.doId in avIds and localAvatar.doId not in self.joinedToons:
|
|
self.__startGame()
|
|
base.cr.playGame.getPlace().fsm.request('stopped')
|
|
self.sendUpdate('requestBoard', [0])
|
|
if not self.hasEntered:
|
|
self.level.countryClub.showInfoText(TTLocalizer.BustACogInstruction)
|
|
self.hasEntered = 1
|
|
for avId in self.joinedToons:
|
|
if avId not in avIds:
|
|
self.joinedToons.remove(avId)
|
|
self.removeToonHeadPanel(avId)
|
|
toon = base.cr.doId2do.get(avId)
|
|
if toon:
|
|
toon.startSmooth()
|
|
|
|
for avId in avIds:
|
|
if avId and avId not in self.joinedToons:
|
|
if avId not in self.everJoinedToons:
|
|
self.everJoinedToons.append(avId)
|
|
self.joinedToons.append(avId)
|
|
index = self.everJoinedToons.index(avId)
|
|
if index > 3:
|
|
print 'ERROR! green game has had more than 4 players, we are about to crash\n %s' % self.everJoinedToons
|
|
print 'Joining Toon is %s index is %s' % (avId, index)
|
|
toon = base.cr.doId2do.get(avId)
|
|
selfPos = self.getPos(render)
|
|
offset = self.toonPoints[index]
|
|
if index > 3:
|
|
print 'odd... we should have crashed by now'
|
|
standPoint = render.getRelativePoint(self, offset)
|
|
if toon:
|
|
toon.stopSmooth()
|
|
self.addToonHeadPanel(toon)
|
|
toon.setAnimState('run', 1.0)
|
|
animFunc = Func(toon.setAnimState, 'neutral', 1.0)
|
|
track = Sequence(LerpPosInterval(toon, 0.75, standPoint), LerpHprInterval(toon, 0.25, Point3(180, 0, 0)), animFunc, Func(self.clearToonTrack, avId), name=toon.uniqueName('gggEnter'), autoPause=1)
|
|
track.delayDelete = DelayDelete.DelayDelete(toon, 'GolfGreenGame.acceptJoin')
|
|
self.storeToonTrack(avId, track)
|
|
track.start()
|
|
|
|
def signalDone(self, success):
|
|
self.finished = 1
|
|
self.soundDone.play()
|
|
self.__leaveGame()
|
|
self.__removeGame()
|
|
self.scoreBoard.hide()
|
|
self.cleanupTimer()
|
|
if success:
|
|
self.level.countryClub.showInfoText(TTLocalizer.BustACogSuccess)
|
|
else:
|
|
self.level.countryClub.showInfoText(TTLocalizer.BustACogFailure)
|
|
|
|
def boardCleared(self, avId):
|
|
self.doFail()
|
|
|
|
def setTimerStart(self, time, timeStamp):
|
|
if self.timer == None:
|
|
self.timeStart = timeStamp
|
|
timePassed = globalClockDelta.localElapsedTime(self.timeStart)
|
|
timeleft = time - timePassed
|
|
self.timeTotal = time
|
|
self.cleanupTimer()
|
|
self.timer = ToontownTimer.ToontownTimer()
|
|
self.timer.posBelowTopRightCorner()
|
|
self.timer.setTime(timeleft)
|
|
self.timer.countdown(timeleft, self.timerExpired)
|
|
return
|
|
|
|
def cleanupTimer(self):
|
|
if self.timer:
|
|
self.timer.stop()
|
|
self.timer.destroy()
|
|
self.timer = None
|
|
return
|
|
|
|
def timerExpired(self):
|
|
self.cleanupTimer()
|
|
|
|
def useTime(self, time = None):
|
|
if time != None:
|
|
self.timeLeft = time
|
|
if self.timerTask != None:
|
|
taskMgr.remove(self.timerTaskName)
|
|
if time != None and time > 0.0 and self.isActive:
|
|
self.timerTask = taskMgr.doMethodLater(1.0, self.gameCountDown, self.timerTaskName)
|
|
self.scoreLabel['text'] = TTLocalizer.GolfGreenGameScoreString % (self.boardsLeft, int(self.timeLeft))
|
|
return
|
|
|
|
def gameCountDown(self, task):
|
|
self.timeLeft = self.timeTotal - globalClockDelta.localElapsedTime(self.timeStart)
|
|
return task.done
|
|
|
|
def scoreData(self, total = 2, closed = 1, scoreList = 'hello world'):
|
|
self.boardsLeft = total - closed
|
|
for panelIndex in self.toonPanels:
|
|
panel = self.toonPanels[panelIndex]
|
|
panel.extraData['text'] = TTLocalizer.GolfGreenGamePlayerScore % 0
|
|
|
|
for entryIndex in xrange(len(scoreList)):
|
|
entry = scoreList[entryIndex]
|
|
if entry[0] in self.toonPanels:
|
|
panel = self.toonPanels[entry[0]]
|
|
panel.extraData['text'] = TTLocalizer.GolfGreenGamePlayerScore % entry[1]
|
|
|
|
self.scoreLabel['text'] = TTLocalizer.GolfGreenGameScoreString % self.boardsLeft
|
|
|
|
def informGag(self, track, level):
|
|
self.bonusBoard.show()
|
|
self.bonusBoard['text'] = TTLocalizer.GolfGreenGameBonusGag % TTLocalizer.BattleGlobalAvPropStringsSingular[track][level]
|
|
iconName = ToontownBattleGlobals.AvPropsNew[track][level]
|
|
icon = self.invModel.find('**/%s' % iconName)
|
|
self.bonusBoard['image'] = icon
|
|
self.bonusBoard['image_scale'] = (1.0, 1, 1.0)
|
|
taskMgr.doMethodLater(4.0, self.hideBonusBoard, 'hide bonus')
|
|
|
|
def helpOthers(self, avId):
|
|
if not avId == localAvatar.doId and self.running:
|
|
self.giftId = 7
|
|
toonName = ''
|
|
toon = base.cr.doId2do[avId]
|
|
if toon:
|
|
toonName = toon.getName()
|
|
self.bonusBoard['text'] = TTLocalizer.GolfGreenGameGotHelp % toonName
|
|
imageBall = loader.loadModel('phase_12/models/bossbotHQ/bust_a_cog_ball_fire')
|
|
imageBall.setHpr(0, 90, 0)
|
|
self.bonusBoard['image'] = imageBall
|
|
self.bonusBoard['image_scale'] = 0.13
|
|
self.bonusBoard.show()
|
|
taskMgr.doMethodLater(4.0, self.hideBonusBoard, 'hide bonus')
|
|
|
|
def hideBonusBoard(self, task):
|
|
if self.bonusBoard:
|
|
if not self.bonusBoard.isEmpty():
|
|
self.bonusBoard.hide()
|
|
|
|
def storeToonTrack(self, avId, track):
|
|
self.clearToonTrack(avId)
|
|
self.__toonTracks[avId] = track
|
|
|
|
def clearToonTrack(self, avId):
|
|
oldTrack = self.__toonTracks.get(avId)
|
|
if oldTrack:
|
|
oldTrack.pause()
|
|
if self.__toonTracks.get(avId):
|
|
DelayDelete.cleanupDelayDeletes(self.__toonTracks[avId])
|
|
del self.__toonTracks[avId]
|
|
|
|
def clearToonTracks(self):
|
|
keyList = []
|
|
for key in self.__toonTracks:
|
|
keyList.append(key)
|
|
|
|
for key in keyList:
|
|
if key in self.__toonTracks:
|
|
self.clearToonTrack(key)
|