class MonsterBlood(DirectObject): def __init__(self): self.value = 100 self.lifeBar = DirectWaitBar(text="Monster", text_fg=(1, 1, 1, 1), text_pos=(1.2, -0.18, 0), text_align=TextNode.ARight, value=self.value, barColor=(0, 1, 0.25, 1), barRelief=DGG.RAISED, barBorderWidth=(0.03, 0.03), borderWidth=(0.01, 0.01), relief=DGG.RIDGE, frameColor=(0.8, 0.05, 0.10, 1), frameSize=(0, 1.2, 0, -0.1), pos=(0.2, 0, base.a2dTop - 0.15)) self.lifeBar.setTransparency(1) self.hide() def show(self): self.lifeBar["value"] = self.value self.lifeBar.show() def hide(self): self.lifeBar.hide() def setLifeBarValue(self, newValue): self.lifeBar["value"] = newValue
class Hud(DirectObject): def __init__(self, framework): super(Hud, self).__init__() self.f = framework self.player = DirectWaitBar( text="Player", text_fg=(1, 1, 1, 1), text_pos=(-1.2, -0.15, 0), text_align=TextNode.ALeft, text_scale=0.075, value=100, barColor=(0, 1, 0.25, 1), barRelief=DGG.FLAT, barBorderWidth=(0.03, 0.03), borderWidth=(0.01, 0.01), relief=DGG.FLAT, frameColor=(0.8, 0.05, 0.10, 1), frameSize=(-1.2, 0, 0, -0.05), pos=(-0.2, 0, self.f.a2dTop - 0.10)) self.player.set_transparency(1) self.bot = DirectWaitBar( text="Enemy", text_fg=(1, 1, 1, 1), text_pos=(1.2, -0.15, 0), text_align=TextNode.ARight, text_scale=0.075, value=100, barColor=(0, 1, 0.25, 1), barRelief=DGG.FLAT, barBorderWidth=(0.03, 0.03), borderWidth=(0.01, 0.01), relief=DGG.FLAT, frameColor=(0.8, 0.05, 0.10, 1), frameSize=(0, 1.2, 0, -0.05), pos=(0.2, 0, self.f.a2dTop - 0.10)) self.bot.set_transparency(1) self.accept("hud_set_hp", self.set_hp) self.hide() def show(self): self.bot.show() self.player.show() def hide(self): self.bot.hide() self.player.hide() def set_hp(self, uid, value): if uid == "enemy": self.bot["value"] = value elif uid == "player": self.player["value"] = value
class Hud(DirectObject): def __init__(self): self.lifeBar1 = DirectWaitBar( text = "Player1", text_fg = (1,1,1,1), text_pos = (-1.2, -0.18, 0), text_align = TextNode.ALeft, value = 100, barColor = (0, 1, 0.25, 1), barRelief = DGG.RAISED, barBorderWidth = (0.03, 0.03), borderWidth = (0.01, 0.01), relief = DGG.RIDGE, frameColor = (0.8,0.05,0.10,1), frameSize = (-1.2, 0, -0.1, 0), pos = (-0.2,0,base.a2dTop-0.15)) self.lifeBar1.setTransparency(1) self.lifeBar2 = DirectWaitBar( text = "Player2", text_fg = (1,1,1,1), text_pos = (1.2, -0.18, 0), text_align = TextNode.ARight, value = 100, barColor = (0, 1, 0.25, 1), barRelief = DGG.RAISED, barBorderWidth = (0.03, 0.03), borderWidth = (0.01, 0.01), relief = DGG.RIDGE, frameColor = (0.8,0.05,0.10,1), frameSize = (0, 1.2, -0.1, 0), pos = (0.2,0,base.a2dTop-0.15)) self.lifeBar2.setTransparency(1) self.accept("hud_setLifeBarValue", self.setLifeBarValue) self.hide() def show(self): self.lifeBar1["value"] = 100 self.lifeBar2["value"] = 100 self.lifeBar1.show() self.lifeBar2.show() def hide(self): self.lifeBar1.hide() self.lifeBar2.hide() def setLifeBarValue(self, barNr, newValue): if barNr == 0: self.lifeBar1["value"] = newValue elif barNr == 1: self.lifeBar2["value"] = newValue
class ControlPointBar(DirectWaitBar): def __init__(self, barColor=(255,0,0,1), pos=(1.0,0,0.9)): self.bar = DirectWaitBar(pos = pos, barColor = barColor, text="", value=0, range=30, frameSize=(-0.3,0.3,0,0.03), frameColor=(0,0,255,1)) def setValue(self, value): self.bar['value'] = float(value) def hide(self): self.bar.hide() def show(self): self.bar.show()
class ResourceBar(DirectWaitBar): def __init__(self, barColor=(200,180,0,1), pos=(0,0,0.9)): self.bar = DirectWaitBar(pos = pos, barColor = barColor, text="", value=70, range=100, frameSize=(-0.3,0.3,0,0.03), frameColor=(0,0,0,1)) def setValue(self, value): self.bar['value'] = float(value) def hide(self): self.bar.hide() def show(self): self.bar.show()
class Bar(DirectObject.DirectObject): def __init__( self): self.bar = DirectWaitBar(text = "Loading...", value = 0, pos = (0,.4,.4)) self.bar.hide() def incBar(self, arg): self.bar['value'] += arg #text = str(bar['value']) #textObject.setText(text) def show(self): self.bar.show() def hide(self): self.bar.hide()
class ControlPointBar(DirectWaitBar): def __init__(self, barColor=(255, 0, 0, 1), pos=(1.0, 0, 0.9)): self.bar = DirectWaitBar(pos=pos, barColor=barColor, text="", value=0, range=30, frameSize=(-0.3, 0.3, 0, 0.03), frameColor=(0, 0, 255, 1)) def setValue(self, value): self.bar['value'] = float(value) def hide(self): self.bar.hide() def show(self): self.bar.show()
class ResourceBar(DirectWaitBar): def __init__(self, barColor=(200, 180, 0, 1), pos=(0, 0, 0.9)): self.bar = DirectWaitBar(pos=pos, barColor=barColor, text="", value=70, range=100, frameSize=(-0.3, 0.3, 0, 0.03), frameColor=(0, 0, 0, 1)) def setValue(self, value): self.bar['value'] = float(value) def hide(self): self.bar.hide() def show(self): self.bar.show()
class Hud(DirectObject): def __init__(self): self.lifeBar = DirectWaitBar(value=100, barColor=(0, 1, 0.20, 1), barRelief=DGG.RAISED, relief=DGG.RIDGE, frameColor=(0.8, 0.05, 0.10, 1), frameSize=(-1.2, 0, 0, -0.1), pos=(-0.2, 0, base.a2dTop)) self.lifeBar.setTransparency(1) self.font = loader.loadFont( str(MAINDIR) + '/assets/fonts/allerdisplay.ttf') self.score_text = OnscreenText(text="Score:", pos=(-1.6, 0.93), scale=0.05, fg=(1, 1, 1, 1), align=TextNode.ACenter, font=self.font, mayChange=False) self.score = OnscreenText(text="0", pos=(-1.6, 0.83), scale=0.07, fg=(1, 1, 1, 1), align=TextNode.ACenter, font=self.font, mayChange=True) self.accept("hud_setLifeBarValue", self.setLifeBarValue) self.hide() def show(self): self.lifeBar["value"] = 100 self.lifeBar.show() def hide(self): self.lifeBar.hide() def setScore(self, score): self.score.setText(str(score)) def setLifeBarValue(self, newValue): self.lifeBar["value"] = newValue
class BossBlood(DirectObject): def __init__(self): self.value = 100 frameTex = loader.loadTexture("assets/gui/blood.jpg") barTex = loader.loadTexture("assets/gui/btn_click.png") self.lifeBar = DirectWaitBar( text="Boss", text_fg=(1, 1, 1, 1), text_pos=(1.0, 0.07, 0), text_align=TextNode.ARight, value=self.value, #0, 1, 0.25, 1 0.8,0.05,0.10,1 #barTexture = "assets/gui/btn_click.png", barColor=(0.8, 0.05, 0.10, 1), frameTexture=frameTex, barTexture=barTex, barRelief=DGG.RIDGE, barBorderWidth=(0.01, 0.01), borderWidth=(0.01, 0.01), relief=DGG.SUNKEN, frameSize=(0, 3.2, 0, 0.05), pos=(base.a2dLeft, 0, base.a2dBottom)) self.lifeBar.setTransparency(1) self.hide() def show(self): self.lifeBar["value"] = self.value self.lifeBar.show() def hide(self): self.lifeBar.hide() def setLifeBarValue(self, newValue, name='BOSS'): self.value = newValue self.lifeBar["value"] = self.value * 100 / self.maxVal self.lifeBar["text"] = str(self.value) + "/" + str( self.maxVal) + ' BOSS' def setLifeBarMaxValue(self, newValue, name='BOSS'): self.maxVal = newValue self.lifeBar["text"] = str(self.value) + "/" + str( self.maxVal) + ' BOSS' self.lifeBar["value"] = self.value * 100 / self.maxVal
class HeroBlood(DirectObject): """docstring for Blood""" def __init__(self): self.value = 100 self.maxVal = 100 #text text_pos value frameSize pos frameTex = loader.loadTexture("assets/gui/blood.jpg") barTex = loader.loadTexture("assets/gui/btn_click.png") self.lifeBar = DirectWaitBar(text=str(self.value), text_fg=(1, 1, 1, 0.6), text_pos=(0.8, 1.92, 0), text_align=TextNode.ALeft, value=self.value, barColor=(0, 0.95, 0.25, 1), frameTexture=frameTex, barTexture=barTex, barRelief=DGG.RIDGE, barBorderWidth=(0.01, 0.01), borderWidth=(0.01, 0.01), relief=DGG.SUNKEN, frameSize=(0.25, 0.8, 1.92, 1.97), pos=(base.a2dLeft, 0, base.a2dBottom)) self.lifeBar.setTransparency(1) self.hide() def show(self): self.lifeBar.show() def hide(self): self.lifeBar.hide() def setLifeBarValue(self, newValue, name='Player'): self.value = newValue self.lifeBar["text"] = str(self.value) + "/" + str( self.maxVal) + ' ' + name self.lifeBar["value"] = self.value * 100 / self.maxVal def setLifeBarMaxValue(self, newValue, name='Player'): self.maxVal = newValue self.lifeBar["text"] = str(self.value) + "/" + str( self.maxVal) + ' ' + name self.lifeBar["value"] = self.value * 100 / self.maxVal
class ProgressBar(object): ''' ''' def __init__(self): ''' ''' self.__wait_bar = DirectWaitBar( text = "Carregando...", value = 0, pos = (0, 0, -.95), text_scale = 0.05, text_pos = (0, 0.025), frameSize = (-1.3, 1.3, 0, 0.08) ) self.hide() def finish(self): self.__wait_bar['barColor'] = (0, 1, 0, 1) self.__wait_bar.setBarColor() self.__wait_bar.finish() self.hide() def hide(self): self.__wait_bar.hide() def show(self): self.__wait_bar.show() def update(self, value): if value < 25: self.__wait_bar['barColor'] = (1, 0, 0, 1) elif value > 25 and value < 75: self.__wait_bar['barColor'] = (1, 1, 0, 1) elif value > 75: self.__wait_bar['barColor'] = (0, 1, 0, 1) self.__wait_bar.setBarColor() self.__wait_bar.update(value)
class ControlPointBar(DirectWaitBar): def __init__(self, barColor=(255,0,0,1), pos=(1.0,0,0.9)): self.bar = DirectWaitBar(pos = pos, barColor = barColor, text="", value=70, range=100, frameSize=(-0.3,0.3,0,0.03), frameColor=(0,0,255,1)) def setValue(self, value): self.bar['value'] = float(value) self.setPos((0,0,0)) def hide(self): self.bar.hide() # to make inherited setPos available for this object def show(self): self.bar.show() # to make inherited setPos available for this object def setPos(self, pos): self.bar.setPos(pos)
class ToonFPSGui: def __init__(self, base): self.base = base self.noAmmoLabel = None self.ammo_gui = None self.hp_meter = None self.crosshair = None self.stats_container = None self.stats_bg = None self.stats_lbl = None self.kills_lbl = None self.deaths_lbl = None self.points_lbl = None return def load(self): self.ammo_gui = loader.loadModel('phase_4/models/minigames/gun_ammo_gui.egg') self.ammo_gui.setScale(0.15) self.ammo_gui.setPos(0.38, 0, 0.1) self.hp_meter = DirectWaitBar(text=str(self.base.hp), text_roll=-90, text_scale=0.2, text_pos=(-0.025, 0), relief=DGG.RAISED, barColor=(1, 0, 0, 1), range=self.base.max_hp, value=self.base.hp, parent=base.a2dBottomRight, scale=0.4, pos=(-0.12, 0, 0.2), frameSize=(-0.4, 0.4, -0.2, 0.2)) self.hp_meter.setR(-90) self.hp_meter.hide() self.crosshair = getCrosshair() font = CIGlobals.getToonFont() box = DGG.getDefaultDialogGeom() if self.base.__class__.__name__ == 'GunGameToonFPS': self.stats_container = DirectFrame(parent=base.a2dTopLeft, pos=(0.3, 0.2, -0.185)) self.stats_bg = OnscreenImage(image=box, color=(1, 1, 0.75, 1), scale=(0.5, 0.3, 0.3), parent=self.stats_container) self.stats_lbl = OnscreenText(font=font, text='Stats', pos=(-0.01, 0.08, 0), parent=self.stats_container) self.kills_lbl = OnscreenText(font=font, text='Kills: ' + str(self.base.kills), pos=(-0.235, 0.025, 0), scale=0.055, parent=self.stats_container, align=TextNode.ALeft) self.deaths_lbl = OnscreenText(font=font, text='Deaths: ' + str(self.base.deaths), pos=(-0.235, -0.04, 0), scale=0.055, parent=self.stats_container, align=TextNode.ALeft) self.points_lbl = OnscreenText(font=font, text='Points: ' + str(self.base.points), pos=(-0.235, -0.105, 0), scale=0.055, parent=self.stats_container, align=TextNode.ALeft) self.stats_container.hide() del font del box def start(self): self.ammo_gui.reparentTo(base.a2dBottomLeft) self.crosshair.show() self.hp_meter.show() if self.base.__class__.__name__ == 'GunGameToonFPS': self.stats_container.show() def end(self): self.ammo_gui.reparentTo(hidden) if self.base.__class__.__name__ == 'GunGameToonFPS': self.stats_container.hide() self.crosshair.hide() self.hp_meter.hide() def cleanup(self): self.ammo_gui.removeNode() self.ammo_gui = None self.hp_meter.destroy() self.hp_meter = None self.crosshair.destroy() self.crosshair = None self.deleteNoAmmoLabel() self.deleteStatsGui() return def deleteStatsGui(self): if self.stats_container: self.stats_container.destroy() self.stats_container = None if self.stats_bg: self.stats_bg.destroy() self.stats_bg = None if self.stats_lbl: self.stats_lbl.destroy() self.stats_lbl = None if self.kills_lbl: self.kills_lbl.destroy() self.kills_lbl = None if self.deaths_lbl: self.deaths_lbl.destroy() self.deaths_lbl = None if self.points_lbl: self.points_lbl.destroy() self.points_lbl = None return def updateStats(self): self.kills_lbl['text'] = 'Kills: ' + str(self.base.kills) self.deaths_lbl['text'] = 'Deaths: ' + str(self.base.deaths) self.points_lbl['text'] = 'Points: ' + str(self.base.points) def deleteNoAmmoLabel(self): if self.noAmmoLabel: self.noAmmoLabel.destroy() self.noAmmoLabel = None return def adjustAmmoGui(self): self.ammo_gui.find('**/bar_' + str(self.base.ammo + 1)).hide() def adjustHpMeter(self): self.hp_meter['text'] = str(self.base.hp) self.hp_meter['value'] = self.base.hp if self.base.hp <= 40: self.hp_meter['barColor'] = (1, 0, 0, 1) else: self.hp_meter['barColor'] = (1, 1, 1, 1) def resetAmmo(self): for bar in self.ammo_gui.findAllMatches('**/bar_*'): bar.show() def notifyNoAmmo(self): self.deleteNoAmmoLabel() self.noAmmoLabel = DirectLabel(text='Press R to reload!', relief=None, text_scale=0.1, text_pos=(0, 0.5, 0), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1)) return
class QuestNote(DirectFrame): notify = directNotify.newCategory("QuestNote") spots = [(-0.45, 0, 0.3), (0.45, 0, 0.3), (0.45, 0, -0.25), (-0.45, 0, -0.25)] RewardTextPos = (0, -0.4) RewardTextScale = 0.06 ProgressTextScale = 0.07 ProgressBarPos = (0, 0, -0.19) ProgressTextPos = (0, -0.19) TaskInfoTextPos = (0, 0.05) NonHeadingTextScale = 0.08 HeadingTextPos = (0, 0.23) HeadingTextScale = 0.1 def __init__(self, index): DirectFrame.__init__(self, scale=0.5) stickergui = loader.loadModel( 'phase_3.5/models/gui/stickerbook_gui.bam') self['image'] = stickergui.find('**/paper_note') self['image_scale'] = (1.3, 1, 1) self.setPos(self.spots[index]) self.useProgressBar = False self.headingText = OnscreenText(parent=self, text="", font=CIGlobals.getToonFont(), pos=self.HeadingTextPos, scale=self.HeadingTextScale) self.taskInfoText = OnscreenText(parent=self, text="", font=CIGlobals.getToonFont(), pos=self.TaskInfoTextPos, scale=self.NonHeadingTextScale) self.progressText = OnscreenText(parent=self, text="", font=CIGlobals.getToonFont(), pos=self.ProgressTextPos, scale=self.ProgressTextScale) self.progressBar = DirectWaitBar( parent=self, relief=DGG.SUNKEN, frameSize=(-0.95, 0.95, -0.1, 0.12), borderWidth=(0.025, 0.025), scale=0.4, frameColor=(251.0 / 255, 252.0 / 255, 176.0 / 255, 1.0), barColor=(0.5, 0.7, 0.5, 1), text='0/0', text_font=CIGlobals.getToonFont(), text_scale=0.19, text_fg=(0.05, 0.14, 0.4, 1), text_align=TextNode.ACenter, text_pos=(0, -0.05), #-0.02 pos=self.ProgressBarPos) self.progressBar.hide() self.rewardText = OnscreenText(parent=self, text="", font=CIGlobals.getToonFont(), pos=self.RewardTextPos, scale=self.RewardTextScale, fg=(1, 0.1, 0.1, 1.0)) self.hide() def setHeading(self, text): self.headingText.setText(text) def setTaskInfo(self, text): self.taskInfoText.setText(text) def setProgress(self, text, range=0, value=0): if self.useProgressBar: self.progressBar.show() self.progressBar['text'] = text self.progressBar['range'] = range self.progressBar['value'] = value else: self.progressText['text'] = text def setReward(self, text): self.rewardText.setText(text) def setCompleted(self, value): if value: self.progressBar.hide() self['image_color'] = QuestGlobals.LIGHT_GREEN
class DistributedMazeGame(DistributedMinigame): notify = directNotify.newCategory('DistributedMazeGame') CAMERA_TASK = 'MazeGameCameraTask' UPDATE_SUITS_TASK = 'MazeGameUpdateSuitsTask' TREASURE_GRAB_EVENT_NAME = 'MazeTreasureGrabbed' def __init__(self, cr): DistributedMinigame.__init__(self, cr) self.gameFSM = ClassicFSM.ClassicFSM('DistributedMazeGame', [ State.State('off', self.enterOff, self.exitOff, ['play']), State.State('play', self.enterPlay, self.exitPlay, ['cleanup', 'showScores']), State.State('showScores', self.enterShowScores, self.exitShowScores, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, []) ], 'off', 'cleanup') self.addChildGameFSM(self.gameFSM) self.usesLookAround = 1 def getTitle(self): return TTLocalizer.MazeGameTitle def getInstructions(self): return TTLocalizer.MazeGameInstructions def getMaxDuration(self): return MazeGameGlobals.GAME_DURATION def __defineConstants(self): self.TOON_SPEED = 8.0 self.TOON_Z = 0 self.MinSuitSpeedRange = [0.8 * self.TOON_SPEED, 0.6 * self.TOON_SPEED] self.MaxSuitSpeedRange = [1.1 * self.TOON_SPEED, 2.0 * self.TOON_SPEED] self.FASTER_SUIT_CURVE = 1 self.SLOWER_SUIT_CURVE = self.getDifficulty() < 0.5 self.slowerSuitPeriods = { 2000: { 4: [128, 76], 8: [128, 99, 81, 68], 12: [128, 108, 93, 82, 74, 67], 16: [128, 112, 101, 91, 83, 76, 71, 66] }, 1000: { 4: [110, 69], 8: [110, 88, 73, 62], 12: [110, 95, 83, 74, 67, 61], 16: [110, 98, 89, 81, 75, 69, 64, 60] }, 5000: { 4: [96, 63], 8: [96, 79, 66, 57], 12: [96, 84, 75, 67, 61, 56], 16: [96, 87, 80, 73, 68, 63, 59, 55] }, 4000: { 4: [86, 58], 8: [86, 71, 61, 53], 12: [86, 76, 68, 62, 56, 52], 16: [86, 78, 72, 67, 62, 58, 54, 51] }, 3000: { 4: [78, 54], 8: [78, 65, 56, 49], 12: [78, 69, 62, 57, 52, 48], 16: [78, 71, 66, 61, 57, 54, 51, 48] }, 9000: { 4: [71, 50], 8: [71, 60, 52, 46], 12: [71, 64, 58, 53, 49, 45], 16: [71, 65, 61, 57, 53, 50, 47, 45] } } self.slowerSuitPeriodsCurve = { 2000: { 4: [128, 65], 8: [128, 78, 66, 64], 12: [128, 88, 73, 67, 64, 64], 16: [128, 94, 79, 71, 67, 65, 64, 64] }, 1000: { 4: [110, 59], 8: [110, 70, 60, 58], 12: [110, 78, 66, 61, 59, 58], 16: [110, 84, 72, 65, 61, 59, 58, 58] }, 5000: { 4: [96, 55], 8: [96, 64, 56, 54], 12: [96, 71, 61, 56, 54, 54], 16: [96, 76, 65, 59, 56, 55, 54, 54] }, 4000: { 4: [86, 51], 8: [86, 59, 52, 50], 12: [86, 65, 56, 52, 50, 50], 16: [86, 69, 60, 55, 52, 51, 50, 50] }, 3000: { 4: [78, 47], 8: [78, 55, 48, 47], 12: [78, 60, 52, 48, 47, 47], 16: [78, 63, 55, 51, 49, 47, 47, 47] }, 9000: { 4: [71, 44], 8: [71, 51, 45, 44], 12: [71, 55, 48, 45, 44, 44], 16: [71, 58, 51, 48, 45, 44, 44, 44] } } self.fasterSuitPeriods = { 2000: { 4: [54, 42], 8: [59, 52, 47, 42], 12: [61, 56, 52, 48, 45, 42], 16: [61, 58, 54, 51, 49, 46, 44, 42] }, 1000: { 4: [50, 40], 8: [55, 48, 44, 40], 12: [56, 52, 48, 45, 42, 40], 16: [56, 53, 50, 48, 45, 43, 41, 40] }, 5000: { 4: [47, 37], 8: [51, 45, 41, 37], 12: [52, 48, 45, 42, 39, 37], 16: [52, 49, 47, 44, 42, 40, 39, 37] }, 4000: { 4: [44, 35], 8: [47, 42, 38, 35], 12: [48, 45, 42, 39, 37, 35], 16: [49, 46, 44, 42, 40, 38, 37, 35] }, 3000: { 4: [41, 33], 8: [44, 40, 36, 33], 12: [45, 42, 39, 37, 35, 33], 16: [45, 43, 41, 39, 38, 36, 35, 33] }, 9000: { 4: [39, 32], 8: [41, 37, 34, 32], 12: [42, 40, 37, 35, 33, 32], 16: [43, 41, 39, 37, 35, 34, 33, 32] } } self.fasterSuitPeriodsCurve = { 2000: { 4: [62, 42], 8: [63, 61, 54, 42], 12: [63, 63, 61, 56, 50, 42], 16: [63, 63, 62, 60, 57, 53, 48, 42] }, 1000: { 4: [57, 40], 8: [58, 56, 50, 40], 12: [58, 58, 56, 52, 46, 40], 16: [58, 58, 57, 56, 53, 49, 45, 40] }, 5000: { 4: [53, 37], 8: [54, 52, 46, 37], 12: [54, 53, 52, 48, 43, 37], 16: [54, 54, 53, 51, 49, 46, 42, 37] }, 4000: { 4: [49, 35], 8: [50, 48, 43, 35], 12: [50, 49, 48, 45, 41, 35], 16: [50, 50, 49, 48, 46, 43, 39, 35] }, 3000: { 4: [46, 33], 8: [47, 45, 41, 33], 12: [47, 46, 45, 42, 38, 33], 16: [47, 46, 46, 45, 43, 40, 37, 33] }, 9000: { 4: [43, 32], 8: [44, 42, 38, 32], 12: [44, 43, 42, 40, 36, 32], 16: [44, 44, 43, 42, 40, 38, 35, 32] } } self.CELL_WIDTH = MazeData.CELL_WIDTH self.MAX_FRAME_MOVE = self.CELL_WIDTH / 2 startOffset = 3 self.startPosHTable = [[Point3(0, startOffset, self.TOON_Z), 0], [Point3(0, -startOffset, self.TOON_Z), 180], [Point3(startOffset, 0, self.TOON_Z), 270], [Point3(-startOffset, 0, self.TOON_Z), 90]] self.camOffset = Vec3(0, -19, 45) def load(self): self.notify.debug('load') DistributedMinigame.load(self) self.__defineConstants() mazeName = MazeGameGlobals.getMazeName(self.doId, self.numPlayers, MazeData.mazeNames) self.maze = Maze.Maze(mazeName) model = loader.loadModel('phase_3.5/models/props/mickeySZ') self.treasureModel = model.find('**/mickeySZ') model.removeNode() self.treasureModel.setScale(1.6) self.treasureModel.setP(-90) self.music = base.loader.loadMusic('phase_4/audio/bgm/MG_toontag.ogg') self.toonHitTracks = {} self.scorePanels = [] def unload(self): self.notify.debug('unload') DistributedMinigame.unload(self) del self.toonHitTracks self.maze.destroy() del self.maze self.treasureModel.removeNode() del self.treasureModel del self.music self.removeChildGameFSM(self.gameFSM) del self.gameFSM def onstage(self): self.notify.debug('onstage') DistributedMinigame.onstage(self) self.maze.onstage() self.randomNumGen.shuffle(self.startPosHTable) lt = base.localAvatar lt.reparentTo(render) lt.hideName() self.__placeToon(self.localAvId) lt.setAnimState('Happy', 1.0) lt.setSpeed(0, 0) self.camParent = render.attachNewNode('mazeGameCamParent') self.camParent.reparentTo(base.localAvatar) self.camParent.setPos(0, 0, 0) self.camParent.setHpr(render, 0, 0, 0) camera.reparentTo(self.camParent) camera.setPos(self.camOffset) self.__spawnCameraTask() self.toonRNGs = [] for i in range(self.numPlayers): self.toonRNGs.append(RandomNumGen.RandomNumGen(self.randomNumGen)) self.treasures = [] for i in range(self.maze.numTreasures): self.treasures.append( MazeTreasure.MazeTreasure(self.treasureModel, self.maze.treasurePosList[i], i, self.doId)) self.__loadSuits() for suit in self.suits: suit.onstage() self.sndTable = { 'hitBySuit': [None] * self.numPlayers, 'falling': [None] * self.numPlayers } for i in range(self.numPlayers): self.sndTable['hitBySuit'][i] = base.loader.loadSfx( 'phase_4/audio/sfx/MG_Tag_C.ogg') self.sndTable['falling'][i] = base.loader.loadSfx( 'phase_4/audio/sfx/MG_cannon_whizz.ogg') self.grabSounds = [] for i in range(5): self.grabSounds.append( base.loader.loadSfx('phase_4/audio/sfx/MG_maze_pickup.ogg')) self.grabSoundIndex = 0 for avId in self.avIdList: self.toonHitTracks[avId] = Wait(0.1) self.scores = [0] * self.numPlayers self.goalBar = DirectWaitBar(parent=render2d, relief=DGG.SUNKEN, frameSize=(-0.35, 0.35, -0.15, 0.15), borderWidth=(0.02, 0.02), scale=0.42, pos=(0.84, 0, 0.5 - 0.28 * self.numPlayers + 0.05), barColor=(0, 0.7, 0, 1)) self.goalBar.setBin('unsorted', 0) self.goalBar.hide() self.introTrack = self.getIntroTrack() self.introTrack.start() return def offstage(self): self.notify.debug('offstage') if self.introTrack.isPlaying(): self.introTrack.finish() del self.introTrack for avId in list(self.toonHitTracks.keys()): track = self.toonHitTracks[avId] if track.isPlaying(): track.finish() self.__killCameraTask() camera.wrtReparentTo(render) self.camParent.removeNode() del self.camParent for panel in self.scorePanels: panel.cleanup() self.scorePanels = [] self.goalBar.destroy() del self.goalBar base.setCellsAvailable(base.rightCells, 1) for suit in self.suits: suit.offstage() self.__unloadSuits() for treasure in self.treasures: treasure.destroy() del self.treasures del self.sndTable del self.grabSounds del self.toonRNGs self.maze.offstage() base.localAvatar.showName() DistributedMinigame.offstage(self) def __placeToon(self, avId): toon = self.getAvatar(avId) if self.numPlayers == 1: toon.setPos(0, 0, self.TOON_Z) toon.setHpr(180, 0, 0) else: posIndex = self.avIdList.index(avId) toon.setPos(self.startPosHTable[posIndex][0]) toon.setHpr(self.startPosHTable[posIndex][1], 0, 0) def setGameReady(self): if not self.hasLocalToon: return self.notify.debug('setGameReady') if DistributedMinigame.setGameReady(self): return for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: toon.reparentTo(render) self.__placeToon(avId) toon.setAnimState('Happy', 1.0) toon.startSmooth() toon.startLookAround() def setGameStart(self, timestamp): if not self.hasLocalToon: return self.notify.debug('setGameStart') DistributedMinigame.setGameStart(self, timestamp) if self.introTrack.isPlaying(): self.introTrack.finish() for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: toon.stopLookAround() self.gameFSM.request('play') def handleDisabledAvatar(self, avId): hitTrack = self.toonHitTracks[avId] if hitTrack.isPlaying(): hitTrack.finish() DistributedMinigame.handleDisabledAvatar(self, avId) def enterOff(self): self.notify.debug('enterOff') def exitOff(self): pass def enterPlay(self): self.notify.debug('enterPlay') for i in range(self.numPlayers): avId = self.avIdList[i] avName = self.getAvatarName(avId) scorePanel = MinigameAvatarScorePanel.MinigameAvatarScorePanel( avId, avName) scorePanel.setPos(1.12, 0.0, 0.5 - 0.28 * i) self.scorePanels.append(scorePanel) self.goalBar.show() self.goalBar['value'] = 0.0 base.setCellsAvailable(base.rightCells, 0) self.__spawnUpdateSuitsTask() orthoDrive = OrthoDrive( self.TOON_SPEED, maxFrameMove=self.MAX_FRAME_MOVE, customCollisionCallback=self.__doMazeCollisions, priority=1) self.orthoWalk = OrthoWalk(orthoDrive, broadcast=not self.isSinglePlayer()) self.orthoWalk.start() self.accept(MazeSuit.COLLISION_EVENT_NAME, self.__hitBySuit) self.accept(self.TREASURE_GRAB_EVENT_NAME, self.__treasureGrabbed) self.timer = ToontownTimer.ToontownTimer() self.timer.posInTopRightCorner() self.timer.setTime(MazeGameGlobals.GAME_DURATION) self.timer.countdown(MazeGameGlobals.GAME_DURATION, self.timerExpired) self.accept('resetClock', self.__resetClock) base.playMusic(self.music, looping=0, volume=0.8) def exitPlay(self): self.notify.debug('exitPlay') self.ignore('resetClock') self.ignore(MazeSuit.COLLISION_EVENT_NAME) self.ignore(self.TREASURE_GRAB_EVENT_NAME) self.orthoWalk.stop() self.orthoWalk.destroy() del self.orthoWalk self.__killUpdateSuitsTask() self.timer.stop() self.timer.destroy() del self.timer for avId in self.avIdList: toon = self.getAvatar(avId) if toon: toon.loop('neutral') def __resetClock(self, tOffset): self.notify.debug('resetClock') self.gameStartTime += tOffset self.timer.countdown(self.timer.currentTime + tOffset, self.timerExpired) def __treasureGrabbed(self, treasureNum): self.treasures[treasureNum].showGrab() self.grabSounds[self.grabSoundIndex].play() self.grabSoundIndex = (self.grabSoundIndex + 1) % len(self.grabSounds) self.sendUpdate('claimTreasure', [treasureNum]) def setTreasureGrabbed(self, avId, treasureNum): if not self.hasLocalToon: return if avId != self.localAvId: self.treasures[treasureNum].showGrab() i = self.avIdList.index(avId) self.scores[i] += 1 self.scorePanels[i].setScore(self.scores[i]) total = 0 for score in self.scores: total += score self.goalBar['value'] = 100.0 * (float(total) / float(self.maze.numTreasures)) def __hitBySuit(self, suitNum): self.notify.debug('hitBySuit') timestamp = globalClockDelta.localToNetworkTime( globalClock.getFrameTime()) self.sendUpdate('hitBySuit', [self.localAvId, timestamp]) self.__showToonHitBySuit(self.localAvId, timestamp) def hitBySuit(self, avId, timestamp): if not self.hasLocalToon: return if self.gameFSM.getCurrentState().getName() not in [ 'play', 'showScores' ]: self.notify.warning('ignoring msg: av %s hit by suit' % avId) return self.notify.debug('avatar ' + repr(avId) + ' hit by a suit') if avId != self.localAvId: self.__showToonHitBySuit(avId, timestamp) def __showToonHitBySuit(self, avId, timestamp): toon = self.getAvatar(avId) if toon == None: return rng = self.toonRNGs[self.avIdList.index(avId)] curPos = toon.getPos(render) oldTrack = self.toonHitTracks[avId] if oldTrack.isPlaying(): oldTrack.finish() toon.setPos(curPos) toon.setZ(self.TOON_Z) parentNode = render.attachNewNode('mazeFlyToonParent-' + repr(avId)) parentNode.setPos(toon.getPos()) toon.reparentTo(parentNode) toon.setPos(0, 0, 0) startPos = parentNode.getPos() dropShadow = toon.dropShadow.copyTo(parentNode) dropShadow.setScale(toon.dropShadow.getScale(render)) trajectory = Trajectory.Trajectory(0, Point3(0, 0, 0), Point3(0, 0, 50), gravMult=1.0) flyDur = trajectory.calcTimeOfImpactOnPlane(0.0) while 1: endTile = [ rng.randint(2, self.maze.width - 1), rng.randint(2, self.maze.height - 1) ] if self.maze.isWalkable(endTile[0], endTile[1]): break endWorldCoords = self.maze.tile2world(endTile[0], endTile[1]) endPos = Point3(endWorldCoords[0], endWorldCoords[1], startPos[2]) def flyFunc(t, trajectory, startPos=startPos, endPos=endPos, dur=flyDur, moveNode=parentNode, flyNode=toon): u = t / dur moveNode.setX(startPos[0] + u * (endPos[0] - startPos[0])) moveNode.setY(startPos[1] + u * (endPos[1] - startPos[1])) flyNode.setPos(trajectory.getPos(t)) flyTrack = Sequence(LerpFunctionInterval(flyFunc, fromData=0.0, toData=flyDur, duration=flyDur, extraArgs=[trajectory]), name=toon.uniqueName('hitBySuit-fly')) if avId != self.localAvId: cameraTrack = Sequence() else: self.camParent.reparentTo(parentNode) startCamPos = camera.getPos() destCamPos = camera.getPos() zenith = trajectory.getPos(flyDur / 2.0)[2] destCamPos.setZ(zenith * 1.3) destCamPos.setY(destCamPos[1] * 0.3) def camTask(task, zenith=zenith, flyNode=toon, startCamPos=startCamPos, camOffset=destCamPos - startCamPos): u = flyNode.getZ() / zenith camera.setPos(startCamPos + camOffset * u) camera.lookAt(toon) return Task.cont camTaskName = 'mazeToonFlyCam-' + repr(avId) taskMgr.add(camTask, camTaskName, priority=20) def cleanupCamTask(self=self, toon=toon, camTaskName=camTaskName, startCamPos=startCamPos): taskMgr.remove(camTaskName) self.camParent.reparentTo(toon) camera.setPos(startCamPos) camera.lookAt(toon) cameraTrack = Sequence(Wait(flyDur), Func(cleanupCamTask), name='hitBySuit-cameraLerp') geomNode = toon.getGeomNode() startHpr = geomNode.getHpr() destHpr = Point3(startHpr) hRot = rng.randrange(1, 8) if rng.choice([0, 1]): hRot = -hRot destHpr.setX(destHpr[0] + hRot * 360) spinHTrack = Sequence(LerpHprInterval(geomNode, flyDur, destHpr, startHpr=startHpr), Func(geomNode.setHpr, startHpr), name=toon.uniqueName('hitBySuit-spinH')) parent = geomNode.getParent() rotNode = parent.attachNewNode('rotNode') geomNode.reparentTo(rotNode) rotNode.setZ(toon.getHeight() / 2.0) oldGeomNodeZ = geomNode.getZ() geomNode.setZ(-toon.getHeight() / 2.0) startHpr = rotNode.getHpr() destHpr = Point3(startHpr) pRot = rng.randrange(1, 3) if rng.choice([0, 1]): pRot = -pRot destHpr.setY(destHpr[1] + pRot * 360) spinPTrack = Sequence(LerpHprInterval(rotNode, flyDur, destHpr, startHpr=startHpr), Func(rotNode.setHpr, startHpr), name=toon.uniqueName('hitBySuit-spinP')) i = self.avIdList.index(avId) soundTrack = Sequence(Func(base.playSfx, self.sndTable['hitBySuit'][i]), Wait(flyDur * (2.0 / 3.0)), SoundInterval(self.sndTable['falling'][i], duration=flyDur * (1.0 / 3.0)), name=toon.uniqueName('hitBySuit-soundTrack')) def preFunc(self=self, avId=avId, toon=toon, dropShadow=dropShadow): forwardSpeed = toon.forwardSpeed rotateSpeed = toon.rotateSpeed if avId == self.localAvId: self.orthoWalk.stop() else: toon.stopSmooth() if forwardSpeed or rotateSpeed: toon.setSpeed(forwardSpeed, rotateSpeed) toon.dropShadow.hide() def postFunc(self=self, avId=avId, oldGeomNodeZ=oldGeomNodeZ, dropShadow=dropShadow, parentNode=parentNode): if avId == self.localAvId: base.localAvatar.setPos(endPos) if hasattr(self, 'orthoWalk'): if self.gameFSM.getCurrentState().getName() == 'play': self.orthoWalk.start() dropShadow.removeNode() del dropShadow toon.dropShadow.show() geomNode = toon.getGeomNode() rotNode = geomNode.getParent() baseNode = rotNode.getParent() geomNode.reparentTo(baseNode) rotNode.removeNode() del rotNode geomNode.setZ(oldGeomNodeZ) toon.reparentTo(render) toon.setPos(endPos) parentNode.removeNode() del parentNode if avId != self.localAvId: toon.startSmooth() preFunc() hitTrack = Sequence(Parallel(flyTrack, cameraTrack, spinHTrack, spinPTrack, soundTrack), Func(postFunc), name=toon.uniqueName('hitBySuit')) self.toonHitTracks[avId] = hitTrack hitTrack.start(globalClockDelta.localElapsedTime(timestamp)) def allTreasuresTaken(self): if not self.hasLocalToon: return self.notify.debug('all treasures taken') if not MazeGameGlobals.ENDLESS_GAME: self.gameFSM.request('showScores') def timerExpired(self): self.notify.debug('local timer expired') if not MazeGameGlobals.ENDLESS_GAME: self.gameFSM.request('showScores') def __doMazeCollisions(self, oldPos, newPos): offset = newPos - oldPos WALL_OFFSET = 1.0 curX = oldPos[0] curY = oldPos[1] curTX, curTY = self.maze.world2tile(curX, curY) def calcFlushCoord(curTile, newTile, centerTile): EPSILON = 0.01 if newTile > curTile: return (newTile - centerTile) * self.CELL_WIDTH - EPSILON - WALL_OFFSET else: return (curTile - centerTile) * self.CELL_WIDTH + WALL_OFFSET offsetX = offset[0] offsetY = offset[1] WALL_OFFSET_X = WALL_OFFSET if offsetX < 0: WALL_OFFSET_X = -WALL_OFFSET_X WALL_OFFSET_Y = WALL_OFFSET if offsetY < 0: WALL_OFFSET_Y = -WALL_OFFSET_Y newX = curX + offsetX + WALL_OFFSET_X newY = curY newTX, newTY = self.maze.world2tile(newX, newY) if newTX != curTX: if self.maze.collisionTable[newTY][newTX]: offset.setX( calcFlushCoord(curTX, newTX, self.maze.originTX) - curX) newX = curX newY = curY + offsetY + WALL_OFFSET_Y newTX, newTY = self.maze.world2tile(newX, newY) if newTY != curTY: if self.maze.collisionTable[newTY][newTX]: offset.setY( calcFlushCoord(curTY, newTY, self.maze.originTY) - curY) offsetX = offset[0] offsetY = offset[1] newX = curX + offsetX + WALL_OFFSET_X newY = curY + offsetY + WALL_OFFSET_Y newTX, newTY = self.maze.world2tile(newX, newY) if self.maze.collisionTable[newTY][newTX]: cX = calcFlushCoord(curTX, newTX, self.maze.originTX) cY = calcFlushCoord(curTY, newTY, self.maze.originTY) if abs(cX - curX) < abs(cY - curY): offset.setX(cX - curX) else: offset.setY(cY - curY) return oldPos + offset def __spawnCameraTask(self): self.notify.debug('spawnCameraTask') camera.lookAt(base.localAvatar) taskMgr.remove(self.CAMERA_TASK) taskMgr.add(self.__cameraTask, self.CAMERA_TASK, priority=45) def __killCameraTask(self): self.notify.debug('killCameraTask') taskMgr.remove(self.CAMERA_TASK) def __cameraTask(self, task): self.camParent.setHpr(render, 0, 0, 0) return Task.cont def __loadSuits(self): self.notify.debug('loadSuits') self.suits = [] self.numSuits = 4 * self.numPlayers safeZone = self.getSafezoneId() slowerTable = self.slowerSuitPeriods if self.SLOWER_SUIT_CURVE: slowerTable = self.slowerSuitPeriodsCurve slowerPeriods = slowerTable[safeZone][self.numSuits] fasterTable = self.fasterSuitPeriods if self.FASTER_SUIT_CURVE: fasterTable = self.fasterSuitPeriodsCurve fasterPeriods = fasterTable[safeZone][self.numSuits] suitPeriods = slowerPeriods + fasterPeriods self.notify.debug('suit periods: ' + repr(suitPeriods)) self.randomNumGen.shuffle(suitPeriods) for i in range(self.numSuits): self.suits.append( MazeSuit(i, self.maze, self.randomNumGen, suitPeriods[i], self.getDifficulty())) def __unloadSuits(self): self.notify.debug('unloadSuits') for suit in self.suits: suit.destroy() del self.suits def __spawnUpdateSuitsTask(self): self.notify.debug('spawnUpdateSuitsTask') for suit in self.suits: suit.gameStart(self.gameStartTime) taskMgr.remove(self.UPDATE_SUITS_TASK) taskMgr.add(self.__updateSuitsTask, self.UPDATE_SUITS_TASK) def __killUpdateSuitsTask(self): self.notify.debug('killUpdateSuitsTask') taskMgr.remove(self.UPDATE_SUITS_TASK) for suit in self.suits: suit.gameEnd() def __updateSuitsTask(self, task): curT = globalClock.getFrameTime() - self.gameStartTime curTic = int(curT * float(MazeGameGlobals.SUIT_TIC_FREQ)) suitUpdates = [] for i in range(len(self.suits)): updateTics = self.suits[i].getThinkTimestampTics(curTic) suitUpdates.extend(list(zip(updateTics, [i] * len(updateTics)))) suitUpdates.sort(key=functools.cmp_to_key(lambda a, b: a[0] - b[0])) if len(suitUpdates) > 0: curTic = 0 for i in range(len(suitUpdates)): update = suitUpdates[i] tic = update[0] suitIndex = update[1] suit = self.suits[suitIndex] if tic > curTic: curTic = tic j = i + 1 while j < len(suitUpdates): if suitUpdates[j][0] > tic: break self.suits[suitUpdates[j][1]].prepareToThink() j += 1 unwalkables = [] for si in range(suitIndex): unwalkables.extend(self.suits[si].occupiedTiles) for si in range(suitIndex + 1, len(self.suits)): unwalkables.extend(self.suits[si].occupiedTiles) suit.think(curTic, curT, unwalkables) return Task.cont def enterShowScores(self): self.notify.debug('enterShowScores') lerpTrack = Parallel() lerpDur = 0.5 lerpTrack.append( Parallel( LerpPosInterval(self.goalBar, lerpDur, Point3(0, 0, -.6), blendType='easeInOut'), LerpScaleInterval(self.goalBar, lerpDur, Vec3(self.goalBar.getScale()) * 2.0, blendType='easeInOut'))) tY = 0.6 bY = -.05 lX = -.5 cX = 0 rX = 0.5 scorePanelLocs = (((cX, bY), ), ((lX, bY), (rX, bY)), ((cX, tY), (lX, bY), (rX, bY)), ((lX, tY), (rX, tY), (lX, bY), (rX, bY))) scorePanelLocs = scorePanelLocs[self.numPlayers - 1] for i in range(self.numPlayers): panel = self.scorePanels[i] pos = scorePanelLocs[i] lerpTrack.append( Parallel( LerpPosInterval(panel, lerpDur, Point3(pos[0], 0, pos[1]), blendType='easeInOut'), LerpScaleInterval(panel, lerpDur, Vec3(panel.getScale()) * 2.0, blendType='easeInOut'))) self.showScoreTrack = Parallel( lerpTrack, Sequence(Wait(MazeGameGlobals.SHOWSCORES_DURATION), Func(self.gameOver))) self.showScoreTrack.start() def exitShowScores(self): self.showScoreTrack.pause() del self.showScoreTrack def enterCleanup(self): self.notify.debug('enterCleanup') def exitCleanup(self): pass def getIntroTrack(self): self.__cameraTask(None) origCamParent = camera.getParent() origCamPos = camera.getPos() origCamHpr = camera.getHpr() iCamParent = base.localAvatar.attachNewNode('iCamParent') iCamParent.setH(180) camera.reparentTo(iCamParent) toonHeight = base.localAvatar.getHeight() camera.setPos(0, -15, toonHeight * 3) camera.lookAt(0, 0, toonHeight / 2.0) iCamParent.wrtReparentTo(origCamParent) waitDur = 5.0 lerpDur = 4.5 lerpTrack = Parallel() startHpr = iCamParent.getHpr() startHpr.setX(PythonUtil.reduceAngle(startHpr[0])) lerpTrack.append( LerpPosHprInterval(iCamParent, lerpDur, pos=Point3(0, 0, 0), hpr=Point3(0, 0, 0), startHpr=startHpr, name=self.uniqueName('introLerpParent'))) lerpTrack.append( LerpPosHprInterval(camera, lerpDur, pos=origCamPos, hpr=origCamHpr, blendType='easeInOut', name=self.uniqueName('introLerpCameraPos'))) base.localAvatar.startLookAround() def cleanup(origCamParent=origCamParent, origCamPos=origCamPos, origCamHpr=origCamHpr, iCamParent=iCamParent): camera.reparentTo(origCamParent) camera.setPos(origCamPos) camera.setHpr(origCamHpr) iCamParent.removeNode() del iCamParent base.localAvatar.stopLookAround() return Sequence(Wait(waitDur), lerpTrack, Func(cleanup))
class PartyCogActivityGui(DirectObject): notify = directNotify.newCategory('PartyCogActivityGui') def __init__(self): DirectObject.__init__(self) self._piePowerMeter = None self._victoryBalanceBar = None self._scoreLabel = None self._cogTracker = None self._piePowerTitle = None self._victoryBalanceTitle = None self._scoreTitle = None self._spamWarning = None self._spamWarningIvalName = 'PartyCogActivityGui-SpamWarning' def load(self): self._initPiePowerMeter() self._initScore() self._initCogTracker() self._initSpamWarning() self._initControlGui() self._initVictoryBalanceBar() def unload(self): if self._cogTracker is not None: self._cogTracker.destory() self._cogTracker = None if self._piePowerMeter is not None: self._piePowerMeter.destroy() self._piePowerMeter = None if self._piePowerTitle is not None: self._piePowerTitle.destroy() self._piePowerTitle = None if self._scoreLabel is not None: self._scoreLabel.destroy() self._scoreLabel = None if self._scoreTitle is not None: self._scoreTitle.destroy() self._scoreTitle = None taskMgr.remove(self._spamWarningIvalName) if self._spamWarning: self._spamWarning.destroy() self._spamWarning = None if hasattr(self, '_attackKeys'): self._attackKeys.detachNode() del self._attackKeys if hasattr(self, '_moveKeys'): self._moveKeys.detachNode() del self._moveKeys if self._victoryBalanceBar: self._victoryBalanceBar.detachNode() self._victoryBalanceBar = None if self._victoryBalanceBarOrange: self._victoryBalanceBarOrange.detachNode() self._victoryBalanceBarOrange = None if self._victoryBalanceBarPie: self._victoryBalanceBarPie.detachNode() self._victoryBalanceBarPie = None if self._victoryBalanceBarArrow: self._victoryBalanceBarArrow.detachNode() self._victoryBalanceBarArrow = None def _initVictoryBalanceBar(self): h = PartyGlobals.CogActivityPowerMeterHeight / 2.0 w = PartyGlobals.CogActivityPowerMeterWidth / 2.0 victoryBalanceBar = loader.loadModel('phase_13/models/parties/tt_m_gui_pty_pieToss_balanceBar') self._victoryBalanceBar = victoryBalanceBar.find('**/*tt_t_gui_pty_pieToss_balanceBarBG') self._victoryBalanceBar.reparentTo(aspect2d) self._victoryBalanceBar.setBin('fixed', 0) self._victoryBalanceBar.setPos(PartyGlobals.CogActivityVictoryBarPos) self._victoryBalanceBar.setScale(1) self._victoryBalanceBarOrange = victoryBalanceBar.find('**/*tt_t_gui_pty_pieToss_balanceBarOrange') self._victoryBalanceBarOrange.reparentTo(self._victoryBalanceBar) self._victoryBalanceBarOrange.setBin('fixed', 1) self._victoryBalanceBarOrange.setPos(PartyGlobals.CogActivityVictoryBarOrangePos) self._victoryBalanceBarOrange.setScale(PartyGlobals.CogActivityBarStartScale, 1.0, 1.0) self._victoryBalanceBarPie = victoryBalanceBar.find('**/*tt_t_gui_pty_pieToss_balanceBarPie') self._victoryBalanceBarPie.reparentTo(self._victoryBalanceBar) self._victoryBalanceBarPie.setBin('fixed', 2) self._victoryBalanceBarPie.setX(PartyGlobals.CogActivityVictoryBarPiePos[0]) self._victoryBalanceBarPie.setY(PartyGlobals.CogActivityVictoryBarPiePos[1]) self._victoryBalanceBarPie.setZ(PartyGlobals.CogActivityVictoryBarPiePos[2]) self._victoryBalanceBarPie.setScale(PartyGlobals.CogActivityBarPieScale) self._victoryBalanceBarArrow = victoryBalanceBar.find('**/*tt_t_gui_pty_pieToss_balanceArrow') self._victoryBalanceBarArrow.reparentTo(self._victoryBalanceBarPie) self._victoryBalanceBarArrow.setBin('fixed', 2) self._victoryBalanceBarArrow.setPos(PartyGlobals.CogActivityVictoryBarArrow) self._victoryBalanceBarArrow.setScale(1 / PartyGlobals.CogActivityBarPieScale) def _initControlGui(self): self._attackIvalName = 'PartyCogActivityGui-attackKeys' self._moveIvalName = 'PartyCogActivityGui-moveKeys' pieTossControls = loader.loadModel('phase_13/models/parties/tt_m_gui_pty_pieToss_controls') self._attackKeys = pieTossControls.find('**/*control*') self._moveKeys = pieTossControls.find('**/*arrow*') self._moveKeys.reparentTo(aspect2d) self._moveKeys.setPos(1.0, 0.0, -0.435) self._moveKeys.setScale(0.15) self._attackKeys.reparentTo(aspect2d) self._attackKeys.setPos(0.85, 0.0, -0.45) self._attackKeys.setScale(0.15) self._moveKeys.hide() self._attackKeys.hide() def _initPiePowerMeter(self): h = PartyGlobals.CogActivityPowerMeterHeight / 2.0 w = PartyGlobals.CogActivityPowerMeterWidth / 2.0 self._piePowerMeter = DirectWaitBar(frameSize=(-h, h, -w, w), relief=DGG.GROOVE, frameColor=(0.9, 0.9, 0.9, 1.0), borderWidth=(0.01, 0.01), barColor=PartyGlobals.CogActivityColors[0], pos=PartyGlobals.CogActivityPowerMeterPos, hpr=(0.0, 0.0, -90.0)) self._piePowerMeter.setBin('fixed', 0) self._piePowerTitle = OnscreenText(text=TTLocalizer.PartyCogGuiPowerLabel, pos=PartyGlobals.CogActivityPowerMeterTextPos, scale=0.05, fg=(1.0, 1.0, 1.0, 1.0), align=TextNode.ACenter) self._piePowerTitle.setBin('fixed', 0) self._piePowerMeter.hide() self._piePowerTitle.hide() def _initScore(self): self._scoreLabel = OnscreenText(text='0', pos=PartyGlobals.CogActivityScorePos, scale=PartyGlobals.TugOfWarTextWordScale, fg=(1.0, 1.0, 0.0, 1.0), align=TextNode.ARight, font=ToontownGlobals.getSignFont(), mayChange=True) self._scoreTitle = OnscreenText(text=TTLocalizer.PartyCogGuiScoreLabel, pos=PartyGlobals.CogActivityScoreTitle, scale=0.05, fg=(1.0, 1.0, 1.0, 1.0), align=TextNode.ARight) self._scoreLabel.hide() self._scoreTitle.hide() def _initCogTracker(self): self._cogTracker = PartyCogTrackerGui() def _initSpamWarning(self): self._spamWarning = OnscreenText(text=TTLocalizer.PartyCogGuiSpamWarning, scale=0.15, fg=(1.0, 1.0, 0, 1.0), shadow=(0, 0, 0, 0.62), mayChange=False, pos=(0, 0.33)) self._spamWarning.hide() def showScore(self): self._scoreLabel.show() self._scoreTitle.show() def hideScore(self): self._scoreLabel.hide() self._scoreTitle.hide() def setScore(self, score = 0): self._scoreLabel['text'] = str(score) def resetPiePowerMeter(self): self._piePowerMeter['value'] = 0 def showPiePowerMeter(self): self._piePowerMeter.show() self._piePowerTitle.show() def hidePiePowerMeter(self): self._piePowerMeter.hide() self._piePowerTitle.hide() def updatePiePowerMeter(self, value): self._piePowerMeter['value'] = value def getPiePowerMeterValue(self): return self._piePowerMeter['value'] def hideSpamWarning(self): taskMgr.remove(self._spamWarningIvalName) if self._spamWarning: self._spamWarning.hide() def showSpamWarning(self): if self._spamWarning.isHidden(): self._spamWarning.show() taskMgr.remove(self._spamWarningIvalName) Sequence(ToontownIntervals.getPulseLargerIval(self._spamWarning, ''), Wait(PartyGlobals.CogActivitySpamWarningShowTime), Func(self.hideSpamWarning), name=self._spamWarningIvalName, autoFinish=1).start() def hide(self): self.hidePiePowerMeter() self.hideScore() self.hideSpamWarning() self.hideControls() def disableToontownHUD(self): base.localAvatar.hideName() base.localAvatar.laffMeter.hide() base.setCellsAvailable(base.bottomCells + [base.rightCells[1]], False) def enableToontownHUD(self): base.localAvatar.showName() base.localAvatar.laffMeter.show() base.setCellsAvailable(base.bottomCells + [base.rightCells[1]], True) def setTeam(self, team): self.team = team if team == 0: self._cogTracker.frame.setR(180) self._piePowerMeter['barColor'] = PartyGlobals.CogActivityColors[team] def startTrackingCogs(self, cogs): self.cogs = cogs taskMgr.add(self.trackCogs, 'trackCogs') def trackCogs(self, task): if self.cogs is None: return self._updateVictoryBar() for i, cog in enumerate(self.cogs): self._cogTracker.updateCog(i, cog, self.team) return task.cont def _updateVictoryBar(self): if not (hasattr(self, '_victoryBalanceBar') and self._victoryBalanceBar): return netDistance = 0 for cog in self.cogs: netDistance = netDistance + cog.targetDistance teamDistance = netDistance / 6.0 self._victoryBalanceBarOrange.setScale(PartyGlobals.CogActivityBarStartScale + teamDistance * 10 * PartyGlobals.CogActivityBarUnitScale, 1.0, 1.0) self._victoryBalanceBarPie.setX(PartyGlobals.CogActivityVictoryBarPiePos[0] + teamDistance * 10 * PartyGlobals.CogActivityBarPieUnitMove) self._victoryBalanceBarPie.setY(PartyGlobals.CogActivityVictoryBarPiePos[1]) self._victoryBalanceBarPie.setZ(PartyGlobals.CogActivityVictoryBarPiePos[2]) if teamDistance > 0.0: self._victoryBalanceBarArrow.setColor(PartyGlobals.CogActivityColors[1]) elif teamDistance < 0.0: self._victoryBalanceBarArrow.setColor(PartyGlobals.CogActivityColors[0]) else: self._victoryBalanceBarArrow.setColor(VBase4(1.0, 1.0, 1.0, 1.0)) def stopTrackingCogs(self): taskMgr.remove('trackCogs') def showAttackControls(self): if self._attackKeys.isHidden(): self._attackKeys.show() taskMgr.remove(self._attackIvalName) Sequence(ToontownIntervals.getPulseLargerIval(self._attackKeys, '', scale=0.15), Wait(PartyGlobals.CogActivityControlsShowTime), Func(self.hideAttackControls), name=self._attackIvalName, autoFinish=1).start() def showMoveControls(self): if self._moveKeys.isHidden() and not self._attackKeys.isHidden(): self._moveKeys.show() taskMgr.remove(self._moveIvalName) Sequence(ToontownIntervals.getPulseLargerIval(self._moveKeys, '', scale=0.15), Wait(PartyGlobals.CogActivityControlsShowTime), Func(self.hideMoveControls), name=self._moveIvalName, autoFinish=1).start() def hideAttackControls(self): taskMgr.remove(self._attackIvalName) if hasattr(self, '_attackKeys') and self._attackKeys: self._attackKeys.hide() def hideMoveControls(self): taskMgr.remove(self._moveIvalName) if hasattr(self, '_moveKeys') and self._moveKeys: self._moveKeys.hide() def hideControls(self): self.hideMoveControls() self.hideAttackControls()
class CharacterGUI: """Widget with the selected character info.""" def __init__(self): self.char = None # the chosen character self.rest_list_shown = False self._status_lab = None self._rest_buttons = {} self._char_desc_wids = [] self._char_desc_shown = False self._fr = DirectFrame( parent=base.a2dTopLeft, # noqa: F821 frameSize=(-0.31, 0.31, -0.1, 0.115), pos=(0.31, 0, -1.9), frameTexture=GUI_PIC + "metal1.png", state=DGG.NORMAL, ) self._fr.setTransparency(TransparencyAttrib.MAlpha) # a "?" button to open a detailed description of the character self._char_desc_but = DirectButton( parent=self._fr, pos=(0.27, 0, 0.0675), command=self._show_char_desc, clickSound=base.main_menu.click_snd, # noqa: F821 **ABOUT_BUT_PARAMS, ) DirectLabel( # Name: parent=self._fr, text=base.labels.CHARACTERS[0], # noqa: F821 text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=RUST_COL, pos=(-0.22, 0, 0.07), ) self._char_name = DirectLabel( parent=self._fr, text="", frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=SILVER_COL, pos=(-0.09, 0, 0.069), ) self._traits = DirectLabel( parent=self._fr, text="", frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=(0.028, 0.028), text_fg=SILVER_COL, text_font=base.main_font, # noqa: F821 pos=(0, 0, 0.025), ) DirectLabel( # Class: parent=self._fr, text=base.labels.CHARACTERS[1], # noqa: F821 text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=RUST_COL, pos=(0.05, 0, 0.07), ) self._char_class = DirectLabel( parent=self._fr, text="", frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=SILVER_COL, pos=(0.17, 0, 0.068), ) DirectLabel( # Health parent=self._fr, text=base.labels.CHARACTERS[2], # noqa: F821 text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=RUST_COL, pos=(-0.22, 0, -0.015), ) self._char_health = DirectWaitBar( parent=self._fr, frameSize=(-0.17, 0.17, -0.002, 0.002), frameColor=(0.35, 0.35, 0.35, 1), value=0, barColor=(0.85, 0.2, 0.28, 1), pos=(0.07, 0, -0.008), ) DirectLabel( # Energy parent=self._fr, text=base.labels.CHARACTERS[3], # noqa: F821 text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=RUST_COL, pos=(-0.216, 0, -0.06), ) self._char_energy = DirectWaitBar( parent=self._fr, frameSize=(-0.17, 0.17, -0.002, 0.002), frameColor=(0.35, 0.35, 0.35, 1), value=0, barColor=(0.46, 0.61, 0.53, 1), pos=(0.07, 0, -0.053), ) self._tip = OnscreenText( parent=base.render2d, # noqa: F821 text="", font=base.main_font, # noqa: F821 scale=(0.021, 0.027), fg=SILVER_COL, bg=(0, 0, 0, 0.4), ) self._tip.hide() self._disease = DirectFrame( parent=self._fr, frameSize=(-0.02, 0.02, -0.02, 0.02), pos=(0.27, 0, -0.008), frameTexture=GUI_PIC + "disease.png", ) self._disease.setTransparency(TransparencyAttrib.MAlpha) self.clear_char_info() def _update_char_info(self, task): """Track the chosen character parameters in the GUI.""" if self.char.is_dead: self.clear_char_info() return task.done self._char_health["value"] = self.char.health self._char_energy["value"] = self.char.energy self._traits["text"] = ", ".join(self.char.traits) if self.char.is_diseased: self._disease.show() else: self._disease.hide() if self._char_desc_shown: self._update_desc() return task.again def _update_desc(self): """Update the chosen character description.""" to_del = [] for wid in self._char_desc_wids: if wid["text"] not in ( # Traits base.labels.CHARACTERS[5], # noqa: F821 # Status base.labels.CHARACTERS[4], # noqa: F821 "", ): wid.destroy() to_del.append(wid) for del_wid in to_del: self._char_desc_wids.remove(del_wid) self._fill_status(self._fill_traits(0.64)) def _fill_traits(self, shift): """Fill the chosen character traits. Args: shift (float): Z-coor for the new widgets. Returns: float: Z-coor including the new widgets shift. """ shift -= 0.03 for trait in self.char.traits + self.char.disabled_traits: self._char_desc_wids.append( DirectLabel( parent=self._fr, text=trait, frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_font=base.main_font, # noqa: F821 text_fg=SILVER_COL if trait in self.char.traits else (0.3, 0.3, 0.3, 1), pos=(0, 0, shift), ) ) self._char_desc_wids.append( DirectLabel( parent=self._fr, text=base.labels.TRAIT_DESC[trait], # noqa: F821 text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.029, text_fg=SILVER_COL if trait in self.char.traits else (0.3, 0.3, 0.3, 1), pos=(0, 0, shift - 0.045), ) ) shift -= 0.1 return shift def _fill_status(self, shift): """Fill the chosen character status. Args: shift (float): Z-coor for the new widgets. """ shift -= 0.04 for status in self.char.statuses: self._char_desc_wids.append( DirectLabel( parent=self._fr, text=status, text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.029, text_fg=SILVER_COL, pos=(0, 0, shift), ) ) shift -= 0.045 def _show_char_desc(self): """Show detailed character description. Includes description of every character's trait and their current status. """ if self._char_desc_shown: self._fr["frameSize"] = (-0.31, 0.31, -0.1, 0.115) clear_wids(self._char_desc_wids) self._status_lab = None else: shift = 0.7 self._fr["frameSize"] = (-0.31, 0.31, -0.1, shift) shift -= 0.06 self._char_desc_wids.append( DirectLabel( parent=self._fr, # Traits text=base.labels.CHARACTERS[5], # noqa: F821, text_font=base.main_font, # noqa: F821, frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=RUST_COL, pos=(-0.225, 0, shift), ) ) if self.char.id in base.team.chars.keys(): # noqa: F821 traits_but = DirectButton( parent=self._fr, text="", frameSize=(-0.025, 0.025, -0.025, 0.025), frameTexture=GUI_PIC + "like.png", relief="flat", pos=(0.265, 0, shift + 0.013), command=base.traits_gui.show, # noqa: F821 ) traits_but.bind( DGG.ENTER, self._highlight_traits_but, extraArgs=[traits_but] ) traits_but.bind( DGG.EXIT, self._dehighlight_traits_but, extraArgs=[traits_but] ) self._char_desc_wids.append(traits_but) shift = self._fill_traits(shift) self._status_lab = DirectLabel( # Status parent=self._fr, # Status text=base.labels.CHARACTERS[4], # noqa: F821 text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=RUST_COL, pos=(-0.221, 0, shift), ) self._char_desc_wids.append(self._status_lab) self._fill_status(shift) self._char_desc_shown = not self._char_desc_shown def _dehighlight_traits_but(self, button, _): """Dehighlight traits tweaking button. Args: button (panda3d.gui.DirectGui.DirectButton): Button to dehighlight. """ button["frameTexture"] = GUI_PIC + "like.png" def _highlight_traits_but(self, button, _): """Hightlight traits tweaking button. Args: button (panda3d.gui.DirectGui.DirectButton): Button to highlight. """ button["frameTexture"] = GUI_PIC + "hover_like.png" def clear_char_info(self, clear_resting=True): """Clear the character GUI. Args: clear_resting (bool): Optional. A flag indicating if the list of the resting characters should also be closed. """ for wid in ( self._char_name, self._char_class, self._char_health, self._char_energy, self._traits, self._char_desc_but, self._disease, ): wid.hide() if self._char_desc_shown: self._show_char_desc() taskMgr.remove("track_char_info") # noqa: F821 self.char = None if clear_resting: for but in self._rest_buttons.values(): but.destroy() self.rest_list_shown = False def destroy_char_button(self, char_id): """Hide the given character button from the resting characters list. Args: char_id (str): Character id. """ if char_id in self._rest_buttons.keys(): self._rest_buttons[char_id].destroy() self._rest_buttons.pop(char_id) def hide_tip(self): """Hide the tooltip.""" self._tip.hide() def show_char_info(self, char): """Show the given character status. Args: char (units.crew.character.Character): The chosen character object. """ self._char_name["text"] = char.name self._char_class["text"] = char.class_.capitalize() self._traits["text"] = ", ".join(char.traits) self._char_health["range"] = char.class_data["health"] self._char_health["value"] = char.health self._char_energy["value"] = char.energy if char.is_diseased: self._disease.show() else: self._disease.hide() self.char = char self._char_name.show() self._char_class.show() self._char_health.show() self._char_energy.show() self._traits.show() self._char_desc_but.show() if self._char_desc_shown: self._show_char_desc() self._show_char_desc() taskMgr.doMethodLater( # noqa: F821 0.5, self._update_char_info, "track_char_info" ) def show_tooltip(self, text): """Show tooltip with the given text. Args: text (str): Text to show in the tooltip. """ if not base.mouseWatcherNode.hasMouse(): # noqa: F821 return if self.rest_list_shown and text == "Rest zone": return self._tip.setText(text) self._tip.setX(base.mouseWatcherNode.getMouseX()) # noqa: F821 self._tip.setY(base.mouseWatcherNode.getMouseY()) # noqa: F821 self._tip.show() def show_resting_chars(self, part): """Show a list of the characters resting in this part. Args: part (Train.RestPart): Rest part of the Train. """ if self.rest_list_shown: return self._tip.hide() self.rest_list_shown = True x = base.mouseWatcherNode.getMouseX() # noqa: F821 z = base.mouseWatcherNode.getMouseY() # noqa: F821 self._rest_buttons["title"] = DirectButton( pos=(x, 0, z), text=base.labels.TIPS[0], # noqa: F821 text_fg=RUST_COL, text_font=base.main_font, # noqa: F821 frameColor=(0, 0, 0, 0.6), scale=(0.04, 0, 0.03), ) shift = -0.039 for char in part.chars: if char.is_dead: continue self._rest_buttons[char.id] = DirectButton( pos=(x, 0, z + shift), text=char.name, text_fg=SILVER_COL, frameColor=(0, 0, 0, 0.6), command=base.common_ctrl.choose_char, # noqa: F821 extraArgs=[char.id], scale=(0.04, 0, 0.03), ) shift -= 0.033 def move_status_label(self, place): """Move the status label widget. Args: place (int): Place to shift the widget. """ if self._status_lab is not None: self._status_lab.setZ(self._status_lab.getZ() + place / 10) def update_resting_chars(self, part): """Update the list of the resting characters. Args: part (train.part.TrainPart): Rest train part. """ for key, but in self._rest_buttons.items(): if key != "title": but.destroy() self._rest_buttons[key] = None x, _, z = self._rest_buttons["title"].getPos() shift = -0.039 for char in part.chars: self._rest_buttons[char.id] = DirectButton( pos=(x, 0, z + shift), text=char.name, text_fg=SILVER_COL, frameColor=(0, 0, 0, 0.6), command=base.common_ctrl.choose_char, # noqa: F821 extraArgs=[char.id], scale=(0.04, 0, 0.03), ) shift -= 0.033
class DistributedMazeGame(DistributedMinigame): notify = directNotify.newCategory('DistributedMazeGame') CAMERA_TASK = 'MazeGameCameraTask' UPDATE_SUITS_TASK = 'MazeGameUpdateSuitsTask' TREASURE_GRAB_EVENT_NAME = 'MazeTreasureGrabbed' def __init__(self, cr): DistributedMinigame.__init__(self, cr) self.gameFSM = ClassicFSM.ClassicFSM('DistributedMazeGame', [State.State('off', self.enterOff, self.exitOff, ['play']), State.State('play', self.enterPlay, self.exitPlay, ['cleanup', 'showScores']), State.State('showScores', self.enterShowScores, self.exitShowScores, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup') self.addChildGameFSM(self.gameFSM) self.usesLookAround = 1 def getTitle(self): return TTLocalizer.MazeGameTitle def getInstructions(self): return TTLocalizer.MazeGameInstructions def getMaxDuration(self): return MazeGameGlobals.GAME_DURATION def __defineConstants(self): self.TOON_SPEED = 8.0 self.TOON_Z = 0 self.MinSuitSpeedRange = [0.8 * self.TOON_SPEED, 0.6 * self.TOON_SPEED] self.MaxSuitSpeedRange = [1.1 * self.TOON_SPEED, 2.0 * self.TOON_SPEED] self.FASTER_SUIT_CURVE = 1 self.SLOWER_SUIT_CURVE = self.getDifficulty() < 0.5 self.slowerSuitPeriods = {2000: {4: [128, 76], 8: [128, 99, 81, 68], 12: [128, 108, 93, 82, 74, 67], 16: [128, 112, 101, 91, 83, 76, 71, 66]}, 1000: {4: [110, 69], 8: [110, 88, 73, 62], 12: [110, 95, 83, 74, 67, 61], 16: [110, 98, 89, 81, 75, 69, 64, 60]}, 5000: {4: [96, 63], 8: [96, 79, 66, 57], 12: [96, 84, 75, 67, 61, 56], 16: [96, 87, 80, 73, 68, 63, 59, 55]}, 4000: {4: [86, 58], 8: [86, 71, 61, 53], 12: [86, 76, 68, 62, 56, 52], 16: [86, 78, 72, 67, 62, 58, 54, 51]}, 3000: {4: [78, 54], 8: [78, 65, 56, 49], 12: [78, 69, 62, 57, 52, 48], 16: [78, 71, 66, 61, 57, 54, 51, 48]}, 9000: {4: [71, 50], 8: [71, 60, 52, 46], 12: [71, 64, 58, 53, 49, 45], 16: [71, 65, 61, 57, 53, 50, 47, 45]}} self.slowerSuitPeriodsCurve = {2000: {4: [128, 65], 8: [128, 78, 66, 64], 12: [128, 88, 73, 67, 64, 64], 16: [128, 94, 79, 71, 67, 65, 64, 64]}, 1000: {4: [110, 59], 8: [110, 70, 60, 58], 12: [110, 78, 66, 61, 59, 58], 16: [110, 84, 72, 65, 61, 59, 58, 58]}, 5000: {4: [96, 55], 8: [96, 64, 56, 54], 12: [96, 71, 61, 56, 54, 54], 16: [96, 76, 65, 59, 56, 55, 54, 54]}, 4000: {4: [86, 51], 8: [86, 59, 52, 50], 12: [86, 65, 56, 52, 50, 50], 16: [86, 69, 60, 55, 52, 51, 50, 50]}, 3000: {4: [78, 47], 8: [78, 55, 48, 47], 12: [78, 60, 52, 48, 47, 47], 16: [78, 63, 55, 51, 49, 47, 47, 47]}, 9000: {4: [71, 44], 8: [71, 51, 45, 44], 12: [71, 55, 48, 45, 44, 44], 16: [71, 58, 51, 48, 45, 44, 44, 44]}} self.fasterSuitPeriods = {2000: {4: [54, 42], 8: [59, 52, 47, 42], 12: [61, 56, 52, 48, 45, 42], 16: [61, 58, 54, 51, 49, 46, 44, 42]}, 1000: {4: [50, 40], 8: [55, 48, 44, 40], 12: [56, 52, 48, 45, 42, 40], 16: [56, 53, 50, 48, 45, 43, 41, 40]}, 5000: {4: [47, 37], 8: [51, 45, 41, 37], 12: [52, 48, 45, 42, 39, 37], 16: [52, 49, 47, 44, 42, 40, 39, 37]}, 4000: {4: [44, 35], 8: [47, 42, 38, 35], 12: [48, 45, 42, 39, 37, 35], 16: [49, 46, 44, 42, 40, 38, 37, 35]}, 3000: {4: [41, 33], 8: [44, 40, 36, 33], 12: [45, 42, 39, 37, 35, 33], 16: [45, 43, 41, 39, 38, 36, 35, 33]}, 9000: {4: [39, 32], 8: [41, 37, 34, 32], 12: [42, 40, 37, 35, 33, 32], 16: [43, 41, 39, 37, 35, 34, 33, 32]}} self.fasterSuitPeriodsCurve = {2000: {4: [62, 42], 8: [63, 61, 54, 42], 12: [63, 63, 61, 56, 50, 42], 16: [63, 63, 62, 60, 57, 53, 48, 42]}, 1000: {4: [57, 40], 8: [58, 56, 50, 40], 12: [58, 58, 56, 52, 46, 40], 16: [58, 58, 57, 56, 53, 49, 45, 40]}, 5000: {4: [53, 37], 8: [54, 52, 46, 37], 12: [54, 53, 52, 48, 43, 37], 16: [54, 54, 53, 51, 49, 46, 42, 37]}, 4000: {4: [49, 35], 8: [50, 48, 43, 35], 12: [50, 49, 48, 45, 41, 35], 16: [50, 50, 49, 48, 46, 43, 39, 35]}, 3000: {4: [46, 33], 8: [47, 45, 41, 33], 12: [47, 46, 45, 42, 38, 33], 16: [47, 46, 46, 45, 43, 40, 37, 33]}, 9000: {4: [43, 32], 8: [44, 42, 38, 32], 12: [44, 43, 42, 40, 36, 32], 16: [44, 44, 43, 42, 40, 38, 35, 32]}} self.CELL_WIDTH = MazeData.CELL_WIDTH self.MAX_FRAME_MOVE = self.CELL_WIDTH / 2 startOffset = 3 self.startPosHTable = [[Point3(0, startOffset, self.TOON_Z), 0], [Point3(0, -startOffset, self.TOON_Z), 180], [Point3(startOffset, 0, self.TOON_Z), 270], [Point3(-startOffset, 0, self.TOON_Z), 90]] self.camOffset = Vec3(0, -19, 45) def load(self): self.notify.debug('load') DistributedMinigame.load(self) self.__defineConstants() mazeName = MazeGameGlobals.getMazeName(self.doId, self.numPlayers, MazeData.mazeNames) self.maze = Maze.Maze(mazeName) model = loader.loadModel('phase_3.5/models/props/mickeySZ') self.treasureModel = model.find('**/mickeySZ') model.removeNode() self.treasureModel.setScale(1.6) self.treasureModel.setP(-90) self.music = base.loadMusic('phase_4/audio/bgm/MG_toontag.ogg') self.toonHitTracks = {} self.scorePanels = [] def unload(self): self.notify.debug('unload') DistributedMinigame.unload(self) del self.toonHitTracks self.maze.destroy() del self.maze self.treasureModel.removeNode() del self.treasureModel del self.music self.removeChildGameFSM(self.gameFSM) del self.gameFSM def onstage(self): self.notify.debug('onstage') DistributedMinigame.onstage(self) self.maze.onstage() self.randomNumGen.shuffle(self.startPosHTable) lt = base.localAvatar lt.reparentTo(render) lt.hideName() self.__placeToon(self.localAvId) lt.setAnimState('Happy', 1.0) lt.setSpeed(0, 0) self.camParent = render.attachNewNode('mazeGameCamParent') self.camParent.reparentTo(base.localAvatar) self.camParent.setPos(0, 0, 0) self.camParent.setHpr(render, 0, 0, 0) camera.reparentTo(self.camParent) camera.setPos(self.camOffset) self.__spawnCameraTask() self.toonRNGs = [] for i in xrange(self.numPlayers): self.toonRNGs.append(RandomNumGen.RandomNumGen(self.randomNumGen)) self.treasures = [] for i in xrange(self.maze.numTreasures): self.treasures.append(MazeTreasure.MazeTreasure(self.treasureModel, self.maze.treasurePosList[i], i, self.doId)) self.__loadSuits() for suit in self.suits: suit.onstage() self.sndTable = {'hitBySuit': [None] * self.numPlayers, 'falling': [None] * self.numPlayers} for i in xrange(self.numPlayers): self.sndTable['hitBySuit'][i] = base.loadSfx('phase_4/audio/sfx/MG_Tag_C.ogg') self.sndTable['falling'][i] = base.loadSfx('phase_4/audio/sfx/MG_cannon_whizz.ogg') self.grabSounds = [] for i in xrange(5): self.grabSounds.append(base.loadSfx('phase_4/audio/sfx/MG_maze_pickup.ogg')) self.grabSoundIndex = 0 for avId in self.avIdList: self.toonHitTracks[avId] = Wait(0.1) self.scores = [0] * self.numPlayers self.goalBar = DirectWaitBar(parent=render2d, relief=DGG.SUNKEN, frameSize=(-0.35, 0.35, -0.15, 0.15), borderWidth=(0.02, 0.02), scale=0.42, pos=(0.84, 0, 0.5 - 0.28 * self.numPlayers + 0.05), barColor=(0, 0.7, 0, 1)) self.goalBar.setBin('unsorted', 0) self.goalBar.hide() self.introTrack = self.getIntroTrack() self.introTrack.start() return def offstage(self): self.notify.debug('offstage') if self.introTrack.isPlaying(): self.introTrack.finish() del self.introTrack for avId in self.toonHitTracks.keys(): track = self.toonHitTracks[avId] if track.isPlaying(): track.finish() self.__killCameraTask() camera.wrtReparentTo(render) self.camParent.removeNode() del self.camParent for panel in self.scorePanels: panel.cleanup() self.scorePanels = [] self.goalBar.destroy() del self.goalBar base.setCellsAvailable(base.rightCells, 1) for suit in self.suits: suit.offstage() self.__unloadSuits() for treasure in self.treasures: treasure.destroy() del self.treasures del self.sndTable del self.grabSounds del self.toonRNGs self.maze.offstage() base.localAvatar.showName() DistributedMinigame.offstage(self) def __placeToon(self, avId): toon = self.getAvatar(avId) if self.numPlayers == 1: toon.setPos(0, 0, self.TOON_Z) toon.setHpr(180, 0, 0) else: posIndex = self.avIdList.index(avId) toon.setPos(self.startPosHTable[posIndex][0]) toon.setHpr(self.startPosHTable[posIndex][1], 0, 0) def setGameReady(self): if not self.hasLocalToon: return self.notify.debug('setGameReady') if DistributedMinigame.setGameReady(self): return for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: toon.reparentTo(render) self.__placeToon(avId) toon.setAnimState('Happy', 1.0) toon.startSmooth() toon.startLookAround() def setGameStart(self, timestamp): if not self.hasLocalToon: return self.notify.debug('setGameStart') DistributedMinigame.setGameStart(self, timestamp) if self.introTrack.isPlaying(): self.introTrack.finish() for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: toon.stopLookAround() self.gameFSM.request('play') def handleDisabledAvatar(self, avId): hitTrack = self.toonHitTracks[avId] if hitTrack.isPlaying(): hitTrack.finish() DistributedMinigame.handleDisabledAvatar(self, avId) def enterOff(self): self.notify.debug('enterOff') def exitOff(self): pass def enterPlay(self): self.notify.debug('enterPlay') for i in xrange(self.numPlayers): avId = self.avIdList[i] avName = self.getAvatarName(avId) scorePanel = MinigameAvatarScorePanel.MinigameAvatarScorePanel(avId, avName) scorePanel.reparentTo(base.a2dTopRight) scorePanel.setPos(-0.213, 0.0, -0.5 - 0.28 * i) self.scorePanels.append(scorePanel) self.goalBar.show() self.goalBar['value'] = 0.0 base.setCellsAvailable(base.rightCells, 0) self.__spawnUpdateSuitsTask() orthoDrive = OrthoDrive(self.TOON_SPEED, maxFrameMove=self.MAX_FRAME_MOVE, customCollisionCallback=self.__doMazeCollisions, priority=1) self.orthoWalk = OrthoWalk(orthoDrive, broadcast=not self.isSinglePlayer()) self.orthoWalk.start() self.accept(MazeSuit.COLLISION_EVENT_NAME, self.__hitBySuit) self.accept(self.TREASURE_GRAB_EVENT_NAME, self.__treasureGrabbed) self.timer = ToontownTimer.ToontownTimer() self.timer.posInTopRightCorner() self.timer.setTime(MazeGameGlobals.GAME_DURATION) self.timer.countdown(MazeGameGlobals.GAME_DURATION, self.timerExpired) self.accept('resetClock', self.__resetClock) base.playMusic(self.music, looping=0, volume=0.8) def exitPlay(self): self.notify.debug('exitPlay') self.ignore('resetClock') self.ignore(MazeSuit.COLLISION_EVENT_NAME) self.ignore(self.TREASURE_GRAB_EVENT_NAME) self.orthoWalk.stop() self.orthoWalk.destroy() del self.orthoWalk self.__killUpdateSuitsTask() self.timer.stop() self.timer.destroy() del self.timer for avId in self.avIdList: toon = self.getAvatar(avId) if toon: toon.loop('neutral') def __resetClock(self, tOffset): self.notify.debug('resetClock') self.gameStartTime += tOffset self.timer.countdown(self.timer.currentTime + tOffset, self.timerExpired) def __treasureGrabbed(self, treasureNum): self.treasures[treasureNum].showGrab() self.grabSounds[self.grabSoundIndex].play() self.grabSoundIndex = (self.grabSoundIndex + 1) % len(self.grabSounds) self.sendUpdate('claimTreasure', [treasureNum]) def setTreasureGrabbed(self, avId, treasureNum): if not self.hasLocalToon: return if avId != self.localAvId: self.treasures[treasureNum].showGrab() i = self.avIdList.index(avId) self.scores[i] += 1 self.scorePanels[i].setScore(self.scores[i]) total = 0 for score in self.scores: total += score self.goalBar['value'] = 100.0 * (float(total) / float(self.maze.numTreasures)) def __hitBySuit(self, suitNum): self.notify.debug('hitBySuit') timestamp = globalClockDelta.localToNetworkTime(globalClock.getFrameTime()) self.sendUpdate('hitBySuit', [self.localAvId, timestamp]) self.__showToonHitBySuit(self.localAvId, timestamp) def hitBySuit(self, avId, timestamp): if not self.hasLocalToon: return if self.gameFSM.getCurrentState().getName() not in ['play', 'showScores']: self.notify.warning('ignoring msg: av %s hit by suit' % avId) return self.notify.debug('avatar ' + `avId` + ' hit by a suit') if avId != self.localAvId: self.__showToonHitBySuit(avId, timestamp) def __showToonHitBySuit(self, avId, timestamp): toon = self.getAvatar(avId) if toon == None: return rng = self.toonRNGs[self.avIdList.index(avId)] curPos = toon.getPos(render) oldTrack = self.toonHitTracks[avId] if oldTrack.isPlaying(): oldTrack.finish() toon.setPos(curPos) toon.setZ(self.TOON_Z) parentNode = render.attachNewNode('mazeFlyToonParent-' + `avId`) parentNode.setPos(toon.getPos()) toon.reparentTo(parentNode) toon.setPos(0,0,0) startPos = parentNode.getPos() dropShadow = toon.dropShadow.copyTo(parentNode) dropShadow.setScale(toon.dropShadow.getScale(render)) trajectory = Trajectory.Trajectory( 0, Point3(0,0,0), Point3(0,0,50), gravMult=1.0) flyDur = trajectory.calcTimeOfImpactOnPlane(0.0) while 1: endTile = [rng.randint(2, self.maze.width-1), rng.randint(2, self.maze.height-1)] if self.maze.isWalkable(endTile[0], endTile[1]): break endWorldCoords = self.maze.tile2world(endTile[0], endTile[1]) endPos = Point3(endWorldCoords[0], endWorldCoords[1], startPos[2]) def flyFunc(t, trajectory, startPos = startPos, endPos = endPos, dur = flyDur, moveNode = parentNode, flyNode = toon): u = t/dur moveNode.setX(startPos[0] + u * (endPos[0]-startPos[0])) moveNode.setY(startPos[1] + u * (endPos[1]-startPos[1])) flyNode.setPos(trajectory.getPos(t)) flyTrack = Sequence( LerpFunctionInterval(flyFunc, fromData=0.0, toData=flyDur, duration=flyDur, extraArgs=[trajectory]), name=toon.uniqueName('hitBySuit-fly')) if avId != self.localAvId: cameraTrack = Sequence() else: self.camParent.reparentTo(parentNode) startCamPos = camera.getPos() destCamPos = camera.getPos() zenith = trajectory.getPos(flyDur/2.0)[2] destCamPos.setZ(zenith*1.3) destCamPos.setY(destCamPos[1]*0.3) def camTask(task, zenith = zenith, flyNode = toon, startCamPos = startCamPos, camOffset = destCamPos - startCamPos): u = flyNode.getZ()/zenith camera.setPos(startCamPos + camOffset*u) camera.lookAt(toon) return Task.cont camTaskName = 'mazeToonFlyCam-' + `avId` taskMgr.add(camTask, camTaskName, priority=20) def cleanupCamTask(self = self, toon = toon, camTaskName = camTaskName, startCamPos = startCamPos): taskMgr.remove(camTaskName) self.camParent.reparentTo(toon) camera.setPos(startCamPos) camera.lookAt(toon) cameraTrack = Sequence( Wait(flyDur), Func(cleanupCamTask), name='hitBySuit-cameraLerp') geomNode = toon.getGeomNode() startHpr = geomNode.getHpr() destHpr = Point3(startHpr) hRot = rng.randrange(1, 8) if rng.choice([0, 1]): hRot = -hRot destHpr.setX(destHpr[0] + hRot*360) spinHTrack = Sequence( LerpHprInterval(geomNode, flyDur, destHpr, startHpr=startHpr), Func(geomNode.setHpr, startHpr), name=toon.uniqueName('hitBySuit-spinH')) parent = geomNode.getParent() rotNode = parent.attachNewNode('rotNode') geomNode.reparentTo(rotNode) rotNode.setZ(toon.getHeight()/2.0) oldGeomNodeZ = geomNode.getZ() geomNode.setZ(-toon.getHeight()/2.0) startHpr = rotNode.getHpr() destHpr = Point3(startHpr) pRot = rng.randrange(1,3) if rng.choice([0, 1]): pRot = -pRot destHpr.setY(destHpr[1] + pRot*360) spinPTrack = Sequence( LerpHprInterval(rotNode, flyDur, destHpr, startHpr=startHpr), Func(rotNode.setHpr, startHpr), name=toon.uniqueName('hitBySuit-spinP')) i = self.avIdList.index(avId) soundTrack = Sequence( Func(base.playSfx, self.sndTable['hitBySuit'][i]), Wait(flyDur * (2.0/3.0)), SoundInterval(self.sndTable['falling'][i], duration=flyDur * (1.0/3.0)), name=toon.uniqueName('hitBySuit-soundTrack')) def preFunc(self = self, avId = avId, toon = toon, dropShadow = dropShadow): forwardSpeed = toon.forwardSpeed rotateSpeed = toon.rotateSpeed if avId == self.localAvId: self.orthoWalk.stop() else: toon.stopSmooth() if forwardSpeed or rotateSpeed: toon.setSpeed(forwardSpeed, rotateSpeed) toon.dropShadow.hide() def postFunc(self = self, avId = avId, oldGeomNodeZ = oldGeomNodeZ, dropShadow = dropShadow, parentNode = parentNode): if avId == self.localAvId: base.localAvatar.setPos(endPos) if hasattr(self, 'orthoWalk'): if self.gameFSM.getCurrentState().getName() == 'play': self.orthoWalk.start() dropShadow.removeNode() del dropShadow toon.dropShadow.show() geomNode = toon.getGeomNode() rotNode = geomNode.getParent() baseNode = rotNode.getParent() geomNode.reparentTo(baseNode) rotNode.removeNode() del rotNode geomNode.setZ(oldGeomNodeZ) toon.reparentTo(render) toon.setPos(endPos) parentNode.removeNode() del parentNode if avId != self.localAvId: toon.startSmooth() preFunc() hitTrack = Sequence(Parallel(flyTrack, cameraTrack, spinHTrack, spinPTrack, soundTrack), Func(postFunc), name=toon.uniqueName('hitBySuit')) self.toonHitTracks[avId] = hitTrack hitTrack.start(globalClockDelta.localElapsedTime(timestamp)) def allTreasuresTaken(self): if not self.hasLocalToon: return self.notify.debug('all treasures taken') if not MazeGameGlobals.ENDLESS_GAME: self.gameFSM.request('showScores') def timerExpired(self): self.notify.debug('local timer expired') if not MazeGameGlobals.ENDLESS_GAME: self.gameFSM.request('showScores') def __doMazeCollisions(self, oldPos, newPos): offset = newPos - oldPos WALL_OFFSET = 1.0 curX = oldPos[0] curY = oldPos[1] curTX, curTY = self.maze.world2tile(curX, curY) def calcFlushCoord(curTile, newTile, centerTile): EPSILON = 0.01 if newTile > curTile: return (newTile - centerTile) * self.CELL_WIDTH - EPSILON - WALL_OFFSET else: return (curTile - centerTile) * self.CELL_WIDTH + WALL_OFFSET offsetX = offset[0] offsetY = offset[1] WALL_OFFSET_X = WALL_OFFSET if offsetX < 0: WALL_OFFSET_X = -WALL_OFFSET_X WALL_OFFSET_Y = WALL_OFFSET if offsetY < 0: WALL_OFFSET_Y = -WALL_OFFSET_Y newX = curX + offsetX + WALL_OFFSET_X newY = curY newTX, newTY = self.maze.world2tile(newX, newY) if newTX != curTX: if self.maze.collisionTable[newTY][newTX]: offset.setX(calcFlushCoord(curTX, newTX, self.maze.originTX) - curX) newX = curX newY = curY + offsetY + WALL_OFFSET_Y newTX, newTY = self.maze.world2tile(newX, newY) if newTY != curTY: if self.maze.collisionTable[newTY][newTX]: offset.setY(calcFlushCoord(curTY, newTY, self.maze.originTY) - curY) offsetX = offset[0] offsetY = offset[1] newX = curX + offsetX + WALL_OFFSET_X newY = curY + offsetY + WALL_OFFSET_Y newTX, newTY = self.maze.world2tile(newX, newY) if self.maze.collisionTable[newTY][newTX]: cX = calcFlushCoord(curTX, newTX, self.maze.originTX) cY = calcFlushCoord(curTY, newTY, self.maze.originTY) if abs(cX - curX) < abs(cY - curY): offset.setX(cX - curX) else: offset.setY(cY - curY) return oldPos + offset def __spawnCameraTask(self): self.notify.debug('spawnCameraTask') camera.lookAt(base.localAvatar) taskMgr.remove(self.CAMERA_TASK) taskMgr.add(self.__cameraTask, self.CAMERA_TASK, priority=45) def __killCameraTask(self): self.notify.debug('killCameraTask') taskMgr.remove(self.CAMERA_TASK) def __cameraTask(self, task): self.camParent.setHpr(render, 0, 0, 0) return Task.cont def __loadSuits(self): self.notify.debug('loadSuits') self.suits = [] self.numSuits = 4 * self.numPlayers safeZone = self.getSafezoneId() slowerTable = self.slowerSuitPeriods if self.SLOWER_SUIT_CURVE: slowerTable = self.slowerSuitPeriodsCurve slowerPeriods = slowerTable[safeZone][self.numSuits] fasterTable = self.fasterSuitPeriods if self.FASTER_SUIT_CURVE: fasterTable = self.fasterSuitPeriodsCurve fasterPeriods = fasterTable[safeZone][self.numSuits] suitPeriods = slowerPeriods + fasterPeriods self.notify.debug('suit periods: ' + `suitPeriods`) self.randomNumGen.shuffle(suitPeriods) for i in xrange(self.numSuits): self.suits.append(MazeSuit(i, self.maze, self.randomNumGen, suitPeriods[i], self.getDifficulty())) def __unloadSuits(self): self.notify.debug('unloadSuits') for suit in self.suits: suit.destroy() self.suits = [] def __spawnUpdateSuitsTask(self): self.notify.debug('spawnUpdateSuitsTask') for suit in self.suits: suit.gameStart(self.gameStartTime) taskMgr.remove(self.UPDATE_SUITS_TASK) taskMgr.add(self.__updateSuitsTask, self.UPDATE_SUITS_TASK) def __killUpdateSuitsTask(self): self.notify.debug('killUpdateSuitsTask') taskMgr.remove(self.UPDATE_SUITS_TASK) for suit in self.suits: suit.gameEnd() def __updateSuitsTask(self, task): curT = globalClock.getFrameTime() - self.gameStartTime curTic = int(curT * float(MazeGameGlobals.SUIT_TIC_FREQ)) suitUpdates = [] for i in xrange(len(self.suits)): updateTics = self.suits[i].getThinkTimestampTics(curTic) suitUpdates.extend(zip(updateTics, [i] * len(updateTics))) suitUpdates.sort(lambda a, b: a[0] - b[0]) if len(suitUpdates) > 0: curTic = 0 for i in xrange(len(suitUpdates)): update = suitUpdates[i] tic = update[0] suitIndex = update[1] suit = self.suits[suitIndex] if tic > curTic: curTic = tic j = i + 1 while j < len(suitUpdates): if suitUpdates[j][0] > tic: break self.suits[suitUpdates[j][1]].prepareToThink() j += 1 unwalkables = [] for si in xrange(suitIndex): unwalkables.extend(self.suits[si].occupiedTiles) for si in xrange(suitIndex + 1, len(self.suits)): unwalkables.extend(self.suits[si].occupiedTiles) suit.think(curTic, curT, unwalkables) return Task.cont def enterShowScores(self): self.notify.debug('enterShowScores') lerpTrack = Parallel() lerpDur = 0.5 lerpTrack.append(Parallel(LerpPosInterval(self.goalBar, lerpDur, Point3(0, 0, -.6), blendType='easeInOut'), LerpScaleInterval(self.goalBar, lerpDur, Vec3(self.goalBar.getScale()) * 2.0, blendType='easeInOut'))) tY = 0.6 bY = -.05 lX = -.5 cX = 0 rX = 0.5 scorePanelLocs = (((cX, bY),), ((lX, bY), (rX, bY)), ((cX, tY), (lX, bY), (rX, bY)), ((lX, tY), (rX, tY), (lX, bY), (rX, bY))) scorePanelLocs = scorePanelLocs[self.numPlayers - 1] for i in xrange(self.numPlayers): panel = self.scorePanels[i] pos = scorePanelLocs[i] panel.wrtReparentTo(aspect2d) lerpTrack.append(Parallel(LerpPosInterval(panel, lerpDur, Point3(pos[0], 0, pos[1]), blendType='easeInOut'), LerpScaleInterval(panel, lerpDur, Vec3(panel.getScale()) * 2.0, blendType='easeInOut'))) self.showScoreTrack = Parallel(lerpTrack, Sequence(Wait(MazeGameGlobals.SHOWSCORES_DURATION), Func(self.gameOver))) self.showScoreTrack.start() #For the Alpha Blueprint ARG if config.GetBool('want-blueprint4-ARG', False): MinigameGlobals.generateDebugARGPhrase() def exitShowScores(self): self.showScoreTrack.pause() del self.showScoreTrack def enterCleanup(self): self.notify.debug('enterCleanup') def exitCleanup(self): pass def getIntroTrack(self): self.__cameraTask(None) origCamParent = camera.getParent() origCamPos = camera.getPos() origCamHpr = camera.getHpr() iCamParent = base.localAvatar.attachNewNode('iCamParent') iCamParent.setH(180) camera.reparentTo(iCamParent) toonHeight = base.localAvatar.getHeight() camera.setPos(0, -15, toonHeight * 3) camera.lookAt(0, 0, toonHeight / 2.0) iCamParent.wrtReparentTo(origCamParent) waitDur = 5.0 lerpDur = 4.5 lerpTrack = Parallel() startHpr = iCamParent.getHpr() startHpr.setX(PythonUtil.reduceAngle(startHpr[0])) lerpTrack.append(LerpPosHprInterval(iCamParent, lerpDur, pos=Point3(0, 0, 0), hpr=Point3(0, 0, 0), startHpr=startHpr, name=self.uniqueName('introLerpParent'))) lerpTrack.append(LerpPosHprInterval(camera, lerpDur, pos=origCamPos, hpr=origCamHpr, blendType='easeInOut', name=self.uniqueName('introLerpCameraPos'))) base.localAvatar.startLookAround() def cleanup(origCamParent = origCamParent, origCamPos = origCamPos, origCamHpr = origCamHpr, iCamParent = iCamParent): camera.reparentTo(origCamParent) camera.setPos(origCamPos) camera.setHpr(origCamHpr) iCamParent.removeNode() del iCamParent base.localAvatar.stopLookAround() return Sequence(Wait(waitDur), lerpTrack, Func(cleanup))
class PartyCogActivityGui(DirectObject): notify = directNotify.newCategory('PartyCogActivityGui') def __init__(self): DirectObject.__init__(self) self._piePowerMeter = None self._victoryBalanceBar = None self._scoreLabel = None self._cogTracker = None self._piePowerTitle = None self._victoryBalanceTitle = None self._scoreTitle = None self._spamWarning = None self._spamWarningIvalName = 'PartyCogActivityGui-SpamWarning' return def load(self): self._initPiePowerMeter() self._initScore() self._initCogTracker() self._initSpamWarning() self._initControlGui() self._initVictoryBalanceBar() def unload(self): if self._cogTracker is not None: self._cogTracker.destory() self._cogTracker = None if self._piePowerMeter is not None: self._piePowerMeter.destroy() self._piePowerMeter = None if self._piePowerTitle is not None: self._piePowerTitle.destroy() self._piePowerTitle = None if self._scoreLabel is not None: self._scoreLabel.destroy() self._scoreLabel = None if self._scoreTitle is not None: self._scoreTitle.destroy() self._scoreTitle = None taskMgr.remove(self._spamWarningIvalName) if self._spamWarning: self._spamWarning.destroy() self._spamWarning = None if hasattr(self, '_attackKeys'): self._attackKeys.detachNode() del self._attackKeys if hasattr(self, '_moveKeys'): self._moveKeys.detachNode() del self._moveKeys if self._victoryBalanceBar: self._victoryBalanceBar.detachNode() self._victoryBalanceBar = None if self._victoryBalanceBarOrange: self._victoryBalanceBarOrange.detachNode() self._victoryBalanceBarOrange = None if self._victoryBalanceBarPie: self._victoryBalanceBarPie.detachNode() self._victoryBalanceBarPie = None if self._victoryBalanceBarArrow: self._victoryBalanceBarArrow.detachNode() self._victoryBalanceBarArrow = None return def _initVictoryBalanceBar(self): h = PartyGlobals.CogActivityPowerMeterHeight / 2.0 w = PartyGlobals.CogActivityPowerMeterWidth / 2.0 victoryBalanceBar = loader.loadModel( 'phase_13/models/parties/tt_m_gui_pty_pieToss_balanceBar') self._victoryBalanceBar = victoryBalanceBar.find( '**/*tt_t_gui_pty_pieToss_balanceBarBG') self._victoryBalanceBar.reparentTo(aspect2d) self._victoryBalanceBar.setBin('fixed', 0) self._victoryBalanceBar.setPos(PartyGlobals.CogActivityVictoryBarPos) self._victoryBalanceBar.setScale(1) self._victoryBalanceBarOrange = victoryBalanceBar.find( '**/*tt_t_gui_pty_pieToss_balanceBarOrange') self._victoryBalanceBarOrange.reparentTo(self._victoryBalanceBar) self._victoryBalanceBarOrange.setBin('fixed', 1) self._victoryBalanceBarOrange.setPos( PartyGlobals.CogActivityVictoryBarOrangePos) self._victoryBalanceBarOrange.setScale( PartyGlobals.CogActivityBarStartScale, 1.0, 1.0) self._victoryBalanceBarPie = victoryBalanceBar.find( '**/*tt_t_gui_pty_pieToss_balanceBarPie') self._victoryBalanceBarPie.reparentTo(self._victoryBalanceBar) self._victoryBalanceBarPie.setBin('fixed', 2) self._victoryBalanceBarPie.setX( PartyGlobals.CogActivityVictoryBarPiePos[0]) self._victoryBalanceBarPie.setY( PartyGlobals.CogActivityVictoryBarPiePos[1]) self._victoryBalanceBarPie.setZ( PartyGlobals.CogActivityVictoryBarPiePos[2]) self._victoryBalanceBarPie.setScale( PartyGlobals.CogActivityBarPieScale) self._victoryBalanceBarArrow = victoryBalanceBar.find( '**/*tt_t_gui_pty_pieToss_balanceArrow') self._victoryBalanceBarArrow.reparentTo(self._victoryBalanceBarPie) self._victoryBalanceBarArrow.setBin('fixed', 2) self._victoryBalanceBarArrow.setPos( PartyGlobals.CogActivityVictoryBarArrow) self._victoryBalanceBarArrow.setScale( 1 / PartyGlobals.CogActivityBarPieScale) def _initControlGui(self): self._attackIvalName = 'PartyCogActivityGui-attackKeys' self._moveIvalName = 'PartyCogActivityGui-moveKeys' pieTossControls = loader.loadModel( 'phase_13/models/parties/tt_m_gui_pty_pieToss_controls') self._attackKeys = pieTossControls.find('**/*control*') self._moveKeys = pieTossControls.find('**/*arrow*') self._moveKeys.reparentTo(aspect2d) self._moveKeys.setPos(1.0, 0.0, -0.435) self._moveKeys.setScale(0.15) self._attackKeys.reparentTo(aspect2d) self._attackKeys.setPos(0.85, 0.0, -0.45) self._attackKeys.setScale(0.15) self._moveKeys.hide() self._attackKeys.hide() def _initPiePowerMeter(self): h = PartyGlobals.CogActivityPowerMeterHeight / 2.0 w = PartyGlobals.CogActivityPowerMeterWidth / 2.0 self._piePowerMeter = DirectWaitBar( frameSize=(-h, h, -w, w), relief=DGG.GROOVE, frameColor=(0.9, 0.9, 0.9, 1.0), borderWidth=(0.01, 0.01), barColor=PartyGlobals.CogActivityColors[0], pos=PartyGlobals.CogActivityPowerMeterPos, hpr=(0.0, 0.0, -90.0)) self._piePowerMeter.setBin('fixed', 0) self._piePowerTitle = OnscreenText( text=TTLocalizer.PartyCogGuiPowerLabel, pos=PartyGlobals.CogActivityPowerMeterTextPos, scale=0.05, fg=(1.0, 1.0, 1.0, 1.0), align=TextNode.ACenter) self._piePowerTitle.setBin('fixed', 0) self._piePowerMeter.hide() self._piePowerTitle.hide() def _initScore(self): self._scoreLabel = OnscreenText( text='0', pos=PartyGlobals.CogActivityScorePos, scale=PartyGlobals.TugOfWarTextWordScale, fg=(1.0, 1.0, 0.0, 1.0), align=TextNode.ARight, font=ToontownGlobals.getSignFont(), mayChange=True) self._scoreTitle = OnscreenText(text=TTLocalizer.PartyCogGuiScoreLabel, pos=PartyGlobals.CogActivityScoreTitle, scale=0.05, fg=(1.0, 1.0, 1.0, 1.0), align=TextNode.ARight) self._scoreLabel.hide() self._scoreTitle.hide() def _initCogTracker(self): self._cogTracker = PartyCogTrackerGui() def _initSpamWarning(self): self._spamWarning = OnscreenText( text=TTLocalizer.PartyCogGuiSpamWarning, scale=0.15, fg=(1.0, 1.0, 0, 1.0), shadow=(0, 0, 0, 0.62), mayChange=False, pos=(0, 0.33)) self._spamWarning.hide() def showScore(self): self._scoreLabel.show() self._scoreTitle.show() def hideScore(self): self._scoreLabel.hide() self._scoreTitle.hide() def setScore(self, score=0): self._scoreLabel['text'] = str(score) def resetPiePowerMeter(self): self._piePowerMeter['value'] = 0 def showPiePowerMeter(self): self._piePowerMeter.show() self._piePowerTitle.show() def hidePiePowerMeter(self): self._piePowerMeter.hide() self._piePowerTitle.hide() def updatePiePowerMeter(self, value): self._piePowerMeter['value'] = value def getPiePowerMeterValue(self): return self._piePowerMeter['value'] def hideSpamWarning(self): taskMgr.remove(self._spamWarningIvalName) if self._spamWarning: self._spamWarning.hide() def showSpamWarning(self): if self._spamWarning.isHidden(): self._spamWarning.show() taskMgr.remove(self._spamWarningIvalName) Sequence(ToontownIntervals.getPulseLargerIval( self._spamWarning, ''), Wait(PartyGlobals.CogActivitySpamWarningShowTime), Func(self.hideSpamWarning), name=self._spamWarningIvalName, autoFinish=1).start() def hide(self): self.hidePiePowerMeter() self.hideScore() self.hideSpamWarning() self.hideControls() def disableToontownHUD(self): base.localAvatar.hideName() base.localAvatar.laffMeter.hide() base.setCellsActive(base.bottomCells + [base.rightCells[1]], False) def enableToontownHUD(self): base.localAvatar.showName() base.localAvatar.laffMeter.show() base.setCellsActive(base.bottomCells + [base.rightCells[1]], True) def setTeam(self, team): self.team = team if team == 0: self._cogTracker.frame.setR(180) self._piePowerMeter['barColor'] = PartyGlobals.CogActivityColors[team] def startTrackingCogs(self, cogs): self.cogs = cogs taskMgr.add(self.trackCogs, 'trackCogs') def trackCogs(self, task): if self.cogs is None: return self._updateVictoryBar() for i, cog in enumerate(self.cogs): self._cogTracker.updateCog(i, cog, self.team) return task.cont def _updateVictoryBar(self): if not (hasattr(self, '_victoryBalanceBar') and self._victoryBalanceBar): return netDistance = 0 for cog in self.cogs: netDistance = netDistance + cog.targetDistance teamDistance = netDistance / 6.0 self._victoryBalanceBarOrange.setScale( PartyGlobals.CogActivityBarStartScale + teamDistance * 10 * PartyGlobals.CogActivityBarUnitScale, 1.0, 1.0) self._victoryBalanceBarPie.setX( PartyGlobals.CogActivityVictoryBarPiePos[0] + teamDistance * 10 * PartyGlobals.CogActivityBarPieUnitMove) self._victoryBalanceBarPie.setY( PartyGlobals.CogActivityVictoryBarPiePos[1]) self._victoryBalanceBarPie.setZ( PartyGlobals.CogActivityVictoryBarPiePos[2]) if teamDistance > 0.0: self._victoryBalanceBarArrow.setColor( PartyGlobals.CogActivityColors[1]) elif teamDistance < 0.0: self._victoryBalanceBarArrow.setColor( PartyGlobals.CogActivityColors[0]) else: self._victoryBalanceBarArrow.setColor(VBase4(1.0, 1.0, 1.0, 1.0)) def stopTrackingCogs(self): taskMgr.remove('trackCogs') def showAttackControls(self): if self._attackKeys.isHidden(): self._attackKeys.show() taskMgr.remove(self._attackIvalName) Sequence(ToontownIntervals.getPulseLargerIval(self._attackKeys, '', scale=0.15), Wait(PartyGlobals.CogActivityControlsShowTime), Func(self.hideAttackControls), name=self._attackIvalName, autoFinish=1).start() def showMoveControls(self): if self._moveKeys.isHidden() and not self._attackKeys.isHidden(): self._moveKeys.show() taskMgr.remove(self._moveIvalName) Sequence(ToontownIntervals.getPulseLargerIval(self._moveKeys, '', scale=0.15), Wait(PartyGlobals.CogActivityControlsShowTime), Func(self.hideMoveControls), name=self._moveIvalName, autoFinish=1).start() def hideAttackControls(self): taskMgr.remove(self._attackIvalName) if hasattr(self, '_attackKeys') and self._attackKeys: self._attackKeys.hide() def hideMoveControls(self): taskMgr.remove(self._moveIvalName) if hasattr(self, '_moveKeys') and self._moveKeys: self._moveKeys.hide() def hideControls(self): self.hideMoveControls() self.hideAttackControls()
class QuestPoster(DirectFrame): notify = directNotify.newCategory('QuestPoster') def __init__(self, quest, parent = aspect2d, **kw): self.quest = quest # Let's begin building the quest poster. bookModel = loader.loadModel('phase_3.5/models/gui/stickerbook_gui.bam') questCard = bookModel.find('**/questCard') optiondefs = (('relief', None, None), ('image', questCard, None), ('image_scale', (0.8, 1.0, 0.58), None), ('state', DGG.NORMAL, None)) self.defineoptions(kw, optiondefs) DirectFrame.__init__(self, relief = None) self.initialiseoptions(QuestPoster) self.questFrame = DirectFrame(parent = self, relief = None) # Quest title text self.headline = DirectLabel(parent = self.questFrame, relief = None, text = self.quest.getName(), text_font = CIGlobals.getMinnieFont(), text_fg = QuestGlobals.TEXT_COLOR, text_scale = 0.05, text_align = TextNode.ACenter, text_wordwrap = 25.0, textMayChange = 1, pos = (0, 0, 0.23)) # Quest information self.questInfo = DirectLabel(parent = self.questFrame, relief = None, text = '', text_font = CIGlobals.getToonFont(), text_fg = QuestGlobals.TEXT_COLOR, text_scale = 0.04, text_align = TextNode.ACenter, text_wordwrap = TEXT_WORDWRAP, textMayChange = 1, pos = (QuestGlobals.DEFAULT_INFO_POS)) self.questInfo.hide() self.questInfo02 = DirectLabel(parent = self.questFrame, relief = None, text = '', text_font = CIGlobals.getToonFont(), text_fg = QuestGlobals.TEXT_COLOR, text_scale = 0.04, text_align = TextNode.ACenter, text_wordwrap = TEXT_WORDWRAP, textMayChange = 1, pos = (QuestGlobals.DEFAULT_INFO2_POS)) self.questInfo02.hide() self.locationInfo = DirectLabel(parent = self.questFrame, relief = None, text = 'N/A', text_font = CIGlobals.getToonFont(), text_fg = QuestGlobals.TEXT_COLOR, text_scale = TEXT_SCALE, text_align = TextNode.ACenter, text_wordwrap = TEXT_WORDWRAP, textMayChange = 1, pos = (0, 0, -0.115)) self.locationInfo.hide() # C'mon Brian this one is obvious self.rewardText = DirectLabel(parent = self.questFrame, relief = None, text = '', text_fg = QuestGlobals.REWARD_RED, text_scale = 0.0425, text_align = TextNode.ALeft, text_wordwrap = 17.0, textMayChange = 1, pos = (-0.36, 0, -0.26)) self.rewardText.hide() self.lPictureFrame = DirectFrame(parent = self.questFrame, relief = None, image = bookModel.find('**/questPictureFrame'), image_scale = QuestGlobals.IMAGE_SCALE_SMALL, text = '', text_pos = (0, -0.11), text_fg = QuestGlobals.TEXT_COLOR, text_scale = TEXT_SCALE, text_align = TextNode.ACenter, text_wordwrap = 11.0, pos = (QuestGlobals.DEFAULT_LEFT_PICTURE_POS), textMayChange = 1) self.lPictureFrame.hide() self.rPictureFrame = DirectFrame(parent = self.questFrame, relief = None, image = bookModel.find('**/questPictureFrame'), image_scale = QuestGlobals.IMAGE_SCALE_SMALL, text = '', text_pos = (0, -0.11), text_fg = QuestGlobals.TEXT_COLOR, text_scale = TEXT_SCALE, text_align = TextNode.ACenter, text_wordwrap = 11.0, textMayChange = 1, pos = (QuestGlobals.DEFAULT_RIGHT_PICTURE_POS)) self.rPictureFrame['image_color'] = Vec4(*QuestGlobals.GREEN) self.rPictureFrame.hide() self.lQuestIcon = DirectFrame(parent = self.lPictureFrame, relief = None, text = ' ', text_font = CIGlobals.getSuitFont(), text_pos = (0, -0.03), text_fg = QuestGlobals.TEXT_COLOR, text_scale = 0.13, text_align = TextNode.ACenter, text_wordwrap = 13.0, textMayChange = 1) self.lQuestIcon.setColorOff(-1) self.rQuestIcon = DirectFrame(parent = self.rPictureFrame, relief = None, text = ' ', text_font = CIGlobals.getSuitFont(), text_pos = (0, -0.03), text_fg = QuestGlobals.TEXT_COLOR, text_scale = 0.13, text_align = TextNode.ACenter, text_wordwrap = 13.0, textMayChange = 1) self.rQuestIcon.setColorOff(-1) head = SuitBank.PennyPincher.getHead().generate() head.setDepthTest(True) head.setDepthWrite(True) head.setScale(0.25) for part in head.getChildren(): part.setDepthTest(True) part.setDepthWrite(True) self.fitGeometry(head, fFlip = 1) self.rQuestIcon['geom'] = head self.rQuestIcon['geom_scale'] = QuestGlobals.IMAGE_SCALE_SMALL self.rQuestIcon['geom_pos'] = Point3(0, 10, -0.05) self.rQuestIcon['geom_hpr'] = Point3(180, 0, 0) self.rQuestIcon.initialiseoptions(DirectFrame) self.auxText = DirectLabel(parent = self.questFrame, relief = None, text = 'Recover', text_font = CIGlobals.getToonFont(), text_scale = QuestGlobals.QPauxText, text_fg = QuestGlobals.TEXT_COLOR, text_align = TextNode.ACenter, pos = (QuestGlobals.DEFAULT_AUX_POS), textMayChange=1) self.auxText.hide() self.middleText = DirectLabel(parent = self.questFrame, relief = None, text = 'from:', text_font = CIGlobals.getToonFont(), text_scale = QuestGlobals.QPauxText, text_fg = QuestGlobals.TEXT_COLOR, text_align = TextNode.ACenter, pos = (QuestGlobals.DEFAULT_MIDDLE_POS), textMayChange=1) self.middleText.hide() self.questProgress = DirectWaitBar(parent = self.questFrame, relief = DGG.SUNKEN, frameSize=(-0.95, 0.95, -0.1, 0.12), borderWidth = (0.025, 0.025), scale = 0.2, frameColor = (0.945, 0.875, 0.706, 1.0), barColor=(0.5, 0.7, 0.5, 1), text='0/0', text_font = CIGlobals.getToonFont(), text_scale = 0.19, text_fg = (0.05, 0.14, 0.4, 1), text_align = TextNode.ACenter, text_pos = (0, -0.05), #-0.02 pos = (0, 0, -0.2425)) self.questProgress.hide() rewardFrameGeom = loader.loadModel('phase_4/models/gui/gag_shop_purchase_gui.bam') self.rewardFrame = DirectFrame(parent = self.questFrame, relief = None, geom = rewardFrameGeom.find('**/Goofys_Sign'), geom_scale = (0.615, 0, 0.4), pos = (-0.01, 0, -0.25) ) jellybeanJar = QuestGlobals.getFilmIcon() self.lRewardFrame = DirectFrame(parent = self.rewardFrame, relief = None, geom = jellybeanJar, geom_scale = QuestGlobals.TP_ACCESS_SCALE, sortOrder = 1, pos = (QuestGlobals.LEFT_TP_ACCESS_POS)) self.lRewardFrame.setBin('gui-popup', 30) self.lRewardAmt = DirectFrame(parent = self.questFrame, relief = None, geom = rewardFrameGeom.find('**/Char_Pnl'), geom_scale = (0.15, 0, 0.1275), text = '#1', text_font = CIGlobals.getToonFont(), text_scale = 0.04, text_fg = (0, 0, 0, 1), text_align = TextNode.ACenter, text_pos = (0, -0.01), sortOrder = 2, pos = (-0.285, 0, -0.255)) self.lRewardAmt.setBin('gui-popup', 40) self.rRewardFrame = DirectFrame(parent = self.rewardFrame, relief = None, geom = QuestGlobals.getJBIcon(), geom_scale = QuestGlobals.JB_JAR_SCALE, pos = QuestGlobals.RIGHT_JB_JAR_POS) self.rRewardAmt = DirectFrame(parent = self.questFrame, relief = None, geom = rewardFrameGeom.find('**/Char_Pnl'), geom_scale = (0.15, 0, 0.1275), text = '25', text_font = CIGlobals.getToonFont(), text_scale = 0.04, text_fg = (0, 0, 0, 1), text_align = TextNode.ACenter, text_pos = (0, -0.01), pos = (0.2725, 0, -0.255)) self.rRewardAmt.setBin('gui-popup', 40) rewardFrameGeom.removeNode() # This is the rotated text on the side. self.sideInfo = DirectLabel(parent = self.questFrame, relief = None, text = QuestGlobals.JUST_FOR_FUN, text_fg = (0.0, 0.439, 1.0, 1.0), text_shadow = (0, 0, 0, 1), pos = (-0.2825, 0, 0.2), scale = 0.03) self.sideInfo.setR(-30) self.sideInfo.hide() bookModel.removeNode() self.laffMeter = None self.hide() return def handleIcon(self, objective, geom, scale, icon): isHead = True if type(geom) == ToonHead else geom.getName() == ('%sHead' % CIGlobals.Suit) if isHead: geom.setDepthWrite(1) geom.setDepthTest(1) self.fitGeometry(geom, fFlip = 1) if isinstance(objective, VisitNPCObjective) and icon == self.rQuestIcon: icon.setPos(icon.getX(), icon.getY(), icon.getZ() + 0.05) icon.setH(180) elif isinstance(objective, CogObjective): icon.setScale(QuestGlobals.IMAGE_SCALE_SMALL) icon.setPos(icon.getX(), icon.getY(), icon.getZ() - 0.04) if icon == self.lQuestIcon: icon.setH(180) icon['geom'] = geom icon['geom_scale'] = QuestGlobals.IMAGE_SCALE_SMALL else: icon['geom'] = geom icon['geom_scale'] = scale def update(self): objective = self.quest.getCurrentObjective() objective.updateInfo() # Let's setup the quest info. self.questInfo.setPos(self.quest.getInfoPos()) self.questInfo['text'] = self.quest.getInfoText() self.questInfo02.setPos(self.quest.getInfo02Pos()) self.questInfo02['text'] = self.quest.getInfo02Text() # Let's move the picture frames to the positions we want them in. self.lPictureFrame.setPos(self.quest.getLeftPicturePos()) self.rPictureFrame.setPos(self.quest.getRightPicturePos()) editLeftAtr = isinstance(objective, VisitNPCObjective) or isinstance(objective, CogObjective) if editLeftAtr and objective.getDidEditLeft() or not editLeftAtr: geom = self.quest.getLeftIconGeom() scale = self.quest.getLeftIconScale() icon = self.lQuestIcon self.handleIcon(objective, geom, scale, icon) self.handleIcon(objective, self.quest.getRightIconGeom(), self.quest.getRightIconScale(), self.rQuestIcon) else: geom = self.quest.getRightIconGeom() scale = self.quest.getRightIconScale() icon = self.rQuestIcon self.handleIcon(objective, geom, scale, icon) self.handleIcon(objective, self.quest.getLeftIconGeom(), self.quest.getLeftIconScale(), self.lQuestIcon) if self.questInfo02['text'] == '': self.rPictureFrame.hide() self.questInfo02.hide() else: self.rPictureFrame.show() self.questInfo02.show() self.middleText['text'] = self.quest.getMiddleText() if not self.middleText['text'] == '': self.middleText.show() self.questInfo.show() self.lPictureFrame.show() # Let's set the location text. self.locationInfo['text'] = self.quest.getLocationText() self.locationInfo['text_pos'] = (0, self.quest.getLocationY()) self.locationInfo.show() # Let's set the progress bar up. self.questProgress['text'] = self.quest.getProgressText() if len(self.questProgress['text']) > 0 and not objective.finished(): self.questProgress.show() self.questProgress['range'] = objective.getNeededAmount() self.questProgress['value'] = objective.getProgress() & pow(2, 16) - 1 else: self.questProgress.hide() # Let's setup the aux text. self.auxText.setPos(self.quest.getAuxPos()) self.auxText['text'] = self.quest.getAuxText() self.auxText.show() maxHP = base.localAvatar.getMaxHealth() # Let's setup the rewards. for i in xrange(0, len(self.quest.getRewards())): reward = self.quest.getRewards()[i] frame = self.lRewardFrame if (i == 0) else self.rRewardFrame info = self.lRewardAmt if (i == 0) else self.rRewardAmt rType = reward.getType() if(rType == RewardType.JELLYBEANS): frame['pos'] = QuestGlobals.LEFT_JB_JAR_POS if (i == 0) else QuestGlobals.RIGHT_JB_JAR_POS frame['geom'] = QuestGlobals.getJBIcon() frame['geom_scale'] = QuestGlobals.JB_JAR_SCALE info['text'] = str(reward.getModifier()) elif(rType == RewardType.TELEPORT_ACCESS or rType == RewardType.GAG_FRAME): frame['pos'] = QuestGlobals.LEFT_TP_ACCESS_POS if(i == 0) else QuestGlobals.RIGHT_TP_ACCESS_POS frame['geom'] = QuestGlobals.getTPAccessIcon() if(rType == RewardType.TELEPORT_ACCESS) else QuestGlobals.getFilmIcon() frame['geom_scale'] = QuestGlobals.TP_ACCESS_SCALE info['text'] = 'N/A' if(rType == RewardType.TELEPORT_ACCESS) else '#%s' % (str(reward.getModifier())) elif(rType == RewardType.LAFF_POINTS): frame.initialiseoptions(DirectFrame) r, g, b, _ = base.localAvatar.getHeadColor() pos = QuestGlobals.LEFT_LAFF_METER_POS if(i == 0) else QuestGlobals.RIGHT_LAFF_METER_POS # Create the laff meter with the new health. hp = maxHP + reward.getModifier() laffMeter = LaffOMeter() laffMeter.generate(r, g, b, base.localAvatar.getAnimal(), maxHP = hp, initialHP = hp) # Let's position the laff meter. frame['geom'] = laffMeter frame['geom_scale'] = QuestGlobals.LAFF_METER_SCALE frame.setPos(pos) info['text'] = '+%s' % (str(reward.getModifier())) laffMeter.destroy() laffMeter = None # Hide or show the other reward depending on if there's 2 rewards. if(len(self.quest.getRewards()) == 1): self.rRewardFrame.hide() self.rRewardAmt.hide() else: self.rRewardFrame.show() self.rRewardAmt.show() if objective.finished(): self.setColor(Vec4(*QuestGlobals.LIGHT_GREEN)) self.sideInfo['text'] = 'Completed!' self.sideInfo.show() self.questInfo.initialiseoptions(DirectLabel) self.questInfo02.initialiseoptions(DirectLabel) self.locationInfo.initialiseoptions(DirectLabel) self.lPictureFrame.initialiseoptions(DirectFrame) self.rPictureFrame.initialiseoptions(DirectFrame) self.lQuestIcon.initialiseoptions(DirectFrame) self.rQuestIcon.initialiseoptions(DirectFrame) self.auxText.initialiseoptions(DirectLabel) self.middleText.initialiseoptions(DirectLabel) self.sideInfo.initialiseoptions(DirectLabel) self.lPictureFrame['image_color'] = self.quest.getPictureFrameColor() self.rPictureFrame['image_color'] = self.quest.getPictureFrameColor() def fitGeometry(self, geom, fFlip = 0, dimension = 0.8): p1 = Point3() p2 = Point3() geom.calcTightBounds(p1, p2) if fFlip: t = p1[0] p1.setX(-p2[0]) p2.setX(-t) d = p2 - p1 biggest = max(d[0], d[2]) s = dimension / biggest mid = (p1 + d / 2.0) * s geomXform = hidden.attachNewNode('geomXform') for child in geom.getChildren(): child.reparentTo(geomXform) geomXform.setPosHprScale(-mid[0], -mid[1] + 1, -mid[2], 180, 0, 0, s, s, s) geomXform.reparentTo(geom) def destroy(self): self._deleteGeoms() DirectFrame.destroy(self) def _deleteGeoms(self): for icon in (self.lQuestIcon, self.rQuestIcon): geom = icon['geom'] if geom and hasattr(geom, 'delete'): geom.delete() def getQuest(self): return self.quest
class PartyCogActivityGui(DirectObject): notify = directNotify.newCategory("PartyCogActivityGui") def __init__(self): DirectObject.__init__(self) self._piePowerMeter = None self._victoryBalanceBar = None self._scoreLabel = None self._cogTracker = None self._piePowerTitle = None self._victoryBalanceTitle = None self._scoreTitle = None self._spamWarning = None self._spamWarningIvalName = "PartyCogActivityGui-SpamWarning" def load(self): self._initPiePowerMeter() self._initScore() self._initCogTracker() self._initSpamWarning() self._initControlGui() self._initVictoryBalanceBar() def unload(self): if self._cogTracker is not None: self._cogTracker.destory() self._cogTracker = None if self._piePowerMeter is not None: self._piePowerMeter.destroy() self._piePowerMeter = None if self._piePowerTitle is not None: self._piePowerTitle.destroy() self._piePowerTitle = None if self._scoreLabel is not None: self._scoreLabel.destroy() self._scoreLabel = None if self._scoreTitle is not None: self._scoreTitle.destroy() self._scoreTitle = None taskMgr.remove(self._spamWarningIvalName) if self._spamWarning: self._spamWarning.destroy() self._spamWarning = None if hasattr(self, '_attackKeys'): self._attackKeys.detachNode() del self._attackKeys if hasattr(self, '_moveKeys'): self._moveKeys.detachNode() del self._moveKeys if self._victoryBalanceBar: self._victoryBalanceBar.detachNode() self._victoryBalanceBar = None if self._victoryBalanceBarOrange: self._victoryBalanceBarOrange.detachNode() self._victoryBalanceBarOrange = None if self._victoryBalanceBarPie: self._victoryBalanceBarPie.detachNode() self._victoryBalanceBarPie = None if self._victoryBalanceBarArrow: self._victoryBalanceBarArrow.detachNode() self._victoryBalanceBarArrow = None def _initVictoryBalanceBar(self): h = PartyGlobals.CogActivityPowerMeterHeight / 2.0 w = PartyGlobals.CogActivityPowerMeterWidth / 2.0 victoryBalanceBar = loader.loadModel("phase_13/models/parties/tt_m_gui_pty_pieToss_balanceBar") self._victoryBalanceBar = victoryBalanceBar.find("**/*tt_t_gui_pty_pieToss_balanceBarBG") self._victoryBalanceBar.reparentTo(aspect2d) self._victoryBalanceBar.setBin("fixed", 0) self._victoryBalanceBar.setPos(PartyGlobals.CogActivityVictoryBarPos) self._victoryBalanceBar.setScale(1) self._victoryBalanceBarOrange = victoryBalanceBar.find("**/*tt_t_gui_pty_pieToss_balanceBarOrange") self._victoryBalanceBarOrange.reparentTo(self._victoryBalanceBar) self._victoryBalanceBarOrange.setBin("fixed", 1) self._victoryBalanceBarOrange.setPos(PartyGlobals.CogActivityVictoryBarOrangePos) self._victoryBalanceBarOrange.setScale(PartyGlobals.CogActivityBarStartScale, 1.0, 1.0) self._victoryBalanceBarPie = victoryBalanceBar.find("**/*tt_t_gui_pty_pieToss_balanceBarPie") self._victoryBalanceBarPie.reparentTo(self._victoryBalanceBar) self._victoryBalanceBarPie.setBin("fixed", 2) self._victoryBalanceBarPie.setX(PartyGlobals.CogActivityVictoryBarPiePos[0]) self._victoryBalanceBarPie.setY(PartyGlobals.CogActivityVictoryBarPiePos[1]) self._victoryBalanceBarPie.setZ(PartyGlobals.CogActivityVictoryBarPiePos[2]) self._victoryBalanceBarPie.setScale(PartyGlobals.CogActivityBarPieScale) self._victoryBalanceBarArrow = victoryBalanceBar.find("**/*tt_t_gui_pty_pieToss_balanceArrow") self._victoryBalanceBarArrow.reparentTo(self._victoryBalanceBarPie) self._victoryBalanceBarArrow.setBin("fixed", 2) self._victoryBalanceBarArrow.setPos(PartyGlobals.CogActivityVictoryBarArrow) self._victoryBalanceBarArrow.setScale(1/PartyGlobals.CogActivityBarPieScale) # self._victoryBalanceBar = DirectWaitBar( # frameSize = (-h, h, -w, w), # relief = DGG.SUNKEN, # frameColor = PartyGlobals.CogActivityColors[0], # borderWidth = (0.0, 0.0), # barColor = PartyGlobals.CogActivityColors[1], # pos = PartyGlobals.CogActivityVictoryBarPos, # hpr = (0.0, 0.0, -90.0), # ) # self._victoryBalanceBar.setBin("fixed", 0) # self._victoryBalanceBar["value"] = 50 def _initControlGui(self): self._attackIvalName = "PartyCogActivityGui-attackKeys" self._moveIvalName = "PartyCogActivityGui-moveKeys" pieTossControls = loader.loadModel("phase_13/models/parties/tt_m_gui_pty_pieToss_controls") self._attackKeys = pieTossControls.find("**/*control*") self._moveKeys = pieTossControls.find("**/*arrow*") self._moveKeys.reparentTo(aspect2d) self._moveKeys.setPos(1.0, 0.0, -0.435) self._moveKeys.setScale(0.15) self._attackKeys.reparentTo(aspect2d) self._attackKeys.setPos(0.85, 0.0, -0.45) self._attackKeys.setScale(0.15) self._moveKeys.hide() self._attackKeys.hide() def _initPiePowerMeter(self): h = PartyGlobals.CogActivityPowerMeterHeight / 2.0 w = PartyGlobals.CogActivityPowerMeterWidth / 2.0 self._piePowerMeter = DirectWaitBar( frameSize = (-h, h, -w, w), relief = DGG.GROOVE, frameColor = (0.9, 0.9, 0.9, 1.0), borderWidth = (0.01, 0.01), barColor = PartyGlobals.CogActivityColors[0], pos = PartyGlobals.CogActivityPowerMeterPos, hpr = (0.0, 0.0, -90.0), ) self._piePowerMeter.setBin("fixed", 0) self._piePowerTitle = OnscreenText( text=TTLocalizer.PartyCogGuiPowerLabel, pos=PartyGlobals.CogActivityPowerMeterTextPos, scale=0.05, fg=(1.0, 1.0, 1.0, 1.0), align=TextNode.ACenter, ) self._piePowerTitle.setBin("fixed", 0) self._piePowerMeter.hide() self._piePowerTitle.hide() def _initScore(self): self._scoreLabel = OnscreenText( text="0", pos=PartyGlobals.CogActivityScorePos, scale=PartyGlobals.TugOfWarTextWordScale, #fg=base.localAvatar.style.getHeadColor(), #fg=PartyGlobals.TeamActivityStatusColor, fg=(1.0, 1.0, 0.0, 1.0), align=TextNode.ARight, font=ToontownGlobals.getSignFont(), mayChange=True, ) self._scoreTitle = OnscreenText( text=TTLocalizer.PartyCogGuiScoreLabel, pos=PartyGlobals.CogActivityScoreTitle, scale=0.05, fg=(1.0, 1.0, 1.0, 1.0), #fg=(0.0, 0.0, 0.0, 1.0), align=TextNode.ARight, ) self._scoreLabel.hide() self._scoreTitle.hide() def _initCogTracker(self): self._cogTracker = PartyCogTrackerGui() def _initSpamWarning(self): self._spamWarning = OnscreenText( text = TTLocalizer.PartyCogGuiSpamWarning, scale = 0.15, fg = (1.0, 1.0, 0, 1.0), shadow = (0, 0, 0, 0.62), mayChange = False, pos = (0, 0.33) ) self._spamWarning.hide() def showScore(self): self._scoreLabel.show() self._scoreTitle.show() def hideScore(self): self._scoreLabel.hide() self._scoreTitle.hide() def setScore(self, score=0): self._scoreLabel["text"] = str(score) def resetPiePowerMeter(self): self._piePowerMeter["value"] = 0 def showPiePowerMeter(self): self._piePowerMeter.show() self._piePowerTitle.show() def hidePiePowerMeter(self): self._piePowerMeter.hide() self._piePowerTitle.hide() def updatePiePowerMeter(self, value): self._piePowerMeter["value"] = value # Uncomment this part if you want the bar to by a psychedelic change of colors. # self._piePowerMeter["barColor"] = ( # min(value * 2, 100) / 100.0, # min((100 - value) * 2, 100) / 100.0, # 0.0, # 1.0 # ) def getPiePowerMeterValue(self): return self._piePowerMeter["value"] def hideSpamWarning(self): taskMgr.remove(self._spamWarningIvalName) if self._spamWarning: self._spamWarning.hide() def showSpamWarning(self): if self._spamWarning.isHidden(): self._spamWarning.show() taskMgr.remove(self._spamWarningIvalName) Sequence( # Boing it in to grab attention. ToontownIntervals.getPulseLargerIval(self._spamWarning, ""), # Let it sit on-screen for a while. Wait(PartyGlobals.CogActivitySpamWarningShowTime), # Then get rid of it. Func(self.hideSpamWarning), name=self._spamWarningIvalName, autoFinish=1 ).start() def hide(self): self.hidePiePowerMeter() self.hideScore() self.hideSpamWarning() self.hideControls() def disableToontownHUD(self): base.localAvatar.hideName() base.localAvatar.laffMeter.hide() base.setCellsAvailable(base.bottomCells + [base.rightCells[1]], False) def enableToontownHUD(self): base.localAvatar.showName() base.localAvatar.laffMeter.show() base.setCellsAvailable(base.bottomCells + [base.rightCells[1]], True) def setTeam(self, team): self.team = team if team == 0: self._cogTracker.frame.setR(180) # The old default power bar color was blue, but that was confusing because there's a blue team. # So the idea here is to make the color the same as the player's team. self._piePowerMeter["barColor"] = PartyGlobals.CogActivityColors[team] def startTrackingCogs(self, cogs): self.cogs = cogs taskMgr.add(self.trackCogs, "trackCogs") def trackCogs(self, task): if self.cogs is None: return self._updateVictoryBar() for i, cog in enumerate(self.cogs): self._cogTracker.updateCog(i,cog,self.team) return task.cont def _updateVictoryBar(self): if not ( hasattr(self, "_victoryBalanceBar") and self._victoryBalanceBar): return netDistance = 0 for cog in self.cogs: netDistance = netDistance + cog.targetDistance teamDistance = netDistance/6.0 self._victoryBalanceBarOrange.setScale(PartyGlobals.CogActivityBarStartScale + \ (teamDistance * 10 * PartyGlobals.CogActivityBarUnitScale),1.0,1.0) #self._victoryBalanceBar["value"] = 50 + (netDistance/6 * 100) self._victoryBalanceBarPie.setX(PartyGlobals.CogActivityVictoryBarPiePos[0] + \ (teamDistance * 10 *PartyGlobals.CogActivityBarPieUnitMove)) self._victoryBalanceBarPie.setY(PartyGlobals.CogActivityVictoryBarPiePos[1]) self._victoryBalanceBarPie.setZ(PartyGlobals.CogActivityVictoryBarPiePos[2]) if teamDistance>0.0: self._victoryBalanceBarArrow.setColor(PartyGlobals.CogActivityColors[1]) elif teamDistance<0.0: self._victoryBalanceBarArrow.setColor(PartyGlobals.CogActivityColors[0]) else: self._victoryBalanceBarArrow.setColor(VBase4(1.0,1.0,1.0,1.0)) def stopTrackingCogs(self): taskMgr.remove("trackCogs") def showAttackControls(self): if self._attackKeys.isHidden(): self._attackKeys.show() taskMgr.remove(self._attackIvalName) Sequence( ToontownIntervals.getPulseLargerIval(self._attackKeys, "", scale = 0.15), Wait(PartyGlobals.CogActivityControlsShowTime), Func(self.hideAttackControls), name=self._attackIvalName, autoFinish=1 ).start() def showMoveControls(self): if self._moveKeys.isHidden() and not self._attackKeys.isHidden(): self._moveKeys.show() taskMgr.remove(self._moveIvalName) Sequence( ToontownIntervals.getPulseLargerIval(self._moveKeys, "", scale = 0.15), Wait(PartyGlobals.CogActivityControlsShowTime), Func(self.hideMoveControls), name=self._moveIvalName, autoFinish=1 ).start() def hideAttackControls(self): taskMgr.remove(self._attackIvalName) if hasattr(self, "_attackKeys") and self._attackKeys: self._attackKeys.hide() def hideMoveControls(self): taskMgr.remove(self._moveIvalName) if hasattr(self, "_moveKeys") and self._moveKeys: self._moveKeys.hide() def hideControls(self): self.hideMoveControls() self.hideAttackControls()
class ThrowGag(Gag): def __init__(self, name, model, damage, hitSfx, splatColor, anim=None, scale=1): Gag.__init__(self, name, model, damage, GagType.THROW, hitSfx, anim=anim, scale=scale) self.splatScale = GagGlobals.splatSizes[self.name] self.splatColor = splatColor self.entities = [] self.timeout = 1.0 self.power = 50 self.powerBar = None self.tossPieStart = 0 self.pieSpeed = 0.2 self.pieExponent = 0.75 def setAvatar(self, avatar): Gag.setAvatar(self, avatar) if self.isLocal(): self.powerBar = DirectWaitBar(range=150, frameColor=(1, 1, 1, 1), barColor=(0.286, 0.901, 1, 1), relief=DGG.RAISED, borderWidth=(0.04, 0.04), pos=(0, 0, 0.85), scale=0.2, hpr=(0, 0, 0), parent=aspect2d, frameSize=(-0.85, 0.85, -0.12, 0.12)) self.powerBar.hide() def __getPiePower(self, time): elapsed = max(time - self.tossPieStart, 0.0) t = elapsed / self.pieSpeed t = math.pow(t, self.pieExponent) power = int(t * 150) % 300 if power > 150: power = 300 - power return power def build(self): if not self.gag: Gag.build(self) self.equip() if self.anim and self.gag: self.gag.loop('chan') return self.gag def start(self): super(ThrowGag, self).start() self.build() self.avatar.setPlayRate(self.playRate, 'pie') self.avatar.play('pie', fromFrame=0, toFrame=45) if self.isLocal(): taskMgr.remove("hidePowerBarTask" + str(hash(self))) self.powerBar.show() self.startPowerBar() def startPowerBar(self): self.tossPieStart = globalClock.getFrameTime() taskMgr.add(self.__powerBarUpdate, "powerBarUpdate" + str(hash(self))) def __powerBarUpdate(self, task): if self.powerBar is None: return task.done self.powerBar['value'] = self.__getPiePower(globalClock.getFrameTime()) return task.cont def stopPowerBar(self): taskMgr.remove("powerBarUpdate" + str(hash(self))) self.power = self.powerBar['value'] def __hidePowerBarTask(self, task): self.powerBar.hide() def throw(self): if self.isLocal(): self.stopPowerBar() self.power += 50 self.power = 250 - self.power print self.power # Make other toons set the throw power on my gag. base.localAvatar.sendUpdate('setThrowPower', [self.id, self.power]) self.startTimeout() taskMgr.doMethodLater(1.5, self.__hidePowerBarTask, "hidePowerBarTask" + str(hash(self))) self.avatar.play('pie', fromFrame=45, toFrame=90) if not self.gag: self.build() def setPower(self, power): self.power = power def release(self): Gag.release(self) base.audio3d.attachSoundToObject(self.woosh, self.gag) base.playSfx(self.woosh, node=self.gag) throwPath = NodePath('ThrowPath') throwPath.reparentTo(self.avatar) throwPath.setScale(render, 1) throwPath.setPos(0, self.power, -90) throwPath.setHpr(90, -90, 90) entity = self.gag if not entity: entity = self.build() entity.wrtReparentTo(render) entity.setHpr(throwPath.getHpr(render)) self.gag = None if not self.handJoint: self.handJoint = self.avatar.find('**/def_joint_right_hold') track = ProjectileInterval(entity, startPos=self.handJoint.getPos(render), endPos=throwPath.getPos(render), gravityMult=0.9, duration=3) event = self.avatar.uniqueName('throwIvalDone') + '-' + str( hash(entity)) track.setDoneEvent(event) base.acceptOnce(event, self.__handlePieIvalDone, [entity]) track.start() self.entities.append([entity, track]) if self.isLocal(): self.buildCollisions(entity) base.localAvatar.sendUpdate('usedGag', [self.id]) self.reset() def __handlePieIvalDone(self, pie): if not pie.isEmpty(): pie.removeNode() def handleSplat(self): base.audio3d.detachSound(self.woosh) if self.woosh: self.woosh.stop() self.buildSplat(self.splatScale, self.splatColor) base.audio3d.attachSoundToObject(self.hitSfx, self.splat) self.splat.reparentTo(render) self.splat.setPos(self.splatPos) base.playSfx(self.hitSfx, node=self.splat) self.cleanupEntity(self.splatPos) self.splatPos = None taskMgr.doMethodLater(0.5, self.delSplat, 'Delete Splat') return def cleanupEntity(self, pos): closestPie = None trackOfClosestPie = None pieHash2range = {} for entity, track in self.entities: if not entity.isEmpty(): pieHash2range[hash(entity)] = (entity.getPos(render) - pos).length() ranges = [] for distance in pieHash2range.values(): ranges.append(distance) ranges.sort() for pieHash in pieHash2range.keys(): distance = pieHash2range[pieHash] if not distance is None and distance == ranges[0]: for entity, track in self.entities: if hash(entity) == pieHash: closestPie = entity trackOfClosestPie = track break break if closestPie != None and trackOfClosestPie != None: if [closestPie, trackOfClosestPie] in self.entities: self.entities.remove([closestPie, trackOfClosestPie]) if not closestPie.isEmpty(): if isinstance(closestPie, Actor): closestPie.cleanup() closestPie.removeNode() def onCollision(self, entry): intoNP = entry.getIntoNodePath() avNP = intoNP.getParent() fromNP = entry.getFromNodePath().getParent() if fromNP.isEmpty(): return for key in base.cr.doId2do.keys(): obj = base.cr.doId2do[key] if obj.__class__.__name__ in CIGlobals.SuitClasses: if obj.getKey() == avNP.getKey(): obj.sendUpdate('hitByGag', [self.getID()]) elif obj.__class__.__name__ == "DistributedToon": if obj.getKey() == avNP.getKey(): if obj.getHealth() < obj.getMaxHealth(): if obj != self.avatar: self.avatar.sendUpdate( 'toonHitByPie', [obj.doId, self.getID()]) else: self.avatar.acceptOnce('gagSensor-into', self.onCollision) return elif obj.__class__.__name__ == "DistributedPieTurret": if obj.getKey() == avNP.getKey(): if obj.getHealth() < obj.getMaxHealth(): self.avatar.sendUpdate( 'toonHitByPie', [obj.doId, self.getID()]) self.splatPos = fromNP.getPos() self.avatar.sendUpdate('setSplatPos', [ self.getID(), self.splatPos.getX(), self.splatPos.getY(), self.splatPos.getZ() ]) self.handleSplat() def buildCollisions(self, entity): pieSphere = CollisionSphere(0, 0, 0, 1) pieSensor = CollisionNode('gagSensor') pieSensor.addSolid(pieSphere) pieNP = entity.attachNewNode(pieSensor) pieNP.setCollideMask(BitMask32(0)) pieNP.node().setFromCollideMask(CIGlobals.WallBitmask | CIGlobals.FloorBitmask) event = CollisionHandlerEvent() event.set_in_pattern("%fn-into") event.set_out_pattern("%fn-out") base.cTrav.add_collider(pieNP, event) self.avatar.acceptOnce('gagSensor-into', self.onCollision) def unEquip(self): taskMgr.remove("hidePowerBarTask" + str(hash(self))) if self.powerBar: self.powerBar.hide() Gag.unEquip(self) def delete(self): taskMgr.remove("powerBarUpdate" + str(hash(self))) taskMgr.remove("hidePowerBarTask" + str(hash(self))) if self.powerBar: self.powerBar.destroy() self.powerBar = None Gag.delete(self)