def initIntervals(self): self.baseSpinDuration = 1.0 self.propellerSpinLerp = LerpFunctionInterval(self.propeller.setH, fromData=0.0, toData=360.0, duration=self.baseSpinDuration, name='%s.propellerSpinLerp-%s' % (self.__class__.__name__, self.toon.doId)) singleBlinkTime = Globals.Gameplay.TargetedWarningSingleBlinkTime blinkTime = Globals.Gameplay.TargetedWarningBlinkTime self.blinkLoop = Sequence(Wait(singleBlinkTime / 2.0), Func(self.setBackpackTexture, Globals.Gameplay.BackpackStates.Attacked), Wait(singleBlinkTime / 2.0), Func(self.setBackpackTexture, Globals.Gameplay.BackpackStates.Targeted), name='%s.blinkLoop-%s' % (self.__class__.__name__, self.toon.doId)) self.blinkWarningSeq = Sequence(Func(self.blinkLoop.loop), Wait(blinkTime), Func(self.blinkLoop.clearToInitial), name='%s.blinkWarningSeq-%s' % (self.__class__.__name__, self.toon.doId)) dur = Globals.Gameplay.BackpackRefuelDuration self.refuelSeq = Sequence(Func(self.setPropellerSpinRate, Globals.Gameplay.RefuelPropSpeed), Wait(dur), Func(self.returnBackpackToLastStateFunc), name='%s.refuelSeq-%s' % (self.__class__.__name__, self.toon.doId)) scale = self.redTapeRing.getScale() pulseTime = 1.0 self.pulseBubbleSeq = Parallel(Sequence(LerpFunctionInterval(self.redTapeRing.setScale, fromData=scale, toData=scale * 1.1, duration=pulseTime / 2.0, blendType='easeInOut'), LerpFunctionInterval(self.redTapeRing.setScale, fromData=scale * 1.1, toData=scale, duration=pulseTime / 2.0, blendType='easeInOut')), LerpHprInterval(self.redTapeRing, pulseTime, Vec3(360, 0, 0), startHpr=Vec3(0, 0, 0)), name='%s.pulseBubbleSeq-%s' % (self.__class__.__name__, self.toon.doId)) bouncePercent = 1.2 scaleTime = 0.5 scaleBounceTime = 0.25 self.popUpBubbleLerp = LerpScaleInterval(self.redTapeRing, scaleTime, scale * bouncePercent, startScale=0.0, blendType='easeInOut') self.popUpBubbleSeq = Sequence(Func(self.updateLerpStartScale, self.popUpBubbleLerp, self.redTapeRing), Func(self.redTapeRing.show), self.popUpBubbleLerp, LerpScaleInterval(self.redTapeRing, scaleBounceTime, scale, startScale=scale * bouncePercent, blendType='easeInOut'), Func(self.pulseBubbleSeq.loop), name='%s.popUpBubbleSeq-%s' % (self.__class__.__name__, self.toon.doId)) self.removeBubbleLerp = LerpScaleInterval(self.redTapeRing, scaleBounceTime, scale * bouncePercent, startScale=scale, blendType='easeInOut') self.removeBubbleSeq = Sequence(Func(self.pulseBubbleSeq.clearToInitial), Func(self.updateLerpStartScale, self.removeBubbleLerp, self.redTapeRing), self.removeBubbleLerp, LerpScaleInterval(self.redTapeRing, scaleTime, 0.0, startScale=scale * bouncePercent, blendType='easeInOut'), Func(self.redTapeRing.hide), name='%s.removeBubbleSeq-%s' % (self.__class__.__name__, self.toon.doId)) self.redTapeRing.setScale(0.0) self.deathInterval = Sequence(Parallel(LerpHprInterval(self.toon, 1.0, Vec3(720, 0, 0)), LerpFunctionInterval(self.toon.setScale, fromData=1.0, toData=0.1, duration=1.0)), Func(self.toon.stash), name='%s.deathInterval-%s' % (self.__class__.__name__, self.toon.doId)) self.spawnInterval = Sequence(Func(self.toon.stash), Func(self.resetToon), Wait(1.0), Func(self.toon.setAnimState, 'TeleportIn'), Func(self.toon.unstash), name='%s.spawnInterval-%s' % (self.__class__.__name__, self.toon.doId)) singleBlinkTime = Globals.Gameplay.InvulSingleBlinkTime blinkTime = Globals.Gameplay.InvulBlinkTime invulBuffTime = Globals.Gameplay.InvulBuffTime self.blinkBubbleLoop = Sequence(LerpFunctionInterval(self.redTapeRing.setAlphaScale, fromData=1.0, toData=0.0, duration=singleBlinkTime / 2.0, blendType='easeInOut'), LerpFunctionInterval(self.redTapeRing.setAlphaScale, fromData=0.0, toData=1.0, duration=singleBlinkTime / 2.0, blendType='easeInOut'), name='%s.blinkBubbleLoop-%s' % (self.__class__.__name__, self.toon.doId)) self.blinkBubbleSeq = Sequence(Wait(invulBuffTime - blinkTime), Func(self.blinkBubbleLoop.loop), Wait(blinkTime), Func(self.blinkBubbleLoop.finish), name='%s.blinkBubbleSeq-%s' % (self.__class__.__name__, self.toon.doId))
def load(self): CogdoGameMovie.load(self) def showDoor(): base.camera.wrtReparentTo(render) base.camera.setPos(self._exit, 0, -55, 40) base.camera.lookAt(self._exit, 0, 0, -20) self._exit.open() exitDur = 1.0 showExitIval = Sequence( Func(base.camera.wrtReparentTo, render), Parallel( base.camera.posInterval(exitDur, Point3(0, -55, 40), other=self._exit, blendType='easeInOut'), base.camera.hprInterval(exitDur, Point3(0, -45, 0), blendType='easeInOut'))) def showPlayersLeaving(): for player in self._players: self._exit.toonEnters(player.toon) self._ival = Sequence( showExitIval, Func(self._exit.open), Func(showPlayersLeaving), Wait(Globals.Gameplay.FinishDurationSeconds - exitDur - 1.0), Func(base.transitions.irisOut), Wait(1.0))
def getToonPullingLeverInterval(self, toon): walkTime = 0.2 reach = ActorInterval(toon, 'leverReach', playRate=2.0) pull = ActorInterval(toon, 'leverPull', startFrame=6) origPos = toon.getPos(render) origHpr = toon.getHpr(render) newPos = self.lever.getPos(render) newHpr = self.lever.getHpr(render) origHpr.setX(PythonUtil.fitSrcAngle2Dest(origHpr[0], newHpr[0])) toon.setPosHpr(origPos, origHpr) reachAndPull = Sequence( ActorInterval(toon, 'walk', loop=True, duration=walkTime - reach.getDuration()), reach, pull) leverSeq = Sequence( Wait(walkTime + reach.getDuration() - 0.1), self.stick.hprInterval(0.55, Point3(0.0, 25.0, 0.0), Point3(0.0, 0.0, 0.0)), Wait(0.3), self.stick.hprInterval(0.4, Point3(0.0, 0.0, 0.0), Point3(0.0, 25.0, 0.0))) returnSeq = Sequence( Parallel(toon.posInterval(walkTime, newPos, origPos), toon.hprInterval(walkTime, newHpr, origHpr), leverSeq, reachAndPull)) return returnSeq
def setup_manual_sequence(self): # print 'setup manual sequence' all_intervals = self.create_intervals() # functions to use in sequences: plot_eye = Func(send_start_plot, check_eye=False) square_move = Func(self.square.move_for_manual_position) write_to_file_move = Func(self.write_to_file, index=0) square_on = Func(self.square.turn_on) write_to_file_on = Func(self.write_to_file, index=1) square_fade = Func(self.square.fade) write_to_file_fade = Func(self.write_to_file, index=2) square_off = Func(self.square.turn_off) write_to_file_off = Func(self.write_to_file, index=3) give_reward = Func(send_message, 'reward') write_to_file_reward = Func(self.write_to_file, index=4) clear_screen = Func(send_message, 'clear') cleanup = Func(self.send_cleanup) # Parallel does not wait for tasks to return before returning itself, which # works out pretty awesome, since move interval is suppose to be time from reward start # until next trial self.manual_sequence = Sequence( Parallel(square_move, write_to_file_move, plot_eye), Parallel(square_on, write_to_file_on), Wait(all_intervals[0]), Parallel(square_fade, write_to_file_fade), Wait(all_intervals[1]), Parallel(square_off, write_to_file_off), Wait(all_intervals[2]), Parallel(give_reward, write_to_file_reward), Wait(all_intervals[3]), Parallel(clear_screen, cleanup), )
def load(self): CogdoGameMovie.load(self) self.toonDNA = ToonDNA.ToonDNA() self.toonDNA.newToonFromProperties('dss', 'ss', 'm', 'm', 2, 0, 2, 2, 1, 8, 1, 8, 1, 14) self.toonHead = Toon.Toon() self.toonHead.setDNA(self.toonDNA) self.makeSuit('sc') self.toonHead.getGeomNode().setDepthWrite(1) self.toonHead.getGeomNode().setDepthTest(1) self.toonHead.loop('neutral') self.toonHead.setPosHprScale(-0.73, 0, -1.27, 180, 0, 0, 0.18, 0.18, 0.18) self.toonHead.reparentTo(hidden) self.toonHead.startBlink() self.cogHead = Suit.Suit() self.cogDNA = SuitDNA.SuitDNA() self.cogDNA.newSuit('le') self.cogHead.setDNA(self.cogDNA) self.cogHead.getGeomNode().setDepthWrite(1) self.cogHead.getGeomNode().setDepthTest(1) self.cogHead.loop('neutral') self.cogHead.setPosHprScale(-0.74, 0, -1.79, 180, 0, 0, 0.12, 0.14, 0.14) self.cogHead.reparentTo(hidden) self.clipPlane = self.toonHead.attachNewNode(PlaneNode('clip')) self.clipPlane.node().setPlane(Plane(0, 0, 1, 0)) self.clipPlane.setPos(0, 0, 2.45) audioMgr = base.cogdoGameAudioMgr self._cogDialogueSfx = audioMgr.createSfx('cogDialogue') self._toonDialogueSfx = audioMgr.createSfx('toonDialogue') def start(): camera.wrtReparentTo(render) self._startUpdateTask() def end(): self._stopUpdateTask() introDuration = Globals.Gameplay.IntroDurationSeconds dialogue = TTLocalizer.CogdoFlyingIntroMovieDialogue waitDur = introDuration / len(dialogue) flyDur = introDuration - waitDur * 0.5 flyThroughIval = Parallel( camera.posInterval(flyDur, self._exit.getPos(render) + Point3(0, -22, 1), blendType='easeInOut'), camera.hprInterval(flyDur, Point3(0, 5, 0), blendType='easeInOut')) self._ival = Sequence( Func(start), Parallel( flyThroughIval, Sequence( Func(self.displayLine, 'cog', self._getRandomLine(dialogue[0])), Wait(waitDur), Func(self.displayLine, 'toon', self._getRandomLine(dialogue[1])), Wait(waitDur), Func(self.displayLine, 'cog', self._getRandomLine(dialogue[2])), Wait(waitDur))), Func(end))
def __showSplat(self, position, direction, hot=False): if self.kaboomTrack is not None and self.kaboomTrack.isPlaying(): self.kaboomTrack.finish() self.clearHitInterval() splatName = 'splat-creampie' self.splat = globalPropPool.getProp(splatName) self.splat.setBillboardPointEye() self.splat.reparentTo(render) self.splat.setPos(self.root, position) self.splat.setAlphaScale(1.0) if not direction == 1.0: self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[0]) if self.currentFacing > 0.0: facing = 'HitFront' else: facing = 'HitBack' else: self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[1]) if self.currentFacing > 0.0: facing = 'HitBack' else: facing = 'HitFront' if hot: targetscale = 0.75 part = 'head' else: targetscale = 0.5 part = 'body' def setSplatAlpha(amount): self.splat.setAlphaScale(amount) self.hitInterval = Sequence( ActorInterval(self.actor, part + facing, loop=0), Func(self.actor.loop, 'idle')) self.hitInterval.start() self.kaboomTrack = Parallel( SoundInterval(self.pieHitSound, volume=1.0, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), Sequence( Func(self.splat.showThrough), Parallel( Sequence( LerpScaleInterval(self.splat, duration=0.175, scale=targetscale, startScale=Point3(0.1, 0.1, 0.1), blendType='easeOut'), Wait(0.175)), Sequence( Wait(0.1), LerpFunc(setSplatAlpha, duration=1.0, fromData=1.0, toData=0.0, blendType='easeOut'))), Func(self.splat.cleanup), Func(self.splat.removeNode))) self.kaboomTrack.start() return
def initLocalPlayerIntervals(self): self.coolDownAfterHitInterval = Sequence(Wait(Globals.Gameplay.HitCooldownTime), Func(self.setEnemyHitting, False), name='coolDownAfterHitInterval-%i' % self.toon.doId) self.deathInterval = Sequence(Func(self.resetVelocities), Parallel(Parallel(Func(self._deathSfx.play), LerpHprInterval(self.toon, 1.0, Vec3(720, 0, 0)), LerpFunctionInterval(self.toon.setScale, fromData=1.0, toData=0.1, duration=1.0), self.toon.posInterval(0.5, Vec3(0, 0, -25), other=self.toon)), Sequence(Wait(0.5), Func(base.transitions.irisOut))), Func(self.toon.stash), Wait(1.0), Func(self.toonSpawnFunc), name='%s.deathInterval' % self.__class__.__name__) self.outOfTimeInterval = Sequence(Func(messenger.send, CogdoFlyingLocalPlayer.PlayWaitingMusicEventName), Func(self._loseSfx.play), Func(base.transitions.irisOut), Wait(1.0), Func(self.resetVelocities), Func(self._guiMgr.setMessage, '', transition=None), Func(self.toon.stash), Func(self.toonSpawnFunc), name='%s.outOfTimeInterval' % self.__class__.__name__) self.spawnInterval = Sequence(Func(self.resetToonFunc), Func(self._cameraMgr.update, 0.0), Func(self._level.update), Func(self.toon.cnode.broadcastPosHprFull), Func(base.transitions.irisIn), Wait(0.5), Func(self.toon.setAnimState, 'TeleportIn'), Func(self.toon.unstash), Wait(1.5), Func(self.requestPostSpawnState), name='%s.spawnInterval' % self.__class__.__name__) self.waitingForWinInterval = Sequence(Func(self._guiMgr.setMessage, TTLocalizer.CogdoFlyingGameWaiting % '.'), Wait(1.5), Func(self._guiMgr.setMessage, TTLocalizer.CogdoFlyingGameWaiting % '..'), Wait(1.5), Func(self._guiMgr.setMessage, TTLocalizer.CogdoFlyingGameWaiting % '...'), Wait(1.5), name='%s.waitingForWinInterval' % self.__class__.__name__) self.waitingForWinSeq = Sequence(Func(self.setWaitingForWinState), Wait(4.0), Func(self.removeAllMemos), Wait(2.0), Func(self.game.distGame.d_sendRequestAction, Globals.AI.GameActions.LandOnWinPlatform, 0), Func(self.playWaitingForWinInterval), name='%s.waitingForWinSeq' % self.__class__.__name__) self.winInterval = Sequence(Func(self._guiMgr.setMessage, ''), Wait(4.0), Func(self.game.distGame.d_sendRequestAction, Globals.AI.GameActions.WinStateFinished, 0), name='%s.winInterval' % self.__class__.__name__) self.goSadSequence = Sequence(Wait(2.5), Func(base.transitions.irisOut, 1.5), name='%s.goSadSequence' % self.__class__.__name__) self.introGuiSeq = Sequence(Wait(0.5), Parallel(Func(self._guiMgr.setTemporaryMessage, TTLocalizer.CogdoFlyingGameMinimapIntro, duration=5.0), Sequence(Wait(1.0), Func(self._guiMgr.presentProgressGui))), Wait(5.0), Func(self._guiMgr.setMessage, TTLocalizer.CogdoFlyingGamePickUpAPropeller), name='%s.introGuiSeq' % self.__class__.__name__)
def load(self): CogdoGameMovie.load(self) self._ival = Sequence() if not self._exit.hasPlayer(self._localPlayer): loseSfx = base.cogdoGameAudioMgr.createSfx('lose') self._ival.append( Sequence(Func(loseSfx.play), Func(self._localPlayer.toon.setAnimState, 'Sad'))) self._ival.append( Sequence(Wait(Globals.FinishDurationSeconds - 1.0), Func(base.transitions.irisOut), Wait(1.0)))
def setup_auto_sequences(self, good_trial): # print 'setup auto sequences' # print self.square.square.getPos() # making two "sequences", although one is just a parallel task # auto sequence is going to start with square fading all_intervals = self.create_intervals() if good_trial: self.square_position = None # print 'good trial? ', good_trial # print 'did square position change? ', self.square_position # functions used in sequence plot_eye = Func(send_start_plot, check_eye=False) watch_eye_timer = Func(send_start_plot, check_eye=True, timer=True) watch_eye = Func(send_start_plot, check_eye=True) square_move = Func(self.square.move, self.square_position) write_to_file_move = Func(self.write_to_file, index=0) square_on = Func(self.square.turn_on) write_to_file_on = Func(self.write_to_file, index=1) write_to_file_fix = Func(self.write_to_file, index=5) square_fade = Func(self.square.fade) write_to_file_fade = Func(self.write_to_file, index=2) square_off = Func(self.square.turn_off) write_to_file_off = Func(self.write_to_file, index=3) give_reward = Func(send_message, 'reward') write_to_file_reward = Func(self.write_to_file, index=4) clear_fix = Func(send_message, 'clear_fix') clear_screen = Func(send_message, 'clear') cleanup = Func(self.send_cleanup) # we don't know how long the wait period should be for square on, # because that wait period doesn't start until fixation, and we don't # know when that will happen. So make two sequences, so wait period # is flexible # create the first sequence. self.auto_sequence_one = Sequence( Parallel(square_move, write_to_file_move), Parallel(square_on, write_to_file_on, watch_eye_timer)) # Parallel does not wait for any doLaterMethods to return before returning itself, which # works out pretty awesome, since move interval is suppose to be time from reward start # until next trial. This would be a problem if there was so much reward that it took up # all of the time for the move_interval, but that would be a lot of reward # print('pump delay', self.config['PUMP_DELAY']) # print('beeps', self.num_beeps) self.auto_sequence_two = Sequence( Parallel(write_to_file_fix, watch_eye), Wait(all_intervals[4]), Func(self.stop_plot_eye_task), Parallel(square_fade, write_to_file_fade, plot_eye), Wait(all_intervals[1]), Parallel(square_off, write_to_file_off), Wait(all_intervals[2]), Parallel(give_reward, write_to_file_reward, clear_fix), Wait(all_intervals[3]), Parallel(clear_screen, cleanup))
def showResults(self, resultsText, winner, totals): if self.player is None: return None base.localAvatar.showName() self.resultsIval = Sequence( Wait(0.1), Func(self.activity.setStatus, TTLocalizer.PartyCogTimeUp), Func(self.activity.showStatus), Wait(2.0), Func(self.activity.hideStatus), Wait(0.5), Func(self.player.lookAtArena), Func(self.showTeamFlags, self.activity.getTeam(base.localAvatar.doId)), Wait(1.0), Func(self.showArrow, 0), Wait(1.3), Func(self.showArrow, 1), Wait(1.3), Func(self.showArrow, 2), Wait(1.3), Func(self.showTotals, totals), Wait(1.0), Func(self.showWinner, resultsText, winner), Func(self._cleanupResultsIval), name='PartyCog-conclusionSequence') self.accept('DistributedPartyActivity-showJellybeanReward', self._cleanupResultsIval) self.resultsIval.start()
def showResults(self, resultsText, winner, totals): if self.player is None: return base.localAvatar.showName() self.resultsIval = Sequence( Wait(0.1), Func(self.activity.setStatus, TTLocalizer.PartyCogTimeUp), Func(self.activity.showStatus), Wait(2.0), Func(self.activity.hideStatus), Wait(0.5), Func(self.player.lookAtArena), Func(self.showTeamFlags, self.activity.getTeam(base.localAvatar.doId)), Wait(1.0), Func(self.showArrow, 0), Wait(1.3), Func(self.showArrow, 1), Wait(1.3), Func(self.showArrow, 2), Wait(1.3), Func(self.showTotals, totals), Wait(1.0), Func(self.showWinner, resultsText, winner), Func(self._cleanupResultsIval), name="PartyCog-conclusionSequence") # Cancel the rewards ival if the jellybean screen pops up. If this happens it means the client # is lagging; the rewards screen tears down the GUI, which this ival uses. self.accept('DistributedPartyActivity-showJellybeanReward', self._cleanupResultsIval) self.resultsIval.start()
def hit(self): hitInterval = Sequence(Func(self.golem.setColorScale, 1, 0, 0, 0.75), Wait(0.15), Func(self.golem.clearColorScale), Wait(0.15), Func(self.golem.setColorScale, 1, 0, 0, 0.75), Wait(0.15), Func(self.golem.clearColorScale), Wait(0.15), Func(self.golem.setColorScale, 1, 0, 0, 0.75), Wait(0.15), Func(self.golem.clearColorScale), Wait(0.15), Func(self.golem.setColorScale, 1, 0, 0, 0.75), Wait(0.15), Func(self.golem.clearColorScale), Wait(0.15)) self.health -= 1 if self.health == 4: self.trackerObject.setColor(0, 1, 0) hitInterval.start() elif self.health == 3: self.trackerObject.setColor(0.25, 0.75, 0) hitInterval.start() elif self.health == 2: self.trackerObject.setColor(0.5, .5, 0) hitInterval.start() elif self.health == 1: self.trackerObject.setColor(0.75, 0.25, 0) hitInterval.start() elif self.health == 0: self.trackerObject.setColor(0, 0, 0) self.request("Destroyed")
def __showSplat(self, position): """Show the splat graphic and sound.""" if self.kaboomTrack is not None and self.kaboomTrack.isPlaying(): self.kaboomTrack.finish() splatName = 'splat-creampie' self.splat = globalPropPool.getProp(splatName) self.splat.setBillboardPointEye() self.splat.reparentTo(render) self.splat.setPos(self.toon, position) self.splat.setY( self.toon, bound(self.splat.getY(), self.toon.getHeight() / 2.0, position.getY())) self.splat.setAlphaScale(1.0) targetscale = 0.75 def setSplatAlpha(amount): self.splat.setAlphaScale(amount) self.kaboomTrack = Parallel( SoundInterval(self.pieHitSound, node=self.toon, volume=1.0, cutOff=PartyGlobals.PARTY_COG_CUTOFF), Sequence( Func(self.splat.showThrough), Parallel( Sequence( LerpScaleInterval(self.splat, duration=0.175, scale=targetscale, startScale=Point3(0.1, 0.1, 0.1), blendType="easeOut"), Wait(0.175), ), Sequence( Wait(0.1), LerpFunc(setSplatAlpha, duration=1.0, fromData=1.0, toData=0.0, blendType="easeOut"))), Func(self.splat.cleanup), Func(self.splat.removeNode), )) self.kaboomTrack.start()
def __init__(self, whl_pos, whl_radius, car_h): GameObject.__init__(self) self.radius = whl_radius v_f = GeomVertexFormat.getV3() vdata = GeomVertexData('skid', v_f, Geom.UHDynamic) prim = GeomTriangles(Geom.UHStatic) self.vtx_cnt = 1 self.last_pos = whl_pos geom = Geom(vdata) geom.add_primitive(prim) self.node = GeomNode('gnode') self.node.add_geom(geom) nodepath = self.eng.gfx.root.attach_node(self.node) nodepath.set_transparency(True) nodepath.set_depth_offset(1) nodepath.node.set_two_sided(True) # for self-shadowing issues self.__set_material(nodepath) nodepath.p3dnode.set_bounds(OmniBoundingVolume()) self.add_vertices(whl_radius, car_h) self.add_vertices(whl_radius, car_h) def alpha(time, n_p): if not n_p.is_empty: n_p.node.set_shader_input('alpha', time) # this if seems necessary since, if there are skidmarks and you # exit from the race (e.g. back to the menu), then alpha is being # called from the interval manager even if the interval manager # correctly says that there are 0 intervals. self.remove_seq = Sequence( Wait(8), LerpFunc(alpha, 8, .5, 0, 'easeInOut', [nodepath]), Func(nodepath.remove_node)) self.remove_seq.start()
def loseGame(self, entry): # The triggers are set up so that the center of the ball should move to the # collision point to be in the hole global action action = "start" toPos = entry.getInteriorPoint(render) taskMgr.remove('rollTask') # Stop the maze task self.pathFollowed = np.zeros(self.pm.shape) self.maze.setP(0) self.maze.setR(0) # Move the ball into the hole over a short sequence of time. Then wait a # second and call start to reset the game Sequence( Parallel( LerpFunc(self.ballRoot.setX, fromData=self.ballRoot.getX(), toData=toPos.getX(), duration=.1), LerpFunc(self.ballRoot.setY, fromData=self.ballRoot.getY(), toData=toPos.getY(), duration=.1), LerpFunc(self.ballRoot.setZ, fromData=self.ballRoot.getZ(), toData=self.ballRoot.getZ() - .9, duration=.2)), Wait(1), Func(self.start)).start()
def __handleCannonHit(self, collisionEntry): if not self.gag: return self.notify.info('__handleCannonHit') #if == None or self.flyColNode == None: # return interPt = collisionEntry.getSurfacePoint(render) hitNode = collisionEntry.getIntoNode().getName() fromNodePath = collisionEntry.getFromNodePath() intoNodePath = collisionEntry.getIntoNodePath() print('Pie hit: {0}'.format(hitNode)) self.__stopFlyTask() self.__stopCollisionHandler(self.gag) track = Sequence() track.append(self.__hitSomething(hitNode)) track.append(Func(self.setReloading, True)) track.append(Wait(0.2)) track.append(Func(self.setReloading, False)) track.append(Func(self.setLanded)) if self.hitTrack: self.hitTrack.finish() self.hitTrack = track self.hitTrack.start()
def setup_photo_sequences(self): # start with cross hair, treat like fixation point, so first wait for fixation watch_eye = Func(self.start_plot_eye_task, check_eye=True) watch_eye_timer = Func(self.start_plot_eye_task, check_eye=True, timer=True) cross_on = Func(self.show_cross_hair) write_to_file_cross_on = Func(self.write_to_file, 'Cross on') write_to_file_fix = Func(self.write_to_file, 'Fixated') cross_off = Func(self.clear_cross_hair) write_to_file_cross_off = Func(self.write_to_file, 'Cross off') cross_interval = random.uniform(*self.cross_hair_int) photo_on = Func(self.show_photo) write_to_file_photo_on = Func(self.write_to_file, 'Photo on', self.photo_path) set_photo_timer = Func(self.set_photo_timer) self.cross_sequence = Parallel(cross_on, write_to_file_cross_on, watch_eye_timer) self.photo_sequence = Sequence( Parallel(write_to_file_fix, watch_eye), Wait(cross_interval), Func(self.stop_plot_eye_task), Parallel(cross_off, write_to_file_cross_off, watch_eye), Parallel(photo_on, write_to_file_photo_on, set_photo_timer))
def singleTargetAttack (caster, targetPos, damage, tileMap, attackClass, isServer): """ Makes caster attack target, inflicting damage. Drains energy on activation. """ target = tileMap.getCreatureAtPos(targetPos) # Safety check: if target == None: return attackSequence = Sequence() # Create a new Sequence # Check for energy availability: attackSequence.append(Func(checkDrainEnergy, caster, attackClass.getEnergyCost)) attackSequence.append(Wait(0.1)) # TODO Figure out a better way to delay until the above check completes # Deal damage server-side and sync: if isServer: # If initiated on the server, deal damage: attackSequence.append(Func(inflictDamage, [target], damage)) attackSequence.append(Func(playAttackAnim, caster, targetPos)) attackSequence.append(Func(syncAction, caster, BasicAttack.actionID, targetCID=target.getCID(), damage=damage)) attackSequence.append(Func(endAction, caster)) # Apply end signal to action. caster.startAction(attackSequence)
def hourChange(self, currentHour): currentHour = currentHour % 12 if currentHour == 0: currentHour = 12 self.hourSoundInterval = Parallel() seq1 = Sequence() for i in range(currentHour): seq1.append(SoundInterval(self.clockSounds[i])) seq1.append(Wait(0.2)) timeForEachDeformation = seq1.getDuration() / currentHour seq2 = Sequence() for i in range(currentHour): seq2.append( self.clockFlat.scaleInterval(timeForEachDeformation / 2.0, Vec3(0.9, 1.0, 1.2), blendType='easeInOut')) seq2.append( self.clockFlat.scaleInterval(timeForEachDeformation / 2.0, Vec3(1.2, 1.0, 0.9), blendType='easeInOut')) seq2.append( self.clockFlat.scaleInterval(timeForEachDeformation / 2.0, Vec3(1.0, 1.0, 1.0), blendType='easeInOut')) self.hourSoundInterval.append(seq1) self.hourSoundInterval.append(seq2) self.hourSoundInterval.start()
def showHitScore(self, number, scale=1): if number <= 0: return if self.hpText: self.hideHitScore() self.HpTextGenerator.setFont(ToontownGlobals.getSignFont()) if number < 0: self.HpTextGenerator.setText(str(number)) else: self.HpTextGenerator.setText('+' + str(number)) self.HpTextGenerator.clearShadow() self.HpTextGenerator.setAlign(TextNode.ACenter) r = 1 g = 1 b = 0 a = 1 self.HpTextGenerator.setTextColor(r, g, b, a) self.hpTextNode = self.HpTextGenerator.generate() self.hpText = render.attachNewNode(self.hpTextNode) self.hpText.setScale(scale) self.hpText.setBillboardPointEye() self.hpText.setBin('fixed', 100) self.hpText.setPos(self.root, 0, 0, self.height / 2) seq = Sequence( self.hpText.posInterval( 0.25, Point3(self.root.getX(render), self.root.getY(render), self.root.getZ(render) + self.height + 1.0), blendType='easeOut'), Wait(0.25), self.hpText.colorInterval(0.1, Vec4(r, g, b, 0)), Func(self.hideHitScore)) seq.start()
def __init__(self, wheel_pos, radius, heading): self.radius = radius v_f = GeomVertexFormat.getV3() self.vdata = GeomVertexData('skid', v_f, Geom.UHDynamic) self.vdata.setNumRows(1) self.vertex = GeomVertexWriter(self.vdata, 'vertex') self.prim = GeomTriangles(Geom.UHStatic) self.cnt = 1 self.last_pos = wheel_pos geom = Geom(self.vdata) geom.addPrimitive(self.prim) node = GeomNode('gnode') node.addGeom(geom) nodePath = render.attachNewNode(node) nodePath.setTransparency(True) nodePath.setDepthOffset(1) self.__set_material(nodePath) nodePath.node().setBounds(OmniBoundingVolume()) self.add_vertices(radius, heading) self.add_vertices(radius, heading) self.remove_seq = Sequence( Wait(8), LerpFunc(nodePath.setAlphaScale, 8, 1, 0, 'easeInOut'), Func(nodePath.remove_node)) self.remove_seq.start()
def play(self, name, fps=30.0, sync=True): """Play the 'name' animation ONCE at 'fps' frames per second speed. if sync is False the animation will start at a random frame """ self.loop(name, fps, sync) time = float(self.animations[name][1]) / float(fps) self.seq = Sequence(Wait(time), Func(self.stop)) self.seq.start()
def __noDanceMoveMatch(self): self.gui.setColor(1, 0, 0) self.gui.showText('No Match!') self.__updateLocalToonState(ToonDancingStates.DanceMove) self.localToonDanceSequence = Sequence( Func(self.__localDisableControls), Wait(1.0), Func(self.__localEnableControls)) self.localToonDanceSequence.start()
def _hideFlashMessage( self, duration=0.0 ): if self.isDisabled(): assert self.notify.debug("_hideFlashMessage we're disabled, but still hiding self.flashText") # return self.flashTextInterval = Sequence(Wait( duration ), LerpFunc( self.flashText.setAlphaScale, fromData=1.0, toData=0.0, duration=1.0 ), Func( self.flashText.stash ),) self.flashTextInterval.start()
def turnWallNotification(self): #give a notification sequence at the beginning notificationSeq = Sequence() notificationSeq.append(Func(addNotification,""" If you just see a blank color, it means you are facing a wall :)""")) notificationSeq.append(Wait(8)) notificationSeq.append(Func(deleteNotifications)) notificationSeq.start()
def transition_enter(self): self.update_texts() for wdg in self.widgets: pos = wdg.get_pos() start_pos = (pos[0] - 3.6, pos[1], pos[2]) wdg.set_pos(start_pos) Sequence(Wait(abs(pos[2] - 1) / 4), LerpPosInterval(wdg, .5, pos, blendType='easeInOut')).start() self.enable()
def _hideFlashMessage(self, duration=0.0): if self.isDisabled(): pass self.flashTextInterval = Sequence( Wait(duration), LerpFunc(self.flashText.setAlphaScale, fromData=1.0, toData=0.0, duration=1.0), Func(self.flashText.stash)) self.flashTextInterval.start()
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 __activateChest(self): for box, value in self.boxControls.iteritems(): if self.activeBox == box.getParent().getName(): if value[0].getFrame() != 0: return if self.chestLogic[self.activeBox] == "GET_Key": self.key.show() self.key.setPos(box.getParent().getPos()) self.key.setZ(self.key.getZ() + 0.5) self.key.setHpr(box.getParent().getHpr()) self.key.setH(self.key.getH() + 90.0) keyRisingInterval = self.key.posInterval(1.5, Point3(self.key.getX(), self.key.getY(), self.key.getZ() + 1.0)) keyRotationInterval = self.key.hprInterval(3.0, Vec3(self.key.getH() + 360*2, 0, 0)) keyAnimation = Parallel(keyRisingInterval, keyRotationInterval, name="keyAnimation") boxAnimation = AnimControlInterval(value[0]) chestFullAnimation = Sequence( boxAnimation, keyAnimation, Wait(0.25), Func(self.key.hide), Func(self.addKey)) elif self.chestLogic[self.activeBox] == "GET_Artifact": self.artifact.show() self.artifact.setPos(box.getParent().getPos()) self.artifact.setZ(self.artifact.getZ() + 0.5) artifactRisingInterval = self.artifact.posInterval( 1.5, Point3(self.artifact.getX(), self.artifact.getY(), self.artifact.getZ() + 1.0)) artifactRotationInterval = self.artifact.hprInterval( 3.0, Vec3(self.artifact.getH() + 360*2, 0, 0)) artifactAnimation = Parallel( artifactRisingInterval, artifactRotationInterval, name="artifactAnimation") boxAnimation = AnimControlInterval(value[0]) chestFullAnimation = Sequence( boxAnimation, artifactAnimation, Wait(0.25), Func(self.artifact.hide), Func(self.getArtifact)) chestFullAnimation.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 getSceneReady(self): '''Get if the scene is ready''' textbox_ready = False view_ready = False intervals_ready = True if not self.gameTextBox.getIsWaiting(): textbox_ready = True if not self.storyView.getIsWaiting(): view_ready = True for itv in self.intervals: if itv.isPlaying(): intervals_ready = False break scene_ready = textbox_ready and view_ready and intervals_ready if not scene_ready: return False #auto play span if scene_ready and self.__autoplaying: if self.__autoplaystep != self.step: self.__autoplaystep = self.step self.__autoInterval = Wait(runtime_data.game_settings['auto_span']) self.__autoInterval.start() scene_ready = False else: if self.__autoInterval.isPlaying(): scene_ready = False if self.audioPlayer.isVoicePlaying(): scene_ready = False return scene_ready
class StoryManager(SogalForm): """Story controller of Sogal Controls the whole story scene. Mainly for logic control And graphics is on other Attributes: gameTextBox: the current GameTextBox, useful for user scripting storyView: the current StoryView, useful for user scripting """ script_space = {} _currentDump = None __destroyed = False def __init__(self): self.step = 0 #shows how many commands line it had run self.scrStack = [] self.commandList = [] self.__currentPtr = None if not runtime_data.RuntimeData.command_ptr: self.nextPtr = 0 else: self.nextPtr = runtime_data.RuntimeData.command_ptr if not runtime_data.RuntimeData.command_stack: runtime_data.RuntimeData.command_stack = self.scrStack else: self.scrStack = runtime_data.RuntimeData.command_stack if not runtime_data.RuntimeData.command_list: runtime_data.RuntimeData.command_list = self.commandList else: self.commandList = runtime_data.RuntimeData.command_list self._frame = DirectFrame(parent = aspect2d) # @UndefinedVariable pydev在傲娇而已不用管 self._frame.setTransparency(TransparencyAttrib.MAlpha) self.storyView = StoryView() self.audioPlayer = base.audioPlayer # @UndefinedVariable pydev在傲娇而已不用管 self.menu = StoryMenuBar() self.gameTextBox = GameTextBox() self.textHistory = TextHistory() self.button_auto = self.menu.addButton(text = 'Auto',state = DGG.NORMAL,command = self.autoPlayButton) self.button_history = self.menu.addButton(text = 'History',state = DGG.NORMAL,command = self.showTextHistoryButton) self.button_skip = self.menu.addButton(text = 'Skip',state = DGG.DISABLED,command = self.startSkippingButton) self.button_lastchoice = self.menu.addButton(text = 'Last Choice',state = DGG.DISABLED,command = self.lastChoice) self.button_save = self.menu.addButton(text = 'Save',state = DGG.DISABLED, command = self.saveButton) self.button_load = self.menu.addButton(text = 'Load',state = DGG.NORMAL,command = self.loadButton) self.button_quicksave = self.menu.addButton(text = 'Quick Save',state = DGG.DISABLED,command = self.quickSaveButton) self.button_quickload = self.menu.addButton(text = 'Quick Load',state = DGG.DISABLED,command = self.quickLoadButton) self.button_config = self.menu.addButton(text = 'Options', state = DGG.NORMAL, command = self._configButton) self.button_title = self.menu.addButton(text = 'Title',state = DGG.NORMAL,command = self.returnToTitle) self._inputReady = True self.__arrow_shown = False self._choiceReady = True self._currentMessage = '' self.__currentSelection = None self.__finishing = False self.__lock = Lock() self.forcejump = False self.__autoInput = False self.__focused = False self.intervals = [] self.__skipping = False self.__autoplaying = False self.__autoInterval = None self.__autoplaystep = None self.mapScriptSpace() SogalForm.__init__(self) self.show() taskMgr.add(self.loopTask,'story_manager_loop',sort = 2,priority = 1) # @UndefinedVariable 傲娇的pydev……因为panda3D的"黑魔法"…… taskMgr.doMethodLater(runtime_data.game_settings['jump_span'],self.__jumpCheck,'story_jump_check', sort = 5, priority = 1) # @UndefinedVariable def focused(self): if not self.__focused: self.accept('mouse1', self.input, [1]) self.accept('enter', self.input, [1]) self.accept('mouse3', self.input, [3]) self.accept('wheel_up', self.showTextHistory) self.accept('escape', self.showMenu) self.accept('control',self.setForceJump, [True]) self.accept('control-up',self.setForceJump, [False]) SogalForm.focused(self) self.__focused = True def defocused(self): if self.__focused: self.ignore('mouse1') self.ignore('enter') self.ignore('mouse3') self.ignore('wheel_up') self.ignore('escape') self.ignore('control') self.ignore('control-up') self.setForceJump(False) SogalForm.defocused(self) self.__arrow_shown = False self.gameTextBox.hideArrow() self.__focused = False def destroy(self): self.__destroyed = True taskMgr.remove('story_manager_loop') # @UndefinedVariable taskMgr.remove('story_jump_check') # @UndefinedVariable if self._frame: self._frame.destroy() self._frame = None if self.__currentSelection: self.__currentSelection.destroy() self.gameTextBox.destroy() self.storyView.destroy() self.menu.destroy() self.textHistory.destroy() SogalForm.destroy(self) def loopTask(self,task): ''' The task loop of StoryManager, trying to advance every task frame ''' if not self.__destroyed: if self.hasFocus(): self.forward(False) return task.cont else: return task.done def _enableSavingButton(self): self.button_save['state'] = DGG.NORMAL self.button_quicksave['state'] = DGG.NORMAL def _disableSavingButton(self): self.button_save['state'] = DGG.DISABLED self.button_quicksave['state'] = DGG.DISABLED def presave(self): if self.nextPtr is not None: runtime_data.RuntimeData.command_ptr = self.nextPtr self.gameTextBox.presave() self.storyView.presave() self.audioPlayer.presave() def reload(self): taskMgr.remove('storyManagerLoop') # @UndefinedVariable self.nextPtr = runtime_data.RuntimeData.command_ptr self.mapScriptSpace() self.gameTextBox.reload() self.storyView.reload() self.audioPlayer.reload() taskMgr.add(self.loopTask,'storyManagerLoop',sort = 2,priority = 1) # @UndefinedVariable 傲娇的pydev……因为panda3D的"黑魔法"…… def mapScriptSpace(self): if runtime_data.RuntimeData.script_space: #map script space self.script_space = runtime_data.RuntimeData.script_space else: runtime_data.RuntimeData.script_space = self.script_space script_global['goto'] = self.goto script_global['story_manager'] = self script_global['game_text_box'] = self.gameTextBox script_global['story_view'] = self.storyView script_global['audio_player'] = self.audioPlayer def quickfinish(self): self.__lock.acquire() if not self.__finishing: self.__finishing = True self.storyView.quickfinish() self.gameTextBox.quickFinish() for itv in self.intervals: itv.finish() self.__lock.release() def input(self,type = 1): self.stopSkipping() self.stopAutoPlaying() if not self.hasFocus(): return #left mouse button or enter key if type == 1 : if not self.getSceneReady(): self.quickfinish() else: self.setTextInputReady(True) #right mouse button elif type == 3: self.quickfinish() if self.getSceneReady(): self.menu.show() def showMenu(self): self.stopSkipping() self.stopAutoPlaying() self.quickfinish() if self.getSceneReady() and not self.forcejump: self.menu.show() def showTextHistory(self): if self.getSceneReady() and not self.forcejump: self.textHistory.show() def saveButton(self): self.menu.hide() base.saveForm.setData(self._currentDump, self._currentMessage) base.saveForm.show() def loadButton(self): self.menu.hide() base.loadForm.show() def quickSaveButton(self): '''quicksave the data''' self.menu.hide() self.button_quicksave['state'] = DGG.DISABLED self.button_quickload['state'] = DGG.DISABLED if self._currentDump: messenger.send('quick_save', [self._currentDump,self._currentMessage]) def quickLoadButton(self): ConfirmDialog(text= '要读取吗?',command= self.__confirmedQuickLoad) def _configButton(self): messenger.send('config_form') def returnToTitle(self): ConfirmDialog(text= '回到标题界面?',command= self.__confirmedReturnToTitle) def __confirmedReturnToTitle(self): messenger.send('return_to_title') def showTextHistoryButton(self): self.menu.hide() self.showTextHistory() def startSkippingButton(self): self.menu.hide() self.startSkipping() def autoPlayButton(self): self.menu.hide() if self.__autoplaying: self.stopAutoPlaying() else: self.startAutoPlaying() def lastChoice(self): ConfirmDialog(text= '要回到上一个选择枝吗?',command= self.__confirmedLastChoice) def __confirmedQuickLoad(self): messenger.send('quick_load') # @UndefinedVariable def __confirmedLastChoice(self): if runtime_data.RuntimeData.last_choice: messenger.send('load_memory',[runtime_data.RuntimeData.last_choice]) # @UndefinedVariable def autoSave(self,info = ''): if not info: info = self._currentMessage messenger.send('auto_save',[self._currentDump,info]) def getSceneReady(self): '''Get if the scene is ready''' textbox_ready = False view_ready = False intervals_ready = True if not self.gameTextBox.getIsWaiting(): textbox_ready = True if not self.storyView.getIsWaiting(): view_ready = True for itv in self.intervals: if itv.isPlaying(): intervals_ready = False break scene_ready = textbox_ready and view_ready and intervals_ready if not scene_ready: return False #auto play span if scene_ready and self.__autoplaying: if self.__autoplaystep != self.step: self.__autoplaystep = self.step self.__autoInterval = Wait(runtime_data.game_settings['auto_span']) self.__autoInterval.start() scene_ready = False else: if self.__autoInterval.isPlaying(): scene_ready = False if self.audioPlayer.isVoicePlaying(): scene_ready = False return scene_ready def getInputReady(self): '''define is user's 'next' command given''' textinput_ready = self._inputReady or self.__autoInput choice_ready = self.getChoiceReady() if self.__autoInput: self.__autoInput = False if textinput_ready and choice_ready: return True return False def setTextInputReady(self, value): self._inputReady = value def getChoiceReady(self): return self._choiceReady def forward(self,is_user = False): '''run nextCommand() or finish current operations quickly @param is_user: define if this operation is started by the player ''' scene_ready = self.getSceneReady() if scene_ready and not self.__arrow_shown: self.gameTextBox.showArrow() self.__arrow_shown = False if scene_ready and self.getInputReady(): self.nextCommand() if self.forcejump or self.__skipping: self.quickfinish() def nextCommand(self): '''Process the next command in the non-processed queue ''' #TODO: 还要添加循环的支持,用到runtime_data.command_stack来暂存需要回跳的命令组和回跳节点 #TODO:添加对条件和选择的支持 self.__finishing = False self.__arrow_shown = False self.gameTextBox.hideArrow() #Dumps story data for saving or further use if self.__destroyed: return self.presave() self._currentDump = copy.deepcopy(runtime_data.RuntimeData) if self.nextPtr < 0: self.nextPtr = 0 self.__currentPtr = self.nextPtr self.nextPtr += 1 if not self.commandList: return if len(self.commandList) > self.__currentPtr: handled = False if self.commandList[self.__currentPtr].command: comline = self.commandList[self.__currentPtr].command.strip() if comline.startswith('mark ')or comline.startswith('mark:'): handled = True # 条件判断处理 If condition elif comline.startswith('if '): splited = space_cutter.split(comline, 1) if len(splited)<2: raise Exception('没条件玩毛线') if self.scriptEval(splited[1]): handled = True else: relative_depth = 0 #if not match the condition, try to jump to elif or else for i in range(self.__currentPtr+1,len(self.commandList)): cli = self.commandList[i] if cli.command: cl = cli.command.strip() else: continue #一个嵌套循环的情况! A inner if if cl.startswith('if '): relative_depth += 1 continue elif relative_depth == 0 and cl.startswith('elif '): splited = space_cutter.split(cl, 1) if len(splited)<2: raise Exception('没条件玩毛线') if self.scriptEval(splited[1]): self.nextPtr = i + 1 handled = True break else: continue elif relative_depth == 0 and cl == 'else': self.nextPtr = i + 1 handled = True break elif cl == 'end' or cl.startswith('end '): if relative_depth == 0: self.nextPtr = i + 1 handled = True break else: relative_depth -= 1 continue #if we meet else or elif then jump to end elif comline.startswith('elif ') or comline == 'else': relative_depth = 0 for i in range(self.__currentPtr+1,len(self.commandList)): cli = self.commandList[i] if cli.command: cl = cli.command.strip() else: continue if cl.startswith('if '): relative_depth += 1 continue elif cl == 'end' or cl.startswith('end '): if relative_depth == 0: self.nextPtr = i + 1 handled = True break else: relative_depth -= 1 continue #ignore end elif comline == 'end' or comline.startswith('end '): handled = True if not handled: self.processCommand(self.commandList[self.__currentPtr]) #self.scrPtr = self.scrPtr + 1 #runtime_data.RuntimeData.command_ptr = self.scrPtr if base.hasQuickData(): self.button_quickload['state'] = DGG.NORMAL if runtime_data.RuntimeData.last_choice: self.button_lastchoice['state'] = DGG.NORMAL if self._currentDump: self._enableSavingButton() self.step += 1 #mark step def goto(self, target): '''Jump to a mark''' for i in range(0, len(self.commandList)): if self.commandList[i].command: mark = mark_cutter.split(self.commandList[i].command , 1) if len(mark) > 1: markText = mark[1].strip() if markText == target: self.nextPtr = i #Solved: #this is not a good solution but this method runs at 'nextCommand', and ths scrPtr would plus 1 afterwards return safeprint('unable to find mark') def processCommand(self,command): '''Process a StoryCommand @param command: The StoryCommand to deal with ''' def seval(strs): return self.scriptEval(strs) #Mark read if not runtime_data.read_text.has_key(command.fileLoc): runtime_data.read_text[command.fileLoc] = {} if not runtime_data.read_text[command.fileLoc].has_key(command.index): already_read = False self.stopSkipping() else: already_read = True runtime_data.read_text[command.fileLoc][command.index] = True if already_read: self.button_skip['state'] = DGG.NORMAL else: self.button_skip['state'] = DGG.DISABLED self.storyView.clearQuickItems() #clear out quick items name = '' continuous = False is_script = False is_selection = False spaceCutter = space_cutter hidingtext = False voiceFlag = False #it will be True if voice is stopped in this line of command #used for disable cross voice of different command lines #but enable one command line with multiple voices autoSaving = False #Mark if autosaving is needed at the end of this step autoSavingInfo = '' #read command line if command.command: commands = command.command.split(',') comm = '' for item in commands: comm = item.strip() if comm: messenger.send('sogalcommand',[comm]) #allow other tools to deal with it @UndefinedVariable #名字设置命令 if comm.startswith('name ') or comm.startswith('name='): nameCutter = re.compile(ur'name *=?',re.UNICODE) name = nameCutter.split(comm,1)[1].strip() #改变文本框格式命令 elif comm.startswith('textboxstyle '): if self.gameTextBox: self.gameTextBox.setTextBoxStyle(spaceCutter.split(comm, 1)[1]) self.gameTextBox.applyStyle() #文本框分段命令 elif comm == 'p': if self.gameTextBox: self.gameTextBox.paragraphSparator() elif comm == 'c': continuous = True elif comm.startswith('wait '): temp = spaceCutter.split(comm,1) if len(temp) > 1: self.sceneWait(seval(temp[1])) #文本框属性设置命令 elif comm.startswith('textbox '): temp = spaceCutter.split(comm,2) if temp[1] == 'apply': self.gameTextBox.applyTextBoxProperties() elif len(temp)>=3: self.gameTextBox.setTextBoxProperty(temp[1],seval(temp[2])) else: safeprint('Not enough: ' + comm) #背景设置命令 elif comm.startswith('bg '): temp = spaceCutter.split(comm,2) if len(temp) >= 3: fadein = seval(temp[2]) else: fadein = 0 self.storyView.changeBackground(temp[1],fadein) #图片显示命令 elif comm.startswith('p '): temp = spaceCutter.split(comm,6) if len(temp) >= 7: fadein = seval(temp[6]) else: fadein = 0 if len(temp) >= 6: scale = seval(temp[5]) else: scale = 1 if len(temp) >= 5: location = (seval(temp[3]),0,seval(temp[4])) else: if self.storyView.itemEntries.has_key(temp[1]): location = self.storyView.itemEntries[temp[1]].pos else: location = (0,0,0) svie = StoryViewItemEntry(temp[1],temp[2],SVIC.FG,pos = location,scale = (scale,scale,scale),color = (1,1,1,1),fadein = fadein) self.storyView.newItem(svie) elif comm.startswith('del '): temp = spaceCutter.split(comm,2) if len(temp)>=3: self.storyView.deleteItem(temp[1], seval(temp[2])) else: self.storyView.deleteItem(temp[1]) elif comm.startswith('ploc '): temp = spaceCutter.split(comm,5) if len(temp) >= 5: location = (seval(temp[2]),seval(temp[3]),seval(temp[4])) else: location = (seval(temp[2]),0,seval(temp[3])) if len(temp) >= 6: fadein = seval(temp[5]) else: fadein = 0 self.storyView.changePosColorScale(temp[1], pos = location,time = fadein) elif comm.startswith('pcolor '): temp = spaceCutter.split(comm,6) color = (seval(temp[2]),seval(temp[3]),seval(temp[4]),seval(temp[5])) if len(temp) >= 7: fadein = seval(temp[6]) else: fadein = 0 self.storyView.changePosColorScale(temp[1], color = color, time = fadein) elif comm.startswith('pscale '): temp = spaceCutter.split(comm,5) if len(temp) >= 5: scale = (seval(temp[2]),seval(temp[3]),seval(temp[4])) else: scale = (seval(temp[2]),seval(temp[2]),seval(temp[2])) if len(temp) == 6: fadein = seval(temp[5]) elif len(temp) == 4: fadein = seval(temp[3]) else: fadein = 0 self.storyView.changePosColorScale(temp[1], scale = scale, time = fadein) elif comm.startswith('o3d '): temp = spaceCutter.split(comm) svie = StoryViewItemEntry(temp[1],temp[2],SVIC.O3D,pos = (seval(temp[3]),seval(temp[4]),seval(temp[5])) ,scale = (seval(temp[10]),seval(temp[11]),seval(temp[12])),color = (seval(temp[6]),seval(temp[7]),seval(temp[8]),seval(temp[9]))) self.storyView.newItem(svie) elif comm.startswith('o2d '): temp = spaceCutter.split(comm) svie = StoryViewItemEntry(temp[1],temp[2],SVIC.O2D,pos = (seval(temp[3]),seval(temp[4]),seval(temp[5])) ,scale = (seval(temp[10]),seval(temp[11]),seval(temp[12])),color = (seval(temp[6]),seval(temp[7]),seval(temp[8]),seval(temp[9]))) self.storyView.newItem(svie) elif comm.startswith('pa '): temp = spaceCutter.split(comm) if len(temp) >= 8: fadein = seval(temp[7]) else: fadein = 0 svie = StoryViewItemEntry(temp[1],temp[2],SVIC.AFG,pos = (seval(temp[3]),0,seval(temp[4])) ,scale = (seval(temp[5]),1,seval(temp[6])),fadein = fadein) self.storyView.newItem(svie) elif comm == 'clear': hidingtext = True self.storyView.clear() elif comm.startswith('clear '): hidingtext = True temp = spaceCutter.split(comm,2) if len(temp)>=3: self.storyView.clear(seval(temp[1]),temp[2]) elif len(temp)==2: self.storyView.clear(seval(temp[1])) else: self.storyView.clear() elif comm.startswith('delbg '): temp = spaceCutter.split(comm,1) if len('temp')>=2: self.storyView.deleteItem('__bg__', seval(temp[1])) else: self.storyView.deleteItem('__bg__') elif comm.startswith('qp '): temp = spaceCutter.split(comm,3) svie = StoryViewItemEntry('quickitem',temp[1],SVIC.FG, pos = (seval(temp[2]),0,seval(temp[3])), quickitem = True ) self.storyView.newItem(svie) elif comm.startswith('v '): if not voiceFlag: self.audioPlayer.stopVoice() voiceFlag = True temp = spaceCutter.split(comm , 2) if len(temp)>=3: volume = seval(temp[2]) else: volume = 1 self.audioPlayer.playVoice(temp[1],volume) elif comm.startswith('se '): temp = spaceCutter.split(comm , 2) if len(temp)>=3: volume = seval(temp[2]) else: volume = 1 self.audioPlayer.playSound(temp[1],volume) elif comm == 'vstop': self.audioPlayer.stopVoice() voiceFlag = True elif comm == 'sestop': self.audioPlayer.stopSound() elif comm.startswith('bgm '): temp = spaceCutter.split(comm , 4) if len(temp)>=3: fadein = seval(temp[2]) else: fadein = 0 if len(temp)>=4: volume = seval(temp[3]) else: volume = 1 if len(temp)>=5: loop = bool(seval(temp[4])) else: loop = True self.audioPlayer.playBGM(temp[1], fadein=fadein, volume=volume, loop=loop) elif comm.startswith('env '): temp = spaceCutter.split(comm , 4) if len(temp)>=3: fadein = seval(temp[2]) else: fadein = 0 if len(temp)>=4: volume = seval(temp[3]) else: volume = 1 if len(temp)>=5: loop = bool(seval(temp[4])) else: loop = True self.audioPlayer.playENV(temp[1], fadein=fadein, volume=volume, loop=loop) elif comm.startswith('bgmstop ') or comm == 'bgmstop': temp = spaceCutter.split(comm , 1) if len(temp)>=2: fadeout = seval(temp[1]) else: fadeout = 0 self.audioPlayer.stopBGM(fadeout) elif comm.startswith('envstop ') or comm == 'envstop': temp = spaceCutter.split(comm , 1) if len(temp)>=2: fadeout = seval(temp[1]) else: fadeout = 0 self.audioPlayer.stopENV(fadeout) elif comm.startswith('audiostop ') or comm == 'audiostop': temp = spaceCutter.split(comm , 1) if len(temp)>=2: fadeout = seval(temp[1]) else: fadeout = 0 self.audioPlayer.stopAll(fadeout) elif comm == 'script': is_script = True elif comm.startswith('script '): temp = spaceCutter.split(comm , 1) self.runScriptFile(temp[1]) elif comm == 'choice' or comm.startswith('choice '): ''' Selection ''' is_selection = True temp = spaceCutter.split(comm, 1) if len(temp) > 1: striped = temp[1].strip() if striped: self.pushText(text = striped, speaker = None, needInput = False, read = already_read) elif comm.startswith('jump '): temp = spaceCutter.split(comm , 1) self.beginScene(temp[1].strip()) elif comm.startswith('expand '): temp = spaceCutter.split(comm , 1) self.expandScene(temp[1].strip()) elif comm.startswith('goto '): temp = spaceCutter.split(comm , 1) self.goto(temp[1].strip()) elif comm.startswith('theme '): temp = spaceCutter.split(comm , 1) self.reloadTheme(temp[1].strip()) elif comm == 'autosave' or comm.startswith('autosave '): if self.step > 0: autoSaving = True temp = spaceCutter.split(comm , 1) if len(temp) > 1: autoSavingInfo = temp[1] else: if comm: safeprint('extra command: ' + comm) if command.text: if is_script: self.runScript(command.text) elif is_selection: ''' If encountered a selection ''' choiceList = [] enablesList = [] textlines = command.text.splitlines() for tl in textlines: if tl.startswith('--'): #--means disabled text = tl[2:] enablesList.append(False) else: text = tl enablesList.append(True) choiceList.append(text) self.showSelection(choiceList = choiceList, enablesList = enablesList) else: self.pushText(text = command.text, speaker = name, continuous = continuous, read = already_read) else: if hidingtext: self.gameTextBox.hide() #better to hide the textbox when 'vclear' if self.gameTextBox.newText: runtime_data.RuntimeData.latest_text = self.gameTextBox.newText if runtime_data.RuntimeData.latest_text: self._currentMessage = runtime_data.RuntimeData.latest_text #Autosave if autoSaving: if autoSavingInfo: self.autoSave(autoSavingInfo) else: self.autoSave() def pushText(self, text, speaker = None, continuous = False, needInput = True, read = False): def translate(t): ''' ,实现通配,__代替空行已经在一开始实现 ''' return t.replace(ur'\:', ur':').replace(ur'\:',ur':').replace(ur'\#',ur'#') #检查有无在文本中的name #name: formation checking textlines = text.splitlines() first_line = unicode(textlines[0]) #匹配第一行中是否有表示name的冒号,正则表达式表示前面不是\的冒号(@name 命令行的简写形式判断) pattern = re.compile(ur'(?<!\\)[:(:)]',re.UNICODE) splited = pattern.split(first_line,maxsplit = 1) #print(splited) #测试用,废弃 #如果存在name即分割成功 if len(splited)>1: speaker = translate(splited[0]).strip() if splited[1].strip(): textlines[0] = splited[1] else: textlines[0] = None final_text = '' #生成文本并解决转义符 #Generate the final text for item in textlines: if item: final_text += translate(item) + '\n' if final_text: self.textHistory.append(final_text, speaker, None) self.gameTextBox.pushText(text = final_text, speaker = speaker, continuous = continuous,read= read) if needInput: self._inputReady = False self.gameTextBox.show() def runScript(self,pscriptText): exec(pscriptText,script_global,self.script_space) def runScriptFile(self,fileName): #'''note that would ignore panda virtual pathes''' pathes = runtime_data.game_settings['pscriptpathes'] types = runtime_data.game_settings['pscripttypes'] for ft in ((folder,type) for folder in pathes for type in types): if exists(ft[0] + fileName + ft[1]): handle = open(ft[0] + fileName + ft[1]) script = handle.read() handle.close() break if script: self.runScript(script) else: safeprint("file not find: "+ fileName) def beginScene(self,fileName): '''Load target .sogal script file and go to that file. ''' self.nextPtr = 0 self.scrStack = [] #used for stack controller pointers self.commandList = loadScriptData(fileName) runtime_data.RuntimeData.command_stack = self.scrStack runtime_data.RuntimeData.command_list = self.commandList def expandScene(self,fileName): '''expand a scene, inserting another sogal file in to current point''' expanding = loadScriptData(fileName) if len(self.commandList)> self.__currentPtr+1: self.commandList = self.commandList[:self.__currentPtr] + expanding + self.commandList[self.__currentPtr+1:] else: self.commandList = self.commandList[:self.__currentPtr] + expanding runtime_data.RuntimeData.command_stack = self.scrStack runtime_data.RuntimeData.command_list = self.commandList self.nextPtr = self.__currentPtr #Solved: # this is not a good solution but this method runs at 'nextCommand', and ths scrPtr would plus 1 afterwards def showSelection(self,choiceList = ['A','B'],enablesList = None): '''This method shows a selection, which sets 'last_choice' in script space to player's choice. (0 is the first, 1 is the second etc.) you can disable some of the selections with enablesList for example for choiceList ['A','B','C'] and enablesList ''' #Store the last selection rdc = copy.deepcopy(self._currentDump) rdc.last_choice = None self.__tempDumpedLastChoice = pickle.dumps(rdc, 2) self._choiceReady = False startPos = (0,0,0.1 * len(choiceList)) frameSize = (-0.6,0.6,-0.05 - 0.1*len(choiceList), 0.1 + 0.1*len(choiceList)) buttonSize = (-0.5,0.5,-0.050,0.10) margin = 0.05 self.__currentSelection = SogalDialog(enableMask = False, fadeScreen= None, command = self.__selected, textList= choiceList, enablesList= enablesList, sortType= 1,noFocus = True, startPos = startPos,frameSize = frameSize,margin = margin, buttonSize = buttonSize) def __selected(self,choice): #Store the last selection if self.__tempDumpedLastChoice: runtime_data.RuntimeData.last_choice = self.__tempDumpedLastChoice self.script_space['last_choice'] = choice self._choiceReady = True def scriptEval(self,str): return eval(str,script_global,runtime_data.RuntimeData.script_space) def setForceJump(self,forcejump): if forcejump: if not self.forcejump: self.forcejump = True self.setTextInputReady(True) self.__skipping = False self.stopAutoPlaying() else: self.forcejump = False def __jumpCheck(self,task): if self.hasFocus(): if self.forcejump or self.__skipping or self.__autoplaying: self.__autoInput = True return task.again def sceneWait(self,time,hidetextbox = True): waitinterval = Wait(time) self.intervals.append(waitinterval) waitinterval.start() if hidetextbox: self.gameTextBox.hide() def reloadTheme(self,theme): base.setStyle(theme) self.menu.reloadTheme() self.textHistory.reloadTheme() self.gameTextBox.reloadTheme() def stopSkipping(self): self.__skipping = False if not self.forcejump: self.__autoInput = False def startSkipping(self): self.stopAutoPlaying() self.__skipping = True def startAutoPlaying(self): self.__skipping = False self.__autoplaying = True self.button_auto['text'] = 'Stop Auto' def stopAutoPlaying(self): self.__autoplaying = False if self.__autoInterval: self.__autoInterval.pause() self.button_auto['text'] = 'Auto'
def sceneWait(self,time,hidetextbox = True): waitinterval = Wait(time) self.intervals.append(waitinterval) waitinterval.start() if hidetextbox: self.gameTextBox.hide()