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 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 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 loadScriptData(fileName): '''Load the sogal script file (.sogal) returns a list of StoryCommands indicating different commands divided by empty lines and continuous rows of @ symbol 读取sogal脚本,将不同的命令区分成很多StoryCommand但是不做解析,仅仅是简单地区分开命令行和文本行 参见 game_entities.StoryCommand ''' _lsdLock.acquire() fileloc = None for pt in ((path,type) for path in runtime_data.game_settings['sogalscrpathes'] for type in runtime_data.game_settings['sogalscrtypes']): if exists(pt[0]+fileName+pt[1]): fileloc = pt[0]+fileName+pt[1] break if not fileloc: safeprint('file not found: ' + fileName) _lsdLock.release() return fileHandle = open(fileloc) #for 'from direct.stdpy.file import open', this 'open' is panda3d opereation and not the standard python operation global _current_index #I hate python below 3 _current_index = 0 #current index of the command io_reader = StringIO(fileHandle.read()) fileHandle.close() io_reader.seek(0) loaded_list = [] global _current_command #虽然global很讨厌…… _current_command = None #当前的命令文字 global _current_text _current_text = None #当前的文本 controlAttribs_startswith = ['if ','while ','elif ','end ','mark ','mark:'] controlAttribs_equal = ['else','end'] def push_current(): global _current_command #如果是python3.0以上在这里用nonlocal就好了…… global _current_text global _current_index '''将当前命令文本加入到loaded_list末尾''' if not _current_command and not _current_text: _current_command = None _current_text = None return else: loaded_list.append(StoryCommand(command = _current_command, text = _current_text,index= _current_index, fileLoc= fileloc)) _current_index += 1 _current_command = None _current_text = None while True: temp_original = unicode(io_reader.readline().decode('utf-8')) if not temp_original: #文件末 push_current() break; else: #textTemp = temp_original.strip('\n') notesplit = re.compile(ur'(?<!\\)#|^#',re.UNICODE) #Convert the line to utf-8 and remove the note afterwards line_raw = notesplit.split(temp_original,1)[0] line = line_raw.strip() if not line: #若是空行,则进行push操作 push_current() elif line.startswith('@'): if _current_command or _current_text: #如果在一个命令列前面已经有了内容,则前面已经是完整的一段,所以推入列表 push_current() _current_command = line.lstrip('@') _stripedcc = _current_command.strip() #There should be no text in control parts so it it is an control part then push for attr in controlAttribs_startswith: if _stripedcc.startswith(attr): push_current() for attr in controlAttribs_equal: if _stripedcc == attr: push_current() else: #于是就剩下是文本的情况 if _current_text: _current_text += '\n' else: _current_text = '' adding = line_raw.rstrip() if adding.startswith('__'): _current_text += ' ' #用一个空格代替空行嗯 else: _current_text += adding _lsdLock.release() return loaded_list