def new_project(self, settings_path, values): """Create a mew project and load it Args: settings_path: The path to the new settings file values: The starting values of the project. """ import tkinter.messagebox settings_file = open(settings_path, "w") settings_file.write(BASIC_SETTINGS) settings_file.close() project = SimpleXMLSerializer(settings_path) project.load() update_settings(project, values) project.save() comp_file = project.get("fife-rpg", "ComponentsFile") act_file = comp_file or project.get("fife-rpg", "ActionsFile") syst_file = act_file or project.get("fife-rpg", "SystemsFile") beh_file = syst_file or project.get("fife-rpg", "BehavioursFile") comb_file = beh_file or project.get("fife-rpg", "CombinedFile") if not comb_file: dest = os.path.join(os.path.dirname(settings_path), "combined.yaml") shutil.copy("combined.yaml.template", dest) self.try_load_project(settings_path) tkinter.messagebox.showinfo(_("Project created"), _("Project successfully created")) self.editor_gui.enable_menus() self.project_changed = False self.entity_changed = False
def createPlayerObject(self): """ @todo: once we have all art assets this should be able to load one of 3 player models """ modeldict = self._modelsettings.get("models", "Player", {}) print('loading: %s' % modeldict["file"]) self._loader.loadImportFile(modeldict["file"]) self._player = Player(self._gamecontroller, self.actorlayer, "warrior") playerfilename = os.path.join("saves", "player_save.xml") if os.path.isfile(playerfilename): player_settings = SimpleXMLSerializer(playerfilename) pvals = player_settings.get("player", "player", {}) self._player.deserialize(pvals)
def convert_fife_project(self, project_filepath): """Converts a fife settings file to a fife-rpg project Args: Project_filepath: Path to the fife settings file """ project = SimpleXMLSerializer(project_filepath) bak_file = "%s.bak" % project_filepath project.save(bak_file) settings = {} settings["ProjectName"] = project.get("FIFE", "WindowTitle", "") update_settings(project, settings) if not self.edit_project_settings(project_filepath, project): return None project.save() return bak_file
class Setting(object): """ This class manages loading and saving of game settings. Usage:: from fife.extensions.fife_settings import Setting settings = Setting(app_name="myapp") screen_width = settings.get("FIFE", "ScreenWidth", 1024) screen_height = settings.get("FIFE", "ScreenHeight", 768) """ def __init__(self, app_name="", settings_file="", default_settings_file= "settings-dist.xml", copy_dist=True, serializer=None): r""" Initializes the Setting object. @param app_name: The applications name. If this parameter is provided alone it will try to read the settings file from the users home directory. In windows this will be something like: C:\Documents and Settings\user\Application Data\fife @type app_name: C{string} @param settings_file: The name of the settings file. If this parameter is provided it will look for the setting file as you specify it, first looking in the working directory. It will NOT look in the users home directory. @type settings_file: C{string} @param default_settings_file: The name of the default settings file. If the settings_file does not exist this file will be copied into the place of the settings_file. This file must exist in the root directory of your project! @type default_settings_file: C{string} @param copy_dist: Copies the default settings file to the settings_file location. If this is False it will create a new empty setting file. @param serializer: Overrides the default XML serializer @type serializer: C{SimpleSerializer} """ self._app_name = app_name self._settings_file = settings_file self._default_settings_file = default_settings_file # Holds SettingEntries self._entries = {} if self._settings_file == "": self._settings_file = "settings.xml" self._appdata = getUserDataDirectory("fife", self._app_name) else: self._appdata = os.path.dirname(self._settings_file) self._settings_file = os.path.basename(self._settings_file) if not os.path.exists(os.path.join(self._appdata, self._settings_file)): if os.path.exists(self._default_settings_file) and copy_dist: shutil.copyfile(self._default_settings_file, os.path.join(self._appdata, self._settings_file)) # valid values possible for the engineSettings self._validSetting = {} self._validSetting['FIFE'] = { 'FullScreen':[True,False], 'RefreshRate':[0,200], 'Display':[0,9], 'VSync':[True,False], 'PychanDebug':[True,False] , 'ProfilingOn':[True,False], 'SDLRemoveFakeAlpha':[True,False], 'GLCompressImages':[False,True], 'GLUseFramebuffer':[False,True], 'GLUseNPOT':[False,True], 'GLUseMipmapping':[False,True], 'GLTextureFiltering':['None', 'Bilinear', 'Trilinear', 'Anisotropic'], 'GLUseMonochrome':[False,True], 'GLUseDepthBuffer':[False,True], 'GLAlphaTestValue':[0.0,1.0], 'RenderBackend':['OpenGL', 'SDL'], 'ScreenResolution':['640x480', '800x600', '1024x600', '1024x768', '1280x768', '1280x800', '1280x960', '1280x1024', '1366x768', '1440x900', '1600x900', '1600x1200', '1680x1050', '1920x1080', '1920x1200'], 'BitsPerPixel':[0,16,24,32], 'InitialVolume':[0.0,10.0], 'WindowTitle':"", 'WindowIcon':"", 'Font':"", 'FontGlyphs':"", 'DefaultFontSize':"", 'Lighting':[0,1], 'ColorKeyEnabled':[True,False], 'ColorKey':['a','b','c'], 'VideoDriver':"", 'RenderDriver':"", 'PlaySounds':[True,False], 'LogToFile':[True,False], 'LogToPrompt':[True,False], 'LogLevelFilter':[0,1,2,3], 'LogModules':['all', 'controller','script','video','audio','loaders','vfs','pool','view','model','metamodel','event_channel','xml'], 'FrameLimitEnabled':[True,False], 'FrameLimit':[0], 'MouseSensitivity':[0.0], 'MouseAcceleration':[True,False], 'NativeImageCursor':[True,False], 'JoystickSupport':[True, False] } glyphDft = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/():;%&`'*#=[]\\\"" # we at this point assume default values are final values for engineSettings self._defaultSetting = {} self._defaultSetting['FIFE'] = { 'FullScreen':False, 'RefreshRate':60, 'Display':0, 'VSync':False, 'PychanDebug':False, 'ProfilingOn':False, 'SDLRemoveFakeAlpha':False, 'GLCompressImages':False, 'GLUseFramebuffer':True, 'GLUseNPOT':True, 'GLUseMipmapping':False, 'GLTextureFiltering':'None', 'GLUseMonochrome':False, 'GLUseDepthBuffer':False, 'GLAlphaTestValue':0.3, 'RenderBackend':'OpenGL', 'ScreenResolution':"1024x768", 'BitsPerPixel':0, 'InitialVolume':5.0, 'WindowTitle':"", 'WindowIcon':"", 'Font':"", 'FontGlyphs':glyphDft, 'DefaultFontSize':12, 'Lighting':0, 'ColorKeyEnabled':False, 'ColorKey':[255,0,255], 'VideoDriver':"", 'RenderDriver':"", 'PlaySounds':True, 'LogToFile':False, 'LogToPrompt':False,'LogLevelFilter':0, 'LogModules':['controller','script'], 'FrameLimitEnabled':False, 'FrameLimit':60, 'MouseSensitivity':0.0, 'MouseAcceleration':False, 'NativeImageCursor':False, 'JoystickSupport':False } # has the settings file been read self._readSettingsCompleted = {} # the global dictionary from which we will read after self._readSettingsCompleted is True self._settingsFromFile = {} # the logger needed to write in log file. It will be initialized in this file when self.getSettings() # method is called by logger self._logger = None #default settings self._resolutions = self._validSetting['FIFE']['ScreenResolution'] self._renderbackends = self._validSetting['FIFE']['RenderBackend'] self._lightingmodels = self._validSetting['FIFE']['Lighting'] #Used to stylize the options gui self._gui_style = "default" #Initialize the serializer if serializer: self._serializer = serializer else: self._serializer = SimpleXMLSerializer() self.initSerializer() # if there's no FIFE module assume the settings file is broken # and replace with default settings file if "FIFE" not in self._serializer.getModuleNameList(): self.setDefaults() # Get all modules and initialize reading of them from xml file as false self._allModules = self._serializer.getModuleNameList() # print("All Module Names:",self._allModules) for module in self._allModules: self._readSettingsCompleted[module] = False self._initDefaultSettingEntries() #self.setOneSetting('FIFE','Font','fonts/FreeSans.ttf',False) #print self.getSettingsFromFile('unknownhorizons') # set all Settings in either validSetting or defaultSetting def setAllSettings(self,module,settings,validSetting = True): if validSetting: self._validSetting[module] = settings else: self._defaultSetting[module] = settings # set an entry in the validSetting or defaultSetting dictionary def setOneSetting(self,module,name,value,validSetting = True): if validSetting: self._validSetting[module][name] = value else: self._defaultSetting[module][name] = value # get all the Settings(either validSetting or defaultSetting) def getAllSettings(self,module,validSetting = True): if validSetting: return self._validSetting[module] else: return self._defaultSetting[module] # get an entry from either validSetting or defaultSetting def getOneSetting(self,module,name,validSetting = True): if validSetting: return self._validSetting[module][name] else: return self._defaultSetting[module][name] # sets valid resolution options in the settings->Resolution def setValidResolutions(self, options): if options: self._resolutions = options self.createAndAddEntry(FIFE_MODULE, "ScreenResolution", initialdata = self._resolutions, requiresrestart=True) def initSerializer(self): self._serializer.load(os.path.join(self._appdata, self._settings_file)) def _initDefaultSettingEntries(self): """Initializes the default fife setting entries. Not to be called from outside this class.""" self.createAndAddEntry(FIFE_MODULE, "PlaySounds", requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "FullScreen", requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "ScreenResolution", initialdata = self._resolutions, requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "RenderBackend", initialdata = self._renderbackends, requiresrestart=True) def createAndAddEntry(self, module, name, applyfunction=None, initialdata=None, requiresrestart=False): """" @param module: The Setting module this Entry belongs to @type module: C{String} @param name: The Setting's name @type name: C{String} @param applyfunction: function that makes the changes when the Setting is saved @type applyfunction: C{function} @param initialdata: If the widget supports the setInitialData() function this can be used to set the initial data @type initialdata: C{String} or C{Boolean} @param requiresrestart: Whether or not the changing of this setting requires a restart @type requiresrestart: C{Boolean} """ entry = SettingEntry(module, name, applyfunction, initialdata, requiresrestart) self.addEntry(entry) def addEntry(self, entry): """Adds a new C{SettingEntry} to the Settting @param entry: A new SettingEntry that is to be added @type entry: C{SettingEntry} """ if entry.module not in self._entries: self._entries[entry.module] = {} self._entries[entry.module][entry.name] = entry """ # Make sure the new entry is available if self.get(entry.module, entry.name) is None: print "Updating", self._settings_file, "to the default, it is missing the entry:"\ , entry.name ,"for module", entry.module #self.setDefaults() if self.get(entry.module, entry.name) is None: print "WARNING:", entry.module, ":", entry.name, "still not found!" """ def saveSettings(self, filename=""): """ Writes the settings to the settings file @param filename: Specifies the file to save the settings to. If it is not specified the original settings file is used. @type filename: C{string} """ if self._serializer: if filename == "": self._serializer.save(os.path.join(self._appdata, self._settings_file)) else: self._serializer.save(filename) # get all the settings of a module name module def getSettingsFromFile(self, module, logger=None): if self._serializer: self._logger = logger modules = self._serializer.getModuleNameList() self._settingsFromFile[module] = self._serializer.getAllSettings(module) if self._logger: self._logger.log_log("Loading Settings From File ...") if self._settingsFromFile[module] is not None: self._readSettingsCompleted[module] = True # we need validation for the module FIFE only if module is not "FIFE": return self._settingsFromFile[module] """ Now we have all the settings we needed. We have to validate the settings. Applicable for module FIFE only """ for name in self._settingsFromFile[module]: # if the setting name is known, so that it is # both in self._settingsFromFile and validSetting if name in self._validSetting[module]: e_value = self._settingsFromFile[module][name] if name == "InitialVolume": if e_value >= self._validSetting[module][name][0] and e_value <= self._validSetting[module][name][1]: self._settingsFromFile[module][name] = e_value else: if self._logger: self._logger.log_log("InitalVolume must have a value between 0.0 and 10.0") elif name == "GLAlphaTestValue": if e_value >= self._validSetting[module][name][0] and e_value <= self._validSetting[module][name][1]: self._settingsFromFile[module][name] = e_value else: if self._logger: self._logger.log_log("GLAlphaTestValue must have a value between 0.0 and 1.0") elif name == "ColorKey": e_value = e_value.split(',') if int(e_value[0]) in range(0,256) and int(e_value[1]) in range(0,256) and int(e_value[2]) in range(0,256): self._settingsFromFile[name] = [int(e_value[0]),int(e_value[1]),int(e_value[2])]; else: if self._logger: self._logger.log_log("ColorKey values must be within 0 and 255. Setting to Default Value.") elif name == "ScreenResolution": temp = e_value.split('x') if len(temp) == 2: self._settingsFromFile[module][name]=e_value else: if self._logger: self._logger.log_log("Invalid Screen Resolution value. We expect two integer separated by x") elif len(self._validSetting[module][name]) == 0: self._settingsFromFile[module][name] = e_value elif name == "LogModules": for checking_element in e_value: module_valid = False for base_element in self._validSetting[module][name]: # checking_element is valid if checking_element == base_element: module_valid = True already_in = False for element in self._settingsFromFile[module][name]: if element == checking_element: already_in = True if already_in == False: self._settingsFromFile[module][name].append(checking_element) if module_valid == False: if self._logger: self._logger.log_log(checking_element +" is not a valid logModule") elif name == "FrameLimit": if e_value > 0: self._settingsFromFile[module][name] = e_value else: if self._logger: self._logger.log_log(e_value + " is not a valid FrameLimit setting. You must specify a positive integer!") elif name == "MouseSensitivity": self._settingsFromFile[module][name] = e_value elif name == "MouseAcceleration": self._settingsFromFile[module][name] = e_value elif name == "NativeImageCursor": self._settingsFromFile[module][name] = e_value elif name == "JoystickSupport": self._settingsFromFile[module][name] = e_value elif name in ("SDLRemoveFakeAlpha", "LogToPrompt", "LogToFile"): if type(e_value) == int: try: e_value = (False, True)[e_value] except IndexError: self._logger.log_warn("Invalid int-value for %s. Defaulted to False!"%name) e_value = False self._logger.log_warn("Use of type int for %s is deprecated. Use bool instead!"%name) self._settingsFromFile[module][name] = e_value else: if isinstance(self._settingsFromFile[module][name],list) == True or isinstance(self._settingsFromFile[module][name],dict) == True: valid = False for value in self._validSetting[module][name]: if value == e_value: valid = True self._settingsFromFile[module][name] = e_value; if valid == False: if self._logger: self._logger.log_log("Setting " + name + " got invalid value. Setting to Default.") else: self._settingsFromFile[module][name] = e_value # name is unknown else: if self._logger: self._logger.log_log("Setting "+ name + " is unknown") if self._logger: self._logger.log_log("Settings Loaded ...") """ Upto this point we have validated all the settings that are in settings.xml file. But, what if a setting is valid and still it is not present in the settings.xml file. For this, we should give them the default Values that are in defaultSetting. """ for name in self._defaultSetting[module]: if name not in self._settingsFromFile[module]: self._settingsFromFile[module][name] = self._defaultSetting[module][name] return self._settingsFromFile[module] else: return None def get(self, module, name, defaultValue=None): """ Gets the value of a specified setting @param module: Name of the module to get the setting from @param name: Setting name @param defaultValue: Specifies the default value to return if the setting is not found @type defaultValue: C{str} or C{unicode} or C{int} or C{float} or C{bool} or C{list} or C{dict} """ if self._serializer: if module is "FIFE": # check whether getAllSettings has been called already if self._readSettingsCompleted[module] is not True: value = self._serializer.get(module, name, defaultValue) if value is not None: return value else: if name in self._defaultSetting[module]: return self._defaultSetting[module][name] else: raise Exception(str(name) + ' is neither in settings.xml nor it has a default value set') else: if name in self._settingsFromFile[module]: return self._settingsFromFile[module][name] else: raise Exception(str(name) + ' is neither in settings.xml nor it has a default value set') else: return self._serializer.get(module, name, defaultValue) else: """ serializer not set, reading from default value """ if name in self._defaultSetting: return self._defaultSetting[module][name] else: raise Exception(str(name) + ' is neither in settings.xml nor it has a default value set') def set(self, module, name, value, extra_attrs={}): """ Sets a setting to specified value. @param module: Module where the setting should be set @param name: Name of setting @param value: Value to assign to setting @type value: C{str} or C{unicode} or C{int} or C{float} or C{bool} or C{list} or C{dict} @param extra_attrs: Extra attributes to be stored in the XML-file @type extra_attrs: C{dict} """ #update the setting cache if module in self._settingsFromFile: self._settingsFromFile[module][name] = value else: self._settingsFromFile[module] = { name: value } if self._serializer: self._serializer.set(module, name, value, extra_attrs) def remove(self, module, name): """ Removes a variable @param module: Module where the variable should be set @param name: Name of the variable """ #update the setting cache if module in self._settingsFromFile: del self._settingsFromFile[module][name] if self._serializer: self._serializer.remove(module, name) def setAvailableScreenResolutions(self, reslist): """ A list of valid default screen resolutions. This should be called once right after you instantiate Settings. Valid screen resolutions must be strings in the form of: WIDTHxHEIGHT Example: settings.setAvailableScreenResolutions(["800x600", "1024x768"]) """ self._resolutions = reslist def setDefaults(self): """ Overwrites the setting file with the default settings file. """ shutil.copyfile(self._default_settings_file, os.path.join(self._appdata, self._settings_file)) self.changesRequireRestart = True self.initSerializer() def _getEntries(self): return self._entries def _setEntries(self, entries): self._entries = entries def _getSerializer(self): return self._serializer entries = property(_getEntries, _setEntries) serializer = property(_getSerializer)
class Settings: # Settings key storing the SettingsVersion used to upgrade settings SETTINGS_VERSION = "SettingsVersion" def __init__(self, settings_file, settings_template_file): self._module_settings = {} self._module_settings_template = {} self._settings_file = settings_file self._settings_template_file = settings_template_file self._settings_serializer = SimpleXMLSerializer() self._settings_serializer.load(settings_file) self._settings_template_serializer = SimpleXMLSerializer() self._settings_template_serializer.load(settings_template_file) if not hasattr(self._settings_template_serializer, 'getModuleName'): # Renamed after 0.3.5: https://github.com/fifengine/fifengine/issues/819. new_api = self._settings_template_serializer.getModuleNameList self._settings_template_serializer.getModuleName = new_api self.upgrade_settings() def get(self, module, name, default=None): if default is None: default = self._settings_template_serializer.get(module, name) v = self._settings_serializer.get(module, name, default) getter = getattr(self, 'get_' + module + '_' + name, None) if getter: return getter(v) else: return v def set(self, module, name, value): setter = getattr(self, 'set_' + module + '_' + name, None) if setter: value = setter(value) # This is necessary, as empty fields return None, but saving # None will result in the String 'None' being stored if value is None: value = '' if module in self._module_settings: self._module_settings[module][name] = value self._settings_serializer.set(module, name, value, {}) def get_module_settings(self, module): self._module_settings[module] = self._settings_serializer.getAllSettings(module) self._module_settings_template[module] = self._settings_template_serializer.getAllSettings(module) for name, value in self._module_settings_template[module].items(): if name not in self._module_settings[module]: self._module_settings[module][name] = value return self._module_settings[module] def get_module_template_settings(self, module): return self._settings_template_serializer.getAllSettings(module) def save(self): self._settings_serializer.save(self._settings_file) def apply(self): data = self.get(SETTINGS.UH_MODULE, "Language") language = LANGUAGENAMES.get_by_value(data) change_language(language) def set_defaults(self): for module in self._settings_template_serializer.getModuleName(): for setting_name in self._settings_template_serializer.getAllSettings(module): value = self._settings_template_serializer.get(module, setting_name) self.set(module, setting_name, value) self.save() def upgrade_settings(self): """Upgrades the settings to a newer version necessary.""" # if the settings file doesn't exist, force an update with # settings version 1 as default value current_version = self.get(SETTINGS.META_MODULE, self.SETTINGS_VERSION, 1) template_version = self._settings_template_serializer.get(SETTINGS.META_MODULE, self.SETTINGS_VERSION) if current_version != template_version: print('Discovered old settings file, auto-upgrading: {} -> {}'.format( current_version, template_version)) for module in self._settings_template_serializer.getModuleName(): for setting_name in self._settings_template_serializer.getAllSettings(module): default_value = self._settings_template_serializer.get(module, setting_name) if self.get(module, setting_name, default=default_value) is default_value: self.set(module, setting_name, default_value) self.set(SETTINGS.META_MODULE, self.SETTINGS_VERSION, template_version) self.save() # settings def get_unknownhorizons_Language(self, value): if value is None: # the entry is None for empty strings value = "" return LANGUAGENAMES[value] def set_unknownhorizons_Language(self, value): return LANGUAGENAMES.get_by_value(value)
class Settings(object): # Settings key storing the SettingsVersion used to upgrade settings SETTINGS_VERSION = "SettingsVersion" def __init__(self, settings_file, settings_template_file): self._module_settings = {} self._module_settings_template = {} self._settings_file = settings_file self._settings_template_file = settings_template_file self._settings_serializer = SimpleXMLSerializer() self._settings_serializer.load(settings_file) self._settings_template_serializer = SimpleXMLSerializer() self._settings_template_serializer.load(settings_template_file) if not hasattr (self._settings_template_serializer, 'getModuleName'): # Renamed after 0.3.5: https://github.com/fifengine/fifengine/issues/819. new_api = self._settings_template_serializer.getModuleNameList self._settings_template_serializer.getModuleName = new_api self.upgrade_settings() def get(self, module, name, default=None): if default is None: default = self._settings_template_serializer.get(module, name) v = self._settings_serializer.get(module, name, default) getter = getattr(self, 'get_' + module + '_' + name, None) if getter: return getter(v) else: return v def set(self, module, name, value): setter = getattr(self, 'set_' + module + '_' + name, None) if setter: value = setter(value) # This is necessary, as empty fields return None, but saving # None will result in the String 'None' being stored if value is None: value = '' if module in self._module_settings: self._module_settings[module][name] = value self._settings_serializer.set(module, name, value, {}) def get_module_settings(self, module): self._module_settings[module] = self._settings_serializer.getAllSettings(module) self._module_settings_template[module] = self._settings_template_serializer.getAllSettings(module) for name, value in self._module_settings_template[module].iteritems(): if name not in self._module_settings[module]: self._module_settings[module][name] = value return self._module_settings[module] def get_module_template_settings(self, module): return self._settings_template_serializer.getAllSettings(module) def save(self): self._settings_serializer.save(self._settings_file) def apply(self): data = self.get(SETTINGS.UH_MODULE, "Language") language = LANGUAGENAMES.get_by_value(data) change_language(language) def set_defaults(self): for module in self._settings_template_serializer.getModuleName(): for setting_name in self._settings_template_serializer.getAllSettings(module): value = self._settings_template_serializer.get(module, setting_name) self.set(module, setting_name, value) self.save() def upgrade_settings(self): """Upgrades the settings to a newer version necessary.""" # if the settings file doesn't exist, force an update with # settings version 1 as default value current_version = self.get(SETTINGS.META_MODULE, self.SETTINGS_VERSION, 1) template_version = self._settings_template_serializer.get(SETTINGS.META_MODULE, self.SETTINGS_VERSION) if current_version != template_version: print 'Discovered old settings file, auto-upgrading: %s -> %s' % \ (current_version, template_version) for module in self._settings_template_serializer.getModuleName(): for setting_name in self._settings_template_serializer.getAllSettings(module): default_value = self._settings_template_serializer.get(module, setting_name) if self.get(module, setting_name, default=default_value) is default_value: self.set(module, setting_name, default_value) self.set(SETTINGS.META_MODULE, self.SETTINGS_VERSION, template_version) self.save() # settings def get_unknownhorizons_Language(self, value): if value is None: # the entry is None for empty strings value = "" return LANGUAGENAMES[value] def set_unknownhorizons_Language(self, value): return LANGUAGENAMES.get_by_value(value)
class Setting(object): """ This class manages loading and saving of game settings. Usage:: from fife.extensions.fife_settings import Setting settings = Setting(app_name="myapp") screen_width = settings.get("FIFE", "ScreenWidth", 1024) screen_height = settings.get("FIFE", "ScreenHeight", 768) """ def __init__(self, app_name="", settings_file="", default_settings_file= "settings-dist.xml", copy_dist=True, serializer=None): """ Initializes the Setting object. @param app_name: The applications name. If this parameter is provided alone it will try to read the settings file from the users home directory. In windows this will be something like: C:\Documents and Settings\user\Application Data\fife @type app_name: C{string} @param settings_file: The name of the settings file. If this parameter is provided it will look for the setting file as you specify it, first looking in the working directory. It will NOT look in the users home directory. @type settings_file: C{string} @param default_settings_file: The name of the default settings file. If the settings_file does not exist this file will be copied into the place of the settings_file. This file must exist in the root directory of your project! @type default_settings_file: C{string} @param settings_gui_xml: If you specify this parameter you can customize the look of the settings dialog box. @param copy_dist: Copies the default settings file to the settings_file location. If this is False it will create a new empty setting file. @param serializer: Overrides the default XML serializer @type serializer: C{SimpleSerializer} """ self._app_name = app_name self._settings_file = settings_file self._default_settings_file = default_settings_file # Holds SettingEntries self._entries = {} if self._settings_file == "": self._settings_file = "settings.xml" self._appdata = getUserDataDirectory("fife", self._app_name) else: self._appdata = os.path.dirname(self._settings_file) self._settings_file = os.path.basename(self._settings_file) if not os.path.exists(os.path.join(self._appdata, self._settings_file)): if os.path.exists(self._default_settings_file) and copy_dist: shutil.copyfile(self._default_settings_file, os.path.join(self._appdata, self._settings_file)) # valid values possible for the engineSettings self._validSetting = {} self._validSetting['FIFE'] = { 'FullScreen':[True,False], 'PychanDebug':[True,False] , 'ProfilingOn':[True,False], 'SDLRemoveFakeAlpha':[True,False], 'GLCompressImages':[False,True], 'GLUseFramebuffer':[False,True], 'GLUseNPOT':[False,True], 'GLUseMipmapping':[False,True], 'GLTextureFiltering':['None', 'Bilinear', 'Trilinear', 'Anisotropic'], 'GLUseMonochrome':[False,True], 'GLUseDepthBuffer':[False,True], 'GLAlphaTestValue':[0.0,1.0], 'RenderBackend':['OpenGL', 'SDL'], 'ScreenResolution':['640x480', '800x600', '1024x600', '1024x768', '1280x768', '1280x800', '1280x960', '1280x1024', '1366x768', '1440x900', '1600x900', '1600x1200', '1680x1050', '1920x1080', '1920x1200'], 'BitsPerPixel':[0,16,24,32], 'InitialVolume':[0.0,10.0], 'WindowTitle':"", 'WindowIcon':"", 'Font':"", 'FontGlyphs':"", 'DefaultFontSize':"", 'Lighting':[0,1], 'ColorKeyEnabled':[True,False], 'ColorKey':['a','b','c'], 'VideoDriver':"", 'PlaySounds':[True,False], 'LogToFile':[True,False], 'LogToPrompt':[True,False],'UsePsyco':[True,False], 'LogLevelFilter':[0,1,2,3], 'LogModules':['all', 'controller','script','video','audio','loaders','vfs','pool','view','model','metamodel','event_channel','xml'], 'FrameLimitEnabled':[True,False], 'FrameLimit':[0], 'MouseSensitivity':[0.0], 'MouseAcceleration':[True,False] } glyphDft = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/():;%&`'*#=[]\\\"" # we at this point assume default values are final values for engineSettings self._defaultSetting = {} self._defaultSetting['FIFE'] = { 'FullScreen':False, 'PychanDebug':False , 'ProfilingOn':False, 'SDLRemoveFakeAlpha':False, 'GLCompressImages':False, 'GLUseFramebuffer':True, 'GLUseNPOT':True, 'GLUseMipmapping':False, 'GLTextureFiltering':'None', 'GLUseMonochrome':False, 'GLUseDepthBuffer':False, 'GLAlphaTestValue':0.3, 'RenderBackend':'OpenGL', 'ScreenResolution':"1024x768", 'BitsPerPixel':0, 'InitialVolume':5.0, 'WindowTitle':"", 'WindowIcon':"", 'Font':"", 'FontGlyphs':glyphDft, 'DefaultFontSize':12, 'Lighting':0, 'ColorKeyEnabled':False, 'ColorKey':[255,0,255], 'VideoDriver':"", 'PlaySounds':True, 'LogToFile':False, 'LogToPrompt':False,'UsePsyco':False,'LogLevelFilter':[0], 'LogModules':['controller','script'], 'FrameLimitEnabled':False, 'FrameLimit':60, 'MouseSensitivity':0.0, 'MouseAcceleration':False } # has the settings file been read self._readSettingsCompleted = {} # the global dictionary from which we will read after self._readSettingsCompleted is True self._settingsFromFile = {} # the logger needed to write in log file. It will be initialized in this file when self.getSettings() # method is called by logger self._logger = None #default settings self._resolutions = self._validSetting['FIFE']['ScreenResolution'] self._renderbackends = self._validSetting['FIFE']['RenderBackend'] self._lightingmodels = self._validSetting['FIFE']['Lighting'] #Used to stylize the options gui self._gui_style = "default" #Initialize the serializer if serializer: self._serializer = serializer else: self._serializer = SimpleXMLSerializer() self.initSerializer() # Get all modules and initialize reading of them from xml file as false self._allModules = self._serializer.getModuleNameList() # print("All Module Names:",self._allModules) for module in self._allModules: self._readSettingsCompleted[module] = False self._initDefaultSettingEntries() #self.setOneSetting('FIFE','Font','fonts/FreeSans.ttf',False) #print self.getSettingsFromFile('unknownhorizons') # set all Settings in either validSetting or defaultSetting def setAllSettings(self,module,settings,validSetting = True): if validSettings: self._validSetting[module] = settings else: self._defaultSetting[module] = settings # set an entry in the validSetting or defaultSetting dictionary def setOneSetting(self,module,name,value,validSetting = True): if validSetting: self._validSetting[module][name] = value else: self._defaultSetting[module][name] = value # get all the Settings(either validSetting or defaultSetting) def getAllSettings(self,module,validSetting = True): if validSetting: return self._validSetting[module] else: return self._defaultSetting[module] # get an entry from either validSetting or defaultSetting def getOneSetting(self,module,name,validSetting = True): if validSetting: return self._validSetting[module][name] else: return self._defaultSetting[module][name] # sets valid resolution options in the settings->Resolution def setValidResolutions(self, options): if options: self._resolutions = options self.createAndAddEntry(FIFE_MODULE, "ScreenResolution", initialdata = self._resolutions, requiresrestart=True) def initSerializer(self): self._serializer.load(os.path.join(self._appdata, self._settings_file)) def _initDefaultSettingEntries(self): """Initializes the default fife setting entries. Not to be called from outside this class.""" self.createAndAddEntry(FIFE_MODULE, "PlaySounds", requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "FullScreen", requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "ScreenResolution", initialdata = self._resolutions, requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "RenderBackend", initialdata = self._renderbackends, requiresrestart=True) def createAndAddEntry(self, module, name, applyfunction=None, initialdata=None, requiresrestart=False): """" @param module: The Setting module this Entry belongs to @type module: C{String} @param name: The Setting's name @type name: C{String} @param applyfunction: function that makes the changes when the Setting is saved @type applyfunction: C{function} @param initialdata: If the widget supports the setInitialData() function this can be used to set the initial data @type initialdata: C{String} or C{Boolean} @param requiresrestart: Whether or not the changing of this setting requires a restart @type requiresrestart: C{Boolean} """ entry = SettingEntry(module, name, applyfunction, initialdata, requiresrestart) self.addEntry(entry) def addEntry(self, entry): """Adds a new C{SettingEntry} to the Settting @param entry: A new SettingEntry that is to be added @type entry: C{SettingEntry} """ if entry.module not in self._entries: self._entries[entry.module] = {} self._entries[entry.module][entry.name] = entry """ # Make sure the new entry is available if self.get(entry.module, entry.name) is None: print "Updating", self._settings_file, "to the default, it is missing the entry:"\ , entry.name ,"for module", entry.module #self.setDefaults() if self.get(entry.module, entry.name) is None: print "WARNING:", entry.module, ":", entry.name, "still not found!" """ def saveSettings(self, filename=""): """ Writes the settings to the settings file @param filename: Specifies the file to save the settings to. If it is not specified the original settings file is used. @type filename: C{string} """ if self._serializer: if filename == "": self._serializer.save(os.path.join(self._appdata, self._settings_file)) else: self._serializer.save(filename) # get all the settings of a module name module def getSettingsFromFile(self, module, logger=None): if self._serializer: self._logger = logger modules = self._serializer.getModuleNameList() self._settingsFromFile[module] = self._serializer.getAllSettings(module) if self._logger: self._logger.log_log("Loading Settings From File ...") if self._settingsFromFile[module] is not None: self._readSettingsCompleted[module] = True # we need validation for the module FIFE only if module is not "FIFE": return self._settingsFromFile[module] """ Now we have all the settings we needed. We have to validate the settings. Applicable for module FIFE only """ for name in self._settingsFromFile[module]: # if the setting name is known, so that it is # both in self._settingsFromFile and validSetting if name in self._validSetting[module]: e_value = self._settingsFromFile[module][name] if name == "InitialVolume": if e_value >= self._validSetting[module][name][0] and e_value <= self._validSetting[module][name][1]: self._settingsFromFile[module][name] = e_value else: if self._logger: self._logger.log_log("InitalVolume must have a value between 0.0 and 10.0") elif name == "GLAlphaTestValue": if e_value >= self._validSetting[module][name][0] and e_value <= self._validSetting[module][name][1]: self._settingsFromFile[module][name] = e_value else: if self._logger: self._logger.log_log("GLAlphaTestValue must have a value between 0.0 and 1.0") elif name == "ColorKey": e_value = e_value.split(',') if int(e_value[0]) in range(0,256) and int(e_value[1]) in range(0,256) and int(e_value[2]) in range(0,256): self._settingsFromFile[name] = [int(e_value[0]),int(e_value[1]),int(e_value[2])]; else: if self._logger: self._logger.log_log("ColorKey values must be within 0 and 255. Setting to Default Value.") elif name == "ScreenResolution": temp = e_value.split('x') if len(temp) == 2: self._settingsFromFile[module][name]=e_value else: if self._logger: self._logger.log_log("Invalid Screen Resolution value. We expect two integer separated by x") elif len(self._validSetting[module][name]) == 0: self._settingsFromFile[module][name] = e_value elif name == "LogModules": for checking_element in e_value: module_valid = False for base_element in self._validSetting[module][name]: # checking_element is valid if checking_element == base_element: module_valid = True already_in = False for element in self._settingsFromFile[module][name]: if element == checking_element: already_in = True if already_in == False: self._settingsFromFile[module][name].append(checking_element) if module_valid == False: if self._logger: self._logger.log_log(checking_element +" is not a valid logModule") elif name == "FrameLimit": if e_value > 0: self._settingsFromFile[module][name] = e_value else: if self._logger: self._logger.log_log(e_value + " is not a valid FrameLimit setting. You must specify a positive integer!") elif name == "MouseSensitivity": self._settingsFromFile[module][name] = e_value elif name == "MouseAcceleration": self._settingsFromFile[module][name] = e_value else: if isinstance(self._settingsFromFile[module][name],list) == True or isinstance(self._settingsFromFile[module][name],dict) == True: valid = False for value in self._validSetting[module][name]: if value == e_value: valid = True self._settingsFromFile[module][name] = e_value; if valid == False: if self._logger: self._logger.log_log("Setting " + name + " got invalid value. Setting to Default.") else: self._settingsFromFile[module][name] = e_value # name is unknown else: if self._logger: self._logger.log_log("Setting "+ name + " is unknown") if self._logger: self._logger.log_log("Settings Loaded ...") """ Upto this point we have validated all the settings that are in settings.xml file. But, what if a setting is valid and still it is not present in the settings.xml file. For this, we should give them the default Values that are in defaultSetting. """ for name in self._defaultSetting[module]: if name not in self._settingsFromFile[module]: self._settingsFromFile[module][name] = self._defaultSetting[module][name] return self._settingsFromFile[module] else: return None def get(self, module, name, defaultValue=None): """ Gets the value of a specified setting @param module: Name of the module to get the setting from @param name: Setting name @param defaultValue: Specifies the default value to return if the setting is not found @type defaultValue: C{str} or C{unicode} or C{int} or C{float} or C{bool} or C{list} or C{dict} """ if self._serializer: if module is "FIFE": # check whether getAllSettings has been called already if self._readSettingsCompleted[module] is not True: value = self._serializer.get(module, name, defaultValue) if value is not None: return value else: if name in self._defaultSetting[module]: return self._defaultSetting[module][name] else: raise Exception(str(name) + ' is neither in settings.xml nor it has a default value set') else: if name in self._settingsFromFile[module]: return self._settingsFromFile[module][name] else: raise Exception(str(name) + ' is neither in settings.xml nor it has a default value set') else: return self._serializer.get(module, name, defaultValue) else: """ serializer not set, reading from default value """ if name in self._defaultSetting: return self._defaultSetting[module][name] else: raise Exception(str(name) + ' is neither in settings.xml nor it has a default value set') def set(self, module, name, value, extra_attrs={}): """ Sets a setting to specified value. @param module: Module where the setting should be set @param name: Name of setting @param value: Value to assign to setting @type value: C{str} or C{unicode} or C{int} or C{float} or C{bool} or C{list} or C{dict} @param extra_attrs: Extra attributes to be stored in the XML-file @type extra_attrs: C{dict} """ #update the setting cache if module in self._settingsFromFile: self._settingsFromFile[module][name] = value else: self._settingsFromFile[module] = { name: value } if self._serializer: self._serializer.set(module, name, value, extra_attrs) def setAvailableScreenResolutions(self, reslist): """ A list of valid default screen resolutions. This should be called once right after you instantiate Settings. Valid screen resolutions must be strings in the form of: WIDTHxHEIGHT Example: settings.setAvailableScreenResolutions(["800x600", "1024x768"]) """ self._resolutions = reslist def setDefaults(self): """ Overwrites the setting file with the default settings file. """ shutil.copyfile(self._default_settings_file, os.path.join(self._appdata, self._settings_file)) self.changesRequireRestart = True self.initSerializer() def _getEntries(self): return self._entries def _setEntries(self, entries): self._entries = entries def _getSerializer(self): return self._serializer entries = property(_getEntries, _setEntries) serializer = property(_getSerializer)
class InteractiveObject(fife.InstanceActionListener): def __init__(self, objectmanager, model, file): fife.InstanceActionListener.__init__(self) self._manager = objectmanager self._model = model self._objectFile = SimpleXMLSerializer(file) self._agentName = self._objectFile.get("object", "agentname", "dummy") self._layer = self._manager._world._map.getLayer(self._objectFile.get("object", "layer", "player")) self._agent = self._layer.getInstance(self._agentName) self._agent.addActionListener(self) self._status = self._objectFile.get("object", "status", 'INACTIVE') self._actions = { 'use' : self.use, 'destroy' : self.destroy, 'turnon' : self.activate, 'turnoff' : self.deactivate, 'explode' : self.explode, 'describe': self.describe, 'glitch' : self.glitch } self._availableactions = { 'use' : False, 'destroy' : False, 'turnon' : False, 'turnoff' : False, 'explode' : False, 'describe' : True, 'glitch' : False } actionstr = self._objectFile.get("object", "actions", None) actions = self._objectFile._deserializeDict(actionstr) for action, bool in actions.iteritems(): if bool in ("True"): self._availableactions[action] = True else: self._availableactions[action] = False self._description = self._objectFile.get("object", "description", "I can see something, but\n I can't tell what it is") self._talk = self._objectFile.get("object", "talk", False) self._message = self._objectFile._deserializeList(self._objectFile.get("object", "messages", "")) self._usesound = self._objectFile.get("object", "sound", False) if self._usesound: self._manager._world._sounds._loadclip(self._agentName, self._objectFile.get("object", "soundfile", ""), False, False) self._sound = self._manager._world._sounds._emitters[self._agentName] self._loadObject() self.onInstanceActionFinished(self._agent, "") def onInstanceActionFinished(self, instance, action): if self._status == 'ACTIVE': self._agent.act('on', self._agent.getFacingLocation()) elif self._status == 'INACTIVE': self._agent.act('off', self._agent.getFacingLocation()) elif self._status == 'DESTROYED': self._agent.act('dead', self._agent.getFacingLocation()) elif self._status == 'GLITCHED': self._agent.act('glitch', self._agent.getFacingLocation()) def use(self): if self._status == 'ACTIVE': self._agent.act('use', self._agent.getFacingLocation()) self._manager._world._player._agent.setFacingLocation(self._agent.getLocation()) if self._noactioncallbacks == 0: self._action() elif self._noactioncallbacks == 1: self._action(self._actioncallbacks[0]) elif self._noactioncallbacks == 2: self._action(self._actioncallbacks[0], self._actioncallbacks[1]) elif self._noactioncallbacks == 3: self._action(self._actioncallbacks[0], self._actioncallbacks[1], self._actioncallbacks[2]) elif self._noactioncallbacks == 4: self._action(self._actioncallbacks[0], self._actioncallbacks[1], self._actioncallbacks[2], self._actioncallbacks[3]) elif self._noactioncallbacks == 5: self._action(self._actioncallbacks[0], self._actioncallbacks[1], self._actioncallbacks[2], self._actioncallbacks[3], self._actioncallbacks[4]) if self._talk: rand = random.randint(0, len(self._message) - 1) self._manager._world._player._agent.say(self._message[rand], 3500) if self._usesound: self._sound.play() def destroy(self): self._agent.act('die', self._agent.getFacingLoaction) self._status = 'DESTROYED' def activate(self): self._agent.act('turnon', self._agent.getFacingLoaction) self._status = 'ACTIVE' def deactivate(self): self._agent.act('turnoff', self._agent.getFacingLoaction) self._status = 'INACTIVE' def explode(self): self._agent.act('explode', self._agent.getFacingLoaction) self._status = 'DESTROYED' def describe(self): self._manager._world._player._agent.say(self._description, 5000) def glitch(self): self._agent.act('glitch', self._agent.getFacingLoaction) self._status = 'GLITCHED' def noAction(self): pass # This function exists purely to act as a void function # for objects that make a pretty light def _loadObject(self): action = self._objectFile.get("object", "action", "none") if action == "none": self._action = self.noAction self._noactioncallbacks = 0 self._actioncallbacks = {} elif action == "door": loc1 = fife.Location() loc1.setLayer(self._manager._world._map.getLayer('player')) loc1.setExactLayerCoordinates(fife.ExactModelCoordinate(self._file.get("event", "newx", 0), self._file.get("event", "newy", 0))) loc2 = fife.Location() loc2.setLayer(self._manager._world._map.getLayer('player')) loc2.setExactLayerCoordinates(fife.ExactModelCoordinate(self._file.get("event", "refx", 0), self._file.get("event", "refy", 0))) self._action = self._manager._world._loadMap self._noactioncallbacks = 5 self._actioncallbakcs = { 0 : self._objectFile.get("object", "mapfile", "") , 1 : 'LEVEL' , 2 : True , 3 : loc1 , 4 : loc2 } elif action == "plot": self._action = self._manager._world._eventtracker._evaluateItem self._noactioncallbacks = 1 self._actioncallbacks = { 0 : self._agentName } elif action == "book": pass # Needs GUI manager elif action == "computer": pass # Needs GUI manager elif action == "teleport": pass # Needs hooks in the player and NPC classes
class Settings(object): # Settings key storing the SettingsVersion used to upgrade settings SETTINGS_VERSION = "SettingsVersion" def __init__(self, settings_file, settings_template_file): self._module_settings = {} self._module_settings_template = {} self._settings_file = settings_file self._settings_template_file = settings_template_file self._settings_serializer = SimpleXMLSerializer() self._settings_serializer.load(settings_file) self._settings_template_serializer = SimpleXMLSerializer() self._settings_template_serializer.load(settings_template_file) self.upgrade_settings() def get(self, module, name, default=None): if default is None: default = self._settings_template_serializer.get(module, name) v = self._settings_serializer.get(module, name, default) getter = getattr(self, 'get_' + module + '_' + name, None) if getter: return getter(v) else: return v def set(self, module, name, value): setter = getattr(self, 'set_' + module + '_' + name, None) if setter: value = setter(value) # This is necessary, as empty fields return None, but saving # None will result in the String 'None' being stored if value is None: value = '' if module in self._module_settings: self._module_settings[module][name] = value self._settings_serializer.set(module, name, value, {}) def get_module_settings(self, module): self._module_settings[module] = self._settings_serializer.getAllSettings(module) self._module_settings_template[module] = self._settings_template_serializer.getAllSettings(module) for name, value in self._module_settings_template[module].iteritems(): if name not in self._module_settings[module]: self._module_settings[module][name] = value return self._module_settings[module] def get_module_template_settings(self, module): return self._settings_template_serializer.getAllSettings(module) def save(self): self._settings_serializer.save(self._settings_file) def apply(self): data = self.get(SETTINGS.UH_MODULE, "Language") language = LANGUAGENAMES.get_by_value(data) change_language(language) def set_defaults(self): for module in self._settings_template_serializer.getModuleName(): for setting_name in self._settings_template_serializer.getAllSettings(module): value = self._settings_template_serializer.get(module, setting_name) self.set(module, setting_name, value) self.save() def upgrade_settings(self): """Upgrades the settings to a newer version necessary.""" current_version = self.get(SETTINGS.META_MODULE, self.SETTINGS_VERSION) template_version = self._settings_template_serializer.get(SETTINGS.META_MODULE, self.SETTINGS_VERSION) if current_version != template_version: print 'Discovered old settings file, auto-upgrading: %s -> %s' % \ (current_version, template_version) for module in self._settings_template_serializer.getModuleName(): for setting_name in self._settings_template_serializer.getAllSettings(module): default_value = self._settings_template_serializer.get(module, setting_name) if self.get(module, setting_name, default=default_value) is default_value: self.set(module, setting_name, default_value) self.set(SETTINGS.META_MODULE, self.SETTINGS_VERSION, template_version) self.save() # settings def get_unknownhorizons_Language(self, value): if value is None: # the entry is None for empty strings value = "" return LANGUAGENAMES[value] def set_unknownhorizons_Language(self, value): return LANGUAGENAMES.get_by_value(value)
def _setup_settings(self, check_file_version=True): # NOTE: SimpleXMLSerializer can't handle relative paths, it fails silently # (although the doc states otherwise) - thus translate paths to absolute ones _template_config_file = os.path.join(os.getcwd(), PATHS.CONFIG_TEMPLATE_FILE) template_config_parser = SimpleXMLSerializer(_template_config_file) template_settings_version = template_config_parser.get( "meta", "SettingsVersion") self._default_hotkeys = template_config_parser.getAllSettings( KEY_MODULE) _user_config_file = os.path.join(os.getcwd(), PATHS.USER_CONFIG_FILE) if check_file_version and os.path.exists(_user_config_file): # check if user settings file is the current one user_config_parser = SimpleXMLSerializer(_user_config_file) user_settings_version = user_config_parser.get( "meta", "SettingsVersion", -1) if template_settings_version > user_settings_version: # we have to update the file print 'Discovered old settings file, auto-upgrading: %s -> %s' % \ (user_settings_version, template_settings_version) # create settings so we have a list of all settings self._setup_settings(check_file_version=False) # save settings here entries = [] # need safe default value default_value = object() def update_value(modulename, entryname): # retrieve values from loaded settings file try: value = self._setting.get(modulename, entryname, default_value) except UnicodeEncodeError: # this can happen when unicode data is saved as str value = "default" if value is not default_value: entries.append((modulename, entryname, value)) # collect values from known settings and unreferenced settings for modulename, module in self._setting.entries.iteritems(): for entryname in module.iterkeys(): update_value(modulename, entryname) for modulename, entry_list in self.UNREFERENCED_SETTINGS.iteritems( ): for entryname in entry_list: update_value(modulename, entryname) # patch old values if user_settings_version <= 10: old_entries = entries entries = [] for i in old_entries: if i[0] == UH_MODULE and i[1] == "Language": entries.append( (i[0], i[1], LANGUAGENAMES.get_by_value(i[2]))) else: entries.append(i) # write actual new file shutil.copy(PATHS.CONFIG_TEMPLATE_FILE, PATHS.USER_CONFIG_FILE) user_config_parser = SimpleXMLSerializer(_user_config_file) for modulename, entryname, value in entries: user_config_parser.set(modulename, entryname, value) user_config_parser.save() self._setting = SettingsDialog( app_name=UH_MODULE, settings_file=PATHS.USER_CONFIG_FILE, settings_gui_xml="settings.xml", changes_gui_xml="requirerestart.xml", default_settings_file=PATHS.CONFIG_TEMPLATE_FILE) self._setting_handler.add_settings()
class Event(): def __init__(self, eventfile, tracker): self._file = SimpleXMLSerializer(filename=eventfile) self._eventname = self._file.get("event", "name", len(tracker._events)) self._status = 'INACTIVE' self._type = self._file.get("event", "type", "dummy") self._tracker = tracker if self._file.get("event", "active", False): self._status = 'ACTIVE' self._repeating = self._file.get("event", "repeating", False) self._activates = self._file.get("event", "activates", "none") if self._type == "dummy": pass self._status = 'FULFILLED' if self._type == "trip": self._target = self._file.get("event", "target", None) self._x = self._file.get("event", "x", 0) self._y = self._file.get("event", "y", 0) if self._type == "areatrip": self._target = self._file.get("event", "target", None) self._xmin = self._file.get("event", "xmin", 0) self._xmax = self._file.get("event", "xmax", 0) self._ymin = self._file.get("event", "ymin", 0) self._ymax = self._file.get("event", "ymax", 0) if self._type == "item": self._item = self._file.get("event", "item", None) if self._type == "dialogue": self._dialogue = self._file.get("event", "dialogue") if self._type == "plot": self._subtype = self._file.get("event", "subtype", "dummy") if self._subtype == "dummy": pass self._status = 'FULFILLED' if self._subtype == "trip": self._target = self._file.get("event", "target", None) self._x = self._file.get("event", "x", 0) self._y = self._file.get("event", "y", 0) if self._subtype == "areatrip": self._target = self._file.get("event", "target", None) self._xmin = self._file.get("event", "xmin", 0) self._xmax = self._file.get("event", "xmax", 0) self._ymin = self._file.get("event", "ymin", 0) self._ymax = self._file.get("event", "ymax", 0) if self._subtype == "item": self._item = self._file.get("event", "item", None) if self._subtype == "dialogue": self._dialogue = self._file.get("event", "dialogue") action = self._file.get("event", "action", "none") if action == "eventmusic": self._tracker._eventmusic[self._eventname] = ThreePartMusic(self._file.get("event", "musicintro", ""), self._file.get("event", "musicloop", ""), self._file.get("event", "musicend", ""), True, tracker._musicmanager._soundmanager) self._action = self._tracker._eventmusic(self._eventname)._play self._noactioncallbacks = 0 self._actioncallbacks = {} elif action == "playsound": self._action = self._tracker._musicmanager._startClip self._noactioncallbacks = 1 self._actioncallbacks = {0: self._file.get("event", "clip", "default")} elif action == "stopsound": self._action = self._tracker._musicmanager._startClip self._noactioncallbacks = 1 self._actioncallbacks = {0: self._file.get("event", "clip", "default")} elif action == "swapmap": self._action = self._tracker._world._loadMap self._noactioncallbacks = 2 self._actioncallbacks = {0: self._file.get("event", "newmap", ""), 1: 'LEVEL'} elif action == "movenpc": self._action = self._tracker._world._npcs[self._file.get("event", "npc", "")].run location = fife.Location() location.setLayer(tracker._world._map.getLayer('player')) location.setExactLayerCoordinates(fife.ExactModelCoordinate(self._file.get("event", "newx", 0), self._file.get("event", "newy", 0))) self._actioncallbacks = {0: location} elif action == "moveplayer": self._action = self._tracker._world._player.run location = fife.Location() location.setLayer(tracker._world._map.getLayer('player')) location.setExactLayerCoordinates(fife.ExactModelCoordinate(self._file.get("event", "newx", 0), self._file.get("event", "newy", 0))) self._actioncallbacks = {0: location} elif action == "npcaction": reaction = self._file.get("event", "clip", "default") if self._tracker._world._npcs[self._file.get("event", "npc", "")]._availableActions[reaction]: self._action = self._tracker._world._npcs[self._file.get("event", "npc", "")]._action[reaction] self._noactioncallbacks = 0 elif action == "playeraction": reaction = self._file.get("event", "clip", "default") if self._tracker._world._player._availableActions[reaction]: self._action = self._tracker._world._player._action[reaction] self._noactioncallbacks = 0 elif action == "portnpc": self._action = self._tracker._world._npcs[self._file.get("event", "npc", "")]._agent.setLocation location = fife.Location() location.setLayer(tracker._world._map.getLayer('player')) location.setExactLayerCoordinates(fife.ExactModelCoordinate(self._file.get("event", "newx", 0), self._file.get("event", "newy", 0))) self._actioncallbacks = {0: location} elif action == "portplayer": self._action = self._tracker._world._player._agent.setLocation self._noactioncallbacks = 1 location = fife.Location() location.setLayer(tracker._world._map.getLayer('player')) location.setExactLayerCoordinates(fife.ExactModelCoordinate(self._file.get("event", "newx", 0), self._file.get("event", "newy", 0))) self._actioncallbacks = {0: location} def _evaluate(self, item=None): if self._target == "player": loc = self._tracker._world._player._agent.getLocation().getExactLayerCoordinates() else: loc = self._tracker._world._npcs[self._target]._agent.getLocation().getExactLayerCoordinates() if self._type == "plot": type = self._subtype plot = True else: type = self._type plot = False if type == "trip": if int(loc.x) == self._x and int(loc.y) == self._y: if self._noactioncallbacks == 0: self._action() elif self._noactioncallbacks == 1: self._action(self._actioncallbacks[0]) elif self._noactioncallbacks == 2: self._action(self._actioncallbacks[0], self._actioncallbacks[1]) elif self._noactioncallbacks == 3: self._action(self._actioncallbacks[0], self._actioncallbacks[1], self._actioncallbacks[2]) if self._repeating: self._status = 'ACTIVE' else: self._status = 'FULFILLED' if self._activates != "none": self._tracker._events[self._activates]._status = 'ACTIVE' elif type == "areatrip": if loc.x >= self._xmin and loc.x <= self._xmax and loc.y >= self._ymin and loc.y <= self._ymax: if self._noactioncallbacks == 0: self._action() elif self._noactioncallbacks == 1: self._action(self._actioncallbacks[0]) elif self._noactioncallbacks == 2: self._action(self._actioncallbacks[0], self._actioncallbacks[1]) elif self._noactioncallbacks == 3: self._action(self._actioncallbacks[0], self._actioncallbacks[1], self._actioncallbacks[2]) if self._repeating: self._status = 'ACTIVE' else: self._status = 'FULFILLED' if self._activates != "none": self._tracker._events[self._activates]._status = 'ACTIVE' elif type == "item": if item != None and item == self._item: if self._noactioncallbacks == 0: self._action() elif self._noactioncallbacks == 1: self._action(self._actioncallbacks[0]) elif self._noactioncallbacks == 2: self._action(self._actioncallbacks[0], self._actioncallbacks[1]) elif self._noactioncallbacks == 3: self._action(self._actioncallbacks[0], self._actioncallbacks[1], self._actioncallbacks[2]) if self._repeating: self._status = 'ACTIVE' else: self._status = 'FULFILLED' if self._activates != "none": self._tracker._events[self._activates]._status = 'ACTIVE' elif type == "dialogue": if self._dialogue in self._tracker._world._player._plots: if self._noactioncallbacks == 0: self._action() elif self._noactioncallbacks == 1: self._action(self._actioncallbacks[0]) elif self._noactioncallbacks == 2: self._action(self._actioncallbacks[0], self._actioncallbacks[1]) elif self._noactioncallbacks == 3: self._action(self._actioncallbacks[0], self._actioncallbacks[1], self._actioncallbacks[2]) if self._repeating: self._status = 'ACTIVE' else: self._status = 'FULFILLED' if self._activates != "none": self._tracker._events[self._activates]._status = 'ACTIVE'
class QuestManager(Serializer): def __init__(self, gamecontroller): self._gamecontroller = gamecontroller self._questsettings = None self._quests = {} self._activequests = [] self._completedquests = [] def serialize(self): pass def deserialize(self, valuedict=None): questfile = self._gamecontroller.settings.get("RPG", "QuestFile", "maps/quests.xml") self._questsettings = SimpleXMLSerializer(questfile) for identifier in self._questsettings.get("QuestGivers", "list", []): for quest in self._questsettings.get(identifier, "questlist", []): questdict = self._questsettings.get(identifier, quest, {}) if questdict['type'] == "RETURN_ITEM": questobj = ReturnItemQuest(identifier, quest, questdict['name'], questdict['desc']) for ritem in self._questsettings.get( quest + "_items", "itemlist", []): itemdict = self._questsettings.get( quest + "_items", ritem, {}) if itemdict["name"] == "GOLD_COINS": questobj.addRequiredGold(int(itemdict['value'])) else: questobj.addRequiredItem(ritem) else: questobj = Quest(identifier, quest, questdict['name'], questdict['desc']) if questdict.has_key("quest_incomplete_dialog"): questobj._incomplete_dialog = questdict[ 'quest_incomplete_dialog'] if questdict.has_key("quest_complete_dialog"): questobj._complete_dialog = questdict[ 'quest_complete_dialog'] self._gamecontroller.questmanager.addQuest(questobj) def reset(self): self._quests = {} self._activequests = [] self._completedquests = [] def addQuest(self, quest): if self._quests.has_key(quest.ownerid): if not quest in self._quests[quest.ownerid]: self._quests[quest.ownerid].append(quest) else: self._quests[quest.ownerid] = [quest] def getQuest(self, questid): for owner in self._quests: for quest in self._quests[owner]: if quest.id == questid: return quest return None def getNextQuest(self, ownerid): if self._quests.has_key(ownerid): for quest in self._quests[ownerid]: if not quest in self._activequests and not quest in self._completedquests: return quest return None def activateQuest(self, quest): """ Adds the quest to the "active quests" list. Note that this does NOT affect the quest in any way. It's just a way of keeping track of which quests the player has accepted. """ if not quest in self._activequests: self._activequests.append(quest) def completeQuest(self, quest): """ Marks the quest as completed. Note that this does NOT modify the quest in any way. This is just a way to keep track of completed quests. """ if not quest in self._completedquests: self._completedquests.append(quest) if quest in self._activequests: self._activequests.remove(quest) def activateQuestById(self, questid): quest = self.getQuest(questid) if quest: self.activateQuest(quest) def completeQuestById(self, questid): quest = self.getQuest(questid) if quest: self.completeQuest(quest) def _getActiveQuests(self): return self._activequests def _getCompletedQuests(self): return self._completedquests def _getAllQuests(self): return self._quests activequests = property(_getActiveQuests) completedquests = property(_getCompletedQuests) quests = property(_getAllQuests)
def _setup_settings(self, check_file_version=True): _user_config_file = os.path.join( os.getcwd(), PATHS.USER_CONFIG_FILE ) if not os.path.exists(_user_config_file): check_file_version = False if check_file_version: # check if user settings file is the current one # NOTE: SimpleXMLSerializer can't handle relative paths, it fails silently # (although the doc states otherwise) - thus translate paths to absolute ones user_config_parser = SimpleXMLSerializer( _user_config_file ) user_settings_version = user_config_parser.get("meta", "SettingsVersion", -1) _template_config_file = os.path.join( os.getcwd(), PATHS.CONFIG_TEMPLATE_FILE ) template_config_parser = SimpleXMLSerializer( _template_config_file ) template_settings_version = template_config_parser.get("meta", "SettingsVersion") if template_settings_version > user_settings_version: # we have to update the file # create settings so we have a list of all settings self._setup_settings(check_file_version=False) # save settings here entries = [] def update_value(modulename, entryname): # retrieve values from loaded settings file try: value = self._setting.get(modulename, entryname) except UnicodeEncodeError: # this can happen when unicode data is saved as str value = "default" entries.append( (modulename, entryname, value ) ) # update known settings and unreferenced settings for modulename, module in self._setting.entries.iteritems(): for entryname in module.iterkeys(): update_value(modulename, entryname) for modulename, entry_list in self.UNREFERENCED_SETTINGS.iteritems(): for entryname in entry_list: update_value(modulename, entryname) # write actual new file shutil.copy( PATHS.CONFIG_TEMPLATE_FILE, PATHS.USER_CONFIG_FILE ) user_config_parser = SimpleXMLSerializer( _user_config_file ) for modulename, entryname, value in entries: user_config_parser.set(modulename, entryname, value) user_config_parser.save() self._setting = LocalizedSetting(app_name=UH_MODULE, settings_file=PATHS.USER_CONFIG_FILE, settings_gui_xml="settings.xml", changes_gui_xml="requirerestart.xml", default_settings_file=PATHS.CONFIG_TEMPLATE_FILE) # TODO: find a way to apply changing to a running game in a clean fashion # possibility: use singaling via changelistener def update_minimap(*args): try: horizons.main._modules.session.ingame_gui.minimap.draw() except AttributeError: pass # session or gui not yet initialised def update_autosave_interval(*args): try: horizons.main._modules.session.reset_autosave() except AttributeError: pass # session or gui not yet initialised #self.createAndAddEntry(self, module, name, widgetname, applyfunction=None, initialdata=None, requiresrestart=False) self._setting.createAndAddEntry(UH_MODULE, "AutosaveInterval", "autosaveinterval", applyfunction=update_autosave_interval) self._setting.createAndAddEntry(UH_MODULE, "AutosaveMaxCount", "autosavemaxcount") self._setting.createAndAddEntry(UH_MODULE, "QuicksaveMaxCount", "quicksavemaxcount") self._setting.createAndAddEntry(UH_MODULE, "EdgeScrolling", "edgescrolling") self._setting.createAndAddEntry(UH_MODULE, "UninterruptedBuilding", "uninterrupted_building") self._setting.createAndAddEntry(UH_MODULE, "MinimapRotation", "minimaprotation", \ applyfunction=update_minimap) self._setting.createAndAddEntry(FIFE_MODULE, "BitsPerPixel", "screen_bpp", initialdata=[0, 16, 32], requiresrestart=True) languages_map = dict(find_available_languages()) languages_map[_('System default')] = '' # English is not shipped as .mo file. languages_map['en'] = '' self._setting.createAndAddEntry(UH_MODULE, "Language", "language", applyfunction=self.update_languages, initialdata= [LANGUAGENAMES[x] for x in sorted(languages_map.keys())]) self._setting.createAndAddEntry(UH_MODULE, "VolumeMusic", "volume_music", applyfunction=self.set_volume_music) self._setting.createAndAddEntry(UH_MODULE, "VolumeEffects", "volume_effects", applyfunction=self.set_volume_effects) self._setting.createAndAddEntry(UH_MODULE, "NetworkPort", "network_port", applyfunction=self.set_network_port) self._setting.entries[FIFE_MODULE]['PlaySounds'].applyfunction = lambda x: self.setup_sound() self._setting.entries[FIFE_MODULE]['PlaySounds'].requiresrestart = False self._setting.entries[FIFE_MODULE]['RenderBackend'].applyfunction = lambda x: self._show_renderbackend_warning()
class NPC(Agent): def __init__(self, settings, model, agentName, layer, world, uniqInMap=True, name=""): super(NPC, self).__init__(settings, model, agentName, layer, uniqInMap) self._state = _STATE_NONE self._name = name self._agentName = agentName self._layer = layer self._availableActions = { 'walk': False, 'run': False, 'talk': False, 'die': False, 'explode': False, 'holdgun': False, 'firegun': False, 'beshot': False, 'walkgun': False, 'rungun': False, 'diegun': False, 'beshotgun': False, 'holdpistol': False, 'aimpistolleft': False, 'aimpistolright': False, 'firepistolleft': False, 'firepistolright': False, 'walkpistol': False, 'runpistol': False, 'diepistol': False, 'beshotpistol': False, 'teleportstart': False, 'teleportend': False, 'glitch': False, 'describe' : True} self._action = { 'walk': self.walk, 'run': self.run, 'talk': self.talk, 'die': self.die, 'explode': self.explode, 'holdgun': self._idle, 'firegun': self.fire, 'beshot': self.beshot, 'walkgun': self.walk, 'rungun': self.run, 'diegun': self.die, 'beshotgun': self.beshot, 'holdpistol': self._idle, 'aimpistolleft': self.aimleft, 'aimpistolright': self.aimright, 'firepistolleft': self.fireleft, 'firepistolright': self.fireright, 'walkpistol': self.walk, 'runpistol': self.run, 'diepistol': self.die, 'beshotpistol': self.beshot, 'teleportstart': self.teleportstart, 'teleportend': self.teleportend, 'glitch': self.glitch, 'decribe' : self.describe } self._world = world self._loadNPC(self._name) def _loadNPC(self, name): self._npcFile = SimpleXMLSerializer(filename="npcs/" + name + ".xml") actionstr = self._npcFile.get("npc", "actions", None) actions = self._npcFile._deserializeDict(actionstr) for action, bool in actions.iteritems(): if bool == "True": self._availableActions[action] = True else: self._availableActions[action] = False self._actionchance = self._npcFile.get("npc", "actionchance", 0) self._description = self._npcFile.get("npc", "description", "I can see a mysterious figure,\n but I can't quite make them out.") self._autowalk = self._npcFile.get("npc", "autowalk", True) self._hasdialogue = self._npcFile.get("npc", "hasdialogue", False) self._autowalk = self._npcFile.get("npc", "autowalk", True) self._loadDialogue() self._idle() def _loadDialogue(self): if not self._hasdialogue: return self._dialogue = {} self._idledialogue = [] index = [] index = self._npcFile._deserializeList(self._npcFile.get("dialogue", "index", "")) for line in index: self._dialogue[line] = self._npcFile._deserializeDict(self._npcFile.get("dialogue", line, "")) idleindex = self._npcFile._deserializeList(self._npcFile.get("dialogue", "idleindex", "")) for line in idleindex: self._idledialogue.append(self._dialogue[line]) def _listAvailableTopics(self): returninglist = [] if not self._hasdialogue: return returninglist for index, dialogue in self._dialogue.iteritems(): if dialogue["requires"] in self._world._player._plots or dialogue["requires"] == '0' and dialogue not in self._idledialogue: returninglist.append((index, dialogue["topic"])) return returninglist def _talk(self, index): if self._world._gamestate == 'LEVEL' and index not in self._world._player._plots: self._world._player._plots.append(index) self._agent.say(self._dialogue[index]["text"], 5000) def onInstanceActionFinished(self, instance, action): self._idle() def _idle(self): self._state = _STATE_IDLE if self._autowalk: chance = random.randint(0,100) if chance < self._actionchance: self._waypointmove() else: self._agent.act('walk', self._agent.getFacingLocation()) chance = random.randint(0,100) if chance < self._actionchance / 2 and self._hasdialogue: self.talk() def _waypointmove(self): no = random.randint(0, len(self._world._waypoints) - 1) point = self._world._waypoints[no] x, point, y = point.partition(',') location = fife.Location() location.setLayer(self._layer) location.setExactLayerCoordinates(fife.ExactModelCoordinate(int(x) + random.randint(-1,1), int(y) + random.randint(-1,1))) self.run(location) def run(self, location): self._state = _STATE_RUN self._agent.move('walk', location, 0.75) def walk(self): pass def talk(self): chance = random.randint(0, len(self._idledialogue) - 1) self._talk(self._idledialogue[chance]["index"]) def die(self): pass def explode(self): pass def beshot(self): pass def aimleft(self): pass def aimright(self): pass def fire(self): pass def fireleft(self): pass def fireright(self): pass def teleportstart(self): pass def teleportend(self): pass def glitch(self): pass def describe(self): self._world._player._agent.say(self._description, 5000)
class Setting(object): """ This class manages loading and saving of game settings. Usage:: from fife.extensions.fife_settings import Setting settings = Setting(app_name="myapp") screen_width = settings.get("FIFE", "ScreenWidth", 1024) screen_height = settings.get("FIFE", "ScreenHeight", 768) """ def __init__(self, app_name="", settings_file="", default_settings_file="settings-dist.xml", settings_gui_xml="", changes_gui_xml="", copy_dist=True, serializer=None): """ Initializes the Setting object. @param app_name: The applications name. If this parameter is provided alone it will try to read the settings file from the users home directory. In windows this will be something like: C:\Documents and Settings\user\Application Data\fife @type app_name: C{string} @param settings_file: The name of the settings file. If this parameter is provided it will look for the setting file as you specify it, first looking in the working directory. It will NOT look in the users home directory. @type settings_file: C{string} @param default_settings_file: The name of the default settings file. If the settings_file does not exist this file will be copied into the place of the settings_file. This file must exist in the root directory of your project! @type default_settings_file: C{string} @param settings_gui_xml: If you specify this parameter you can customize the look of the settings dialog box. @param copy_dist: Copies the default settings file to the settings_file location. If this is False it will create a new empty setting file. @param serializer: Overrides the default XML serializer @type serializer: C{SimpleSerializer} """ self._app_name = app_name self._settings_file = settings_file self._default_settings_file = default_settings_file self._settings_gui_xml = settings_gui_xml self._changes_gui_xml = changes_gui_xml self.OptionsDlg = None # Holds SettingEntries self._entries = {} if self._settings_file == "": self._settings_file = "settings.xml" self._appdata = getUserDataDirectory("fife", self._app_name) else: self._appdata = os.path.dirname(self._settings_file) self._settings_file = os.path.basename(self._settings_file) if self._settings_gui_xml == "": self._settings_gui_xml = SETTINGS_GUI_XML if self._changes_gui_xml == "": self._changes_gui_xml = CHANGES_REQUIRE_RESTART if not os.path.exists(os.path.join(self._appdata, self._settings_file)): if os.path.exists(self._default_settings_file) and copy_dist: shutil.copyfile( self._default_settings_file, os.path.join(self._appdata, self._settings_file)) # valid values possible for the engineSettings self._validSetting = {} self._validSetting['FIFE'] = { 'FullScreen': [True, False], 'PychanDebug': [True, False], 'ProfilingOn': [True, False], 'SDLRemoveFakeAlpha': [0, 1], 'GLCompressImages': [False, True], 'GLUseFramebuffer': [False, True], 'GLUseNPOT': [False, True], 'RenderBackend': ['OpenGL', 'SDL', 'OpenGLe'], 'ScreenResolution': [ '640x480', '800x600', '1024x600', '1024x768', '1280x768', '1280x800', '1280x960', '1280x1024', '1366x768', '1440x900', '1600x900', '1600x1200', '1680x1050', '1920x1080', '1920x1200' ], 'BitsPerPixel': [0, 16, 24, 32], 'InitialVolume': [0.0, 10.0], 'WindowTitle': "", 'WindowIcon': "", 'Font': "", 'FontGlyphs': "", 'DefaultFontSize': "", 'Lighting': [0, 1], 'ColorKeyEnabled': [True, False], 'ColorKey': ['a', 'b', 'c'], 'VideoDriver': "", 'PlaySounds': [True, False], 'LogToFile': [0, 1], 'LogToPrompt': [0, 1], 'UsePsyco': [True, False], 'LogLevelFilter': [0, 1, 2, 3], 'LogModules': [ 'all', 'controller', 'script', 'video', 'audio', 'loaders', 'vfs', 'pool', 'view', 'model', 'metamodel', 'event_channel', 'xml' ], 'FrameLimitEnabled': [True, False], 'FrameLimit': [0], 'MouseSensitivity': [0.0], 'MouseAcceleration': [True, False] } glyphDft = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/():;%&`'*#=[]\\\"" # we at this point assume default values are final values for engineSettings self._defaultSetting = {} self._defaultSetting['FIFE'] = { 'FullScreen': False, 'PychanDebug': False, 'ProfilingOn': False, 'SDLRemoveFakeAlpha': 0, 'GLCompressImages': False, 'GLUseFramebuffer': True, 'GLUseNPOT': True, 'RenderBackend': 'OpenGL', 'ScreenResolution': "1024x768", 'BitsPerPixel': 0, 'InitialVolume': 5.0, 'WindowTitle': "", 'WindowIcon': "", 'Font': "", 'FontGlyphs': glyphDft, 'DefaultFontSize': 12, 'Lighting': 0, 'ColorKeyEnabled': False, 'ColorKey': [255, 0, 255], 'VideoDriver': "", 'PlaySounds': True, 'LogToFile': 0, 'LogToPrompt': 0, 'UsePsyco': False, 'LogLevelFilter': [0], 'LogModules': ['controller', 'script'], 'FrameLimitEnabled': False, 'FrameLimit': 60, 'MouseSensitivity': 0.0, 'MouseAcceleration': False } # has the settings file been read self._readSettingsCompleted = {} # the global dictionary from which we will read after self._readSettingsCompleted is True self._settingsFromFile = {} # the logger needed to write in log file. It will be initialized in this file when self.getSettings() # method is called by logger self._logger = None #default settings self._resolutions = self._validSetting['FIFE']['ScreenResolution'] self._renderbackends = self._validSetting['FIFE']['RenderBackend'] self._lightingmodels = self._validSetting['FIFE']['Lighting'] #Used to stylize the options gui self._gui_style = "default" #Initialize the serializer if serializer: self._serializer = serializer else: self._serializer = SimpleXMLSerializer() self.initSerializer() # Get all modules and initialize reading of them from xml file as false self._allModules = self._serializer.getModuleName() # print("All Module Names:",self._allModules) for module in self._allModules: self._readSettingsCompleted[module] = False self._initDefaultSettingEntries() #self.setOneSetting('FIFE','Font','fonts/FreeSans.ttf',False) #print self.getSettingsFromFile('unknownhorizons') # set all Settings in either validSetting or defaultSetting def setAllSettings(self, module, settings, validSetting=True): if validSettings: self._validSetting[module] = settings else: self._defaultSetting[module] = settings # set an entry in the validSetting or defaultSetting dictionary def setOneSetting(self, module, name, value, validSetting=True): if validSetting: self._validSetting[module][name] = value else: self._defaultSetting[module][name] = value # get all the Settings(either validSetting or defaultSetting) def getAllSettings(self, module, validSetting=True): if validSetting: return self._validSetting[module] else: return self._defaultSetting[module] # get an entry from either validSetting or defaultSetting def getOneSetting(self, module, name, validSetting=True): if validSetting: return self._validSetting[module][name] else: return self._defaultSetting[module][name] # sets valid resolution options in the settings->Resolution def setValidResolutions(self, options): if options: self._resolutions = options self.createAndAddEntry(FIFE_MODULE, "ScreenResolution", "screen_resolution", initialdata=self._resolutions, requiresrestart=True) def initSerializer(self): self._serializer.load(os.path.join(self._appdata, self._settings_file)) def _initDefaultSettingEntries(self): """Initializes the default fife setting entries. Not to be called from outside this class.""" self.createAndAddEntry(FIFE_MODULE, "PlaySounds", "enable_sound", requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "FullScreen", "enable_fullscreen", requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "ScreenResolution", "screen_resolution", initialdata=self._resolutions, requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "RenderBackend", "render_backend", initialdata=self._renderbackends, requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "Lighting", "lighting_model", initialdata=self._lightingmodels, requiresrestart=True) def createAndAddEntry(self, module, name, widgetname, applyfunction=None, initialdata=None, requiresrestart=False): """" @param module: The Setting module this Entry belongs to @type module: C{String} @param name: The Setting's name @type name: C{String} @param widgetname: The name of the widget that is used to change this setting @type widgetname: C{String} @param applyfunction: function that makes the changes when the Setting is saved @type applyfunction: C{function} @param initialdata: If the widget supports the setInitialData() function this can be used to set the initial data @type initialdata: C{String} or C{Boolean} @param requiresrestart: Whether or not the changing of this setting requires a restart @type requiresrestart: C{Boolean} """ entry = SettingEntry(module, name, widgetname, applyfunction, initialdata, requiresrestart) self.addEntry(entry) def addEntry(self, entry): """Adds a new C{SettingEntry} to the Settting @param entry: A new SettingEntry that is to be added @type entry: C{SettingEntry} """ if entry.module not in self._entries: self._entries[entry.module] = {} self._entries[entry.module][entry.name] = entry """ # Make sure the new entry is available if self.get(entry.module, entry.name) is None: print "Updating", self._settings_file, "to the default, it is missing the entry:"\ , entry.name ,"for module", entry.module #self.setDefaults() if self.get(entry.module, entry.name) is None: print "WARNING:", entry.module, ":", entry.name, "still not found!" """ def saveSettings(self, filename=""): """ Writes the settings to the settings file @param filename: Specifies the file to save the settings to. If it is not specified the original settings file is used. @type filename: C{string} """ if self._serializer: if filename == "": self._serializer.save( os.path.join(self._appdata, self._settings_file)) else: self._serializer.save(filename) # get all the settings of a module name module def getSettingsFromFile(self, module, logger=None): if self._serializer: self._logger = logger modules = self._serializer.getModuleName() self._settingsFromFile[module] = self._serializer.getAllSettings( module) if self._logger: self._logger.log_log("Loading Settings From File ...") if self._settingsFromFile[module] is not None: self._readSettingsCompleted[module] = True # we need validation for the module FIFE only if module is not "FIFE": return self._settingsFromFile[module] """ Now we have all the settings we needed. We have to validate the settings. Applicable for module FIFE only """ for name in self._settingsFromFile[module]: # if the setting name is known, so that it is # both in self._settingsFromFile and validSetting if name in self._validSetting[module]: e_value = self._settingsFromFile[module][name] if name == "InitialVolume": if e_value >= self._validSetting[module][name][ 0] and e_value <= self._validSetting[module][ name][1]: self._settingsFromFile[module][name] = e_value else: if self._logger: self._logger.log_log( "InitalVolume must have a value between 0.0 and 10.0" ) elif name == "ColorKey": e_value = e_value.split(',') if int(e_value[0]) in range(0, 256) and int( e_value[1]) in range(0, 256) and int( e_value[2]) in range(0, 256): self._settingsFromFile[name] = [ int(e_value[0]), int(e_value[1]), int(e_value[2]) ] else: if self._logger: self._logger.log_log( "ColorKey values must be within 0 and 255. Setting to Default Value." ) elif name == "ScreenResolution": temp = e_value.split('x') if len(temp) == 2: self._settingsFromFile[module][name] = e_value else: if self._logger: self._logger.log_log( "Invalid Screen Resolution value. We expect two integer seperted by x" ) elif len(self._validSetting[module][name]) == 0: self._settingsFromFile[module][name] = e_value elif name == "LogModules": for checking_element in e_value: module_valid = False for base_element in self._validSetting[module][ name]: # checking_element is valid if checking_element == base_element: module_valid = True already_in = False for element in self._settingsFromFile[ module][name]: if element == checking_element: already_in = True if already_in == False: self._settingsFromFile[module][ name].append(checking_element) if module_valid == False: if self._logger: self._logger.log_log( checking_element + " is not a valid logModule") elif name == "FrameLimit": if e_value > 0: self._settingsFromFile[module][name] = e_value else: if self._logger: self._logger.log_log( e_value + " is not a valid FrameLimit setting. You must specify a positive integer!" ) elif name == "MouseSensitivity": self._settingsFromFile[module][name] = e_value elif name == "MouseAcceleration": self._settingsFromFile[module][name] = e_value else: if isinstance(self._settingsFromFile[module][name], list) == True or isinstance( self._settingsFromFile[module][name], dict) == True: valid = False for value in self._validSetting[module][name]: if value == e_value: valid = True self._settingsFromFile[module][ name] = e_value if valid == False: if self._logger: self._logger.log_log( "Setting " + name + " got invalid value. Setting to Default." ) else: self._settingsFromFile[module][name] = e_value # name is unknown else: if self._logger: self._logger.log_log("Setting " + name + " is unknown") if self._logger: self._logger.log_log("Settings Loaded ...") """ Upto this point we have validated all the settings that are in settings.xml file. But, what if a setting is valid and still it is not present in the settings.xml file. For this, we should give them the default Values that are in defaultSetting. """ for name in self._defaultSetting[module]: if name not in self._settingsFromFile[module]: self._settingsFromFile[module][ name] = self._defaultSetting[module][name] return self._settingsFromFile[module] else: return None def get(self, module, name, defaultValue=None): """ Gets the value of a specified setting @param module: Name of the module to get the setting from @param name: Setting name @param defaultValue: Specifies the default value to return if the setting is not found @type defaultValue: C{str} or C{unicode} or C{int} or C{float} or C{bool} or C{list} or C{dict} """ if self._serializer: if module is "FIFE": # check whether getAllSettings has been called already if self._readSettingsCompleted[module] is not True: value = self._serializer.get(module, name, defaultValue) if value is not None: return value else: if name in self._defaultSetting[module]: return self._defaultSetting[module][name] else: raise Exception( str(name) + ' is neither in settings.xml nor it has a default value set' ) else: if name in self._settingsFromFile[module]: return self._settingsFromFile[module][name] else: raise Exception( str(name) + ' is neither in settings.xml nor it has a default value set' ) else: return self._serializer.get(module, name, defaultValue) else: """ serializer not set, reading from default value """ if name in self._defaultSetting: return self._defaultSetting[module][name] else: raise Exception( str(name) + ' is neither in settings.xml nor it has a default value set' ) def set(self, module, name, value, extra_attrs={}): """ Sets a setting to specified value. @param module: Module where the setting should be set @param name: Name of setting @param value: Value to assign to setting @type value: C{str} or C{unicode} or C{int} or C{float} or C{bool} or C{list} or C{dict} @param extra_attrs: Extra attributes to be stored in the XML-file @type extra_attrs: C{dict} """ #update the setting cache if module in self._settingsFromFile: self._settingsFromFile[module][name] = value else: self._settingsFromFile[module] = {name: value} if self._serializer: self._serializer.set(module, name, value, extra_attrs) def setGuiStyle(self, style): """ Set a custom gui style used for the option dialog. @param style: Pychan style to be used @type style: C{string} """ self._gui_style = style def onOptionsPress(self): """ Opens the options dialog box. Usually you would bind this to a button. """ self.changesRequireRestart = False self.isSetToDefault = False if not self.OptionsDlg: self.loadSettingsDialog() self.fillWidgets() self.OptionsDlg.show() def loadSettingsDialog(self): """ Load up the settings xml and return the widget. """ self.OptionsDlg = self._loadWidget(self._settings_gui_xml) self.OptionsDlg.stylize(self._gui_style) self.OptionsDlg.mapEvents({ 'okButton': self.applySettings, 'cancelButton': self.OptionsDlg.hide, 'defaultButton': self.setDefaults }) return self.OptionsDlg def _loadWidget(self, dialog): """Loads a widget. Can load both files and pure xml strings""" if os.path.isfile(self._settings_gui_xml): return pychan.loadXML(dialog) else: return pychan.loadXML(StringIO(dialog)) def fillWidgets(self): for module in self._entries.itervalues(): for entry in module.itervalues(): widget = self.OptionsDlg.findChildByName( entry.settingwidgetname) """ little change to prevent crash from no settings in settings.xml file """ """ The checking of value for None is specially for the clients who use settings with different names under modules other than "FIFE" for which we have no default value to set. This will prevent the settings widget from crash """ value = self.get(entry.module, entry.name) if isinstance(entry.initialdata, list): try: value = entry.initialdata.index(value) except ValueError: raise ValueError("\"" + str(value) + "\" is not a valid value for " + entry.name + ". Valid options: " + str(entry.initialdata)) elif isinstance(entry.initialdata, dict): try: value = entry.initialdata.keys().index(value) except ValueError: raise ValueError("\"" + str(value) + "\" is not a valid value for " + entry.name + ". Valid options: " + str(entry.initialdata.keys())) entry.initializeWidget(widget, value) def applySettings(self): """ Writes the settings file. If a change requires a restart of the engine it notifies you with a small dialog box. """ for module in self._entries.itervalues(): for entry in module.itervalues(): widget = self.OptionsDlg.findChildByName( entry.settingwidgetname) data = widget.getData() # If the data is a list we need to get the correct selected data # from the list. This is needed for e.g. dropdowns or listboxs if isinstance(entry.initialdata, list): data = entry.initialdata[data] elif isinstance(entry.initialdata, dict): data = entry.initialdata.keys()[data] # only take action if something really changed if data != self.get(entry.module, entry.name): self.set(entry.module, entry.name, data) entry.onApply(data) if entry.requiresrestart: self.changesRequireRestart = True self.saveSettings() self.OptionsDlg.hide() if self.changesRequireRestart: self._showChangeRequireRestartDialog() def _showChangeRequireRestartDialog(self): """Shows a dialog that informes the user that a restart is required to perform the changes.""" RestartDlg = self._loadWidget(self._changes_gui_xml) RestartDlg.stylize(self._gui_style) RestartDlg.mapEvents({'closeButton': RestartDlg.hide}) RestartDlg.show() def setAvailableScreenResolutions(self, reslist): """ A list of valid default screen resolutions. This should be called once right after you instantiate Settings. Valid screen resolutions must be strings in the form of: WIDTHxHEIGHT Example: settings.setAvailableScreenResolutions(["800x600", "1024x768"]) """ self._resolutions = reslist def setDefaults(self): """ Overwrites the setting file with the default settings file. """ shutil.copyfile(self._default_settings_file, os.path.join(self._appdata, self._settings_file)) self.changesRequireRestart = True self.initSerializer() #On startup the settings dialog is not yet initialized. We dont #fill the widgets with data in that case. if self.OptionsDlg: self.fillWidgets() def _getEntries(self): return self._entries def _setEntries(self, entries): self._entries = entries def _getSerializer(self): return self._serializer entries = property(_getEntries, _setEntries) serializer = property(_getSerializer)
class QuestManager(Serializer): def __init__(self, gameplay): self._gameplay = gameplay self._questSettings = None self._quests = [] self._activeQuests = [] self._completedQuests = [] def serialize(self): pass def deserialize(self, valueDict): questFile = "maps/quests.xml" self._questSettings = SimpleXMLSerializer(questFile) for identifier in self._questSettings.get("QuestGivers", "list", []): for quest in self._questSettings.get(identifier, "questList", []): questDict = self._questSettings.get(identifier, quest, []) if questDict["type"] == 'RETURN_ITEM': questObj = ReturnItemQuest(identifier, quest, questDict["name"], questDict["desc"]) for ritem in self._questSettings.get(quest + "_items", "itemlist", []): itemDict = self._questSettings.get(quest + "_items", ritem, []) if itemDict["name"] == "GOLD_COINS": questObj.addRequiredGold(itemDict["value"]) else: questObj.addRequiredItem(ritem) else: questObj = Quest(identifier, quest, questDict["name"], questDict["desc"]) if questDict.has_key("quest_incomplete_dialog"): questObj._incompleteDialog = questDict["quest_incomplete_dialog"] if questDict.has_key("quest_complete_dialog"): questObj._completeDialog = questDict["quest_complete_dialog"] self._gameplay.questManager.addQuest(questObj) def reset(self): self._quests = [] self._activeQuests = [] self._completedQuests = [] def addQuest(self, quest): if self._quests.has_key(quest.ownerId): if not quest in self._quests[quest.ownerId]: self._quests[quest.ownerId].append(quest) else: self._quests[quest.ownerId] = [quest] def getQuest(self, questId): for owner in self._quests: for quest in self._quests[owner]: if quest.id == questId: return quest return None def getNextQuest(self, ownerId): if self._quests.has_key(ownerId): for quest in self._quests[ownerId]: if not quest in self._activeQuests and not quest in self._completedQuests: return quest return None def activateQuest(self, quest): if not quest in self._activeQuests: self._activeQuests.append(quest) def completeQuest(self, quest): if not quest in self._completedQuests: self._completedQuests.append(quest) if quest in self._activeQuests: self._activeQuests.remove(quest) def activateQuestById(self, questId): quest = self.getQuest(questId) if quest: self.activateQuest(quest) def completeQuestById(self, questId): quest = self.getQuest(questId) if quest: self.completeQuest(quest) def _getActiveQuests(self): return self._activeQuests def _getCompletedQuests(self): return self._completedQuests def _getAllQuests(self): return self._quests activeQuests = property(_getActiveQuests) completedQuests = property(_getCompletedQuests) quests = property(_getAllQuests)
class QuestManager(Serializer): def __init__(self, gamecontroller): self._gamecontroller = gamecontroller self._questsettings = None self._quests = {} self._activequests = [] self._completedquests = [] def serialize(self): pass def deserialize(self, valuedict=None): questfile = self._gamecontroller.settings.get("RPG", "QuestFile", "maps/quests.xml") self._questsettings = SimpleXMLSerializer(questfile) for identifier in self._questsettings.get("QuestGivers", "list", []): for quest in self._questsettings.get(identifier, "questlist", []): questdict = self._questsettings.get(identifier, quest, {}) if questdict['type'] == "RETURN_ITEM": questobj = ReturnItemQuest(identifier, quest, questdict['name'], questdict['desc']) for ritem in self._questsettings.get(quest+"_items", "itemlist", []): itemdict = self._questsettings.get(quest+"_items", ritem, {}) if itemdict["name"] == "GOLD_COINS": questobj.addRequiredGold(int(itemdict['value'])) else: questobj.addRequiredItem(ritem) else: questobj = Quest(identifier, quest, questdict['name'], questdict['desc']) if questdict.has_key("quest_incomplete_dialog"): questobj._incomplete_dialog = questdict['quest_incomplete_dialog'] if questdict.has_key("quest_complete_dialog"): questobj._complete_dialog = questdict['quest_complete_dialog'] self._gamecontroller.questmanager.addQuest(questobj) def reset(self): self._quests = {} self._activequests = [] self._completedquests = [] def addQuest(self, quest): if self._quests.has_key(quest.ownerid): if not quest in self._quests[quest.ownerid]: self._quests[quest.ownerid].append(quest) else: self._quests[quest.ownerid] = [quest] def getQuest(self, questid): for owner in self._quests: for quest in self._quests[owner]: if quest.id == questid: return quest return None def getNextQuest(self, ownerid): if self._quests.has_key(ownerid): for quest in self._quests[ownerid]: if not quest in self._activequests and not quest in self._completedquests: return quest return None def activateQuest(self, quest): """ Adds the quest to the "active quests" list. Note that this does NOT affect the quest in any way. It's just a way of keeping track of which quests the player has accepted. """ if not quest in self._activequests: self._activequests.append(quest) def completeQuest(self, quest): """ Marks the quest as completed. Note that this does NOT modify the quest in any way. This is just a way to keep track of completed quests. """ if not quest in self._completedquests: self._completedquests.append(quest) if quest in self._activequests: self._activequests.remove(quest) def activateQuestById(self, questid): quest = self.getQuest(questid) if quest: self.activateQuest(quest) def completeQuestById(self, questid): quest = self.getQuest(questid) if quest: self.completeQuest(quest) def _getActiveQuests(self): return self._activequests def _getCompletedQuests(self): return self._completedquests def _getAllQuests(self): return self._quests activequests = property(_getActiveQuests) completedquests = property(_getCompletedQuests) quests = property(_getAllQuests)
class Setting(object): """ This class manages loading and saving of game settings. Usage:: from fife.extensions.fife_settings import Setting settings = Setting(app_name="myapp") screen_width = settings.get("FIFE", "ScreenWidth", 1024) screen_height = settings.get("FIFE", "ScreenHeight", 768) """ def __init__(self, app_name="", settings_file="", default_settings_file= "settings-dist.xml", settings_gui_xml="", changes_gui_xml="", copy_dist=True, serializer=None): """ Initializes the Setting object. @param app_name: The applications name. If this parameter is provided alone it will try to read the settings file from the users home directory. In windows this will be something like: C:\Documents and Settings\user\Application Data\fife @type app_name: C{string} @param settings_file: The name of the settings file. If this parameter is provided it will look for the setting file as you specify it, first looking in the working directory. It will NOT look in the users home directory. @type settings_file: C{string} @param default_settings_file: The name of the default settings file. If the settings_file does not exist this file will be copied into the place of the settings_file. This file must exist in the root directory of your project! @type default_settings_file: C{string} @param settings_gui_xml: If you specify this parameter you can customize the look of the settings dialog box. @param copy_dist: Copies the default settings file to the settings_file location. If this is False it will create a new empty setting file. @param serializer: Overrides the default XML serializer @type serializer: C{SimpleSerializer} """ self._app_name = app_name self._settings_file = settings_file self._default_settings_file = default_settings_file self._settings_gui_xml = settings_gui_xml self._changes_gui_xml = changes_gui_xml self.OptionsDlg = None # Holds SettingEntries self._entries = {} if self._settings_file == "": self._settings_file = "settings.xml" self._appdata = getUserDataDirectory("fife", self._app_name) else: self._appdata = os.path.dirname(self._settings_file) self._settings_file = os.path.basename(self._settings_file) if self._settings_gui_xml == "": self._settings_gui_xml = SETTINGS_GUI_XML if self._changes_gui_xml == "": self._changes_gui_xml = CHANGES_REQUIRE_RESTART if not os.path.exists(os.path.join(self._appdata, self._settings_file)): if os.path.exists(self._default_settings_file) and copy_dist: shutil.copyfile(self._default_settings_file, os.path.join(self._appdata, self._settings_file)) #default settings self._resolutions = ['640x480', '800x600', '1024x768', '1280x800', '1440x900'] self._renderbackends = ['OpenGL', 'SDL'] self._lightingmodels = [0, 1, 2] #Used to stylize the options gui self._gui_style = "default" #Initialize the serializer if serializer: self._serializer = serializer else: self._serializer = SimpleXMLSerializer() self.initSerializer() self._initDefaultSettingEntries() def initSerializer(self): self._serializer.load(os.path.join(self._appdata, self._settings_file)) def _initDefaultSettingEntries(self): """Initializes the default fife setting entries. Not to be called from outside this class.""" self.createAndAddEntry(FIFE_MODULE, "PlaySounds", "enable_sound", requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "FullScreen", "enable_fullscreen", requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "ScreenResolution", "screen_resolution", initialdata = self._resolutions, requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "RenderBackend", "render_backend", initialdata = self._renderbackends, requiresrestart=True) self.createAndAddEntry(FIFE_MODULE, "Lighting", "lighting_model", initialdata = self._lightingmodels, requiresrestart=True) def createAndAddEntry(self, module, name, widgetname, applyfunction=None, initialdata=None, requiresrestart=False): """" @param module: The Setting module this Entry belongs to @type module: C{String} @param name: The Setting's name @type name: C{String} @param widgetname: The name of the widget that is used to change this setting @type widgetname: C{String} @param applyfunction: function that makes the changes when the Setting is saved @type applyfunction: C{function} @param initialdata: If the widget supports the setInitialData() function this can be used to set the initial data @type initialdata: C{String} or C{Boolean} @param requiresrestart: Whether or not the changing of this setting requires a restart @type requiresrestart: C{Boolean} """ entry = SettingEntry(module, name, widgetname, applyfunction, initialdata, requiresrestart) self.addEntry(entry) def addEntry(self, entry): """Adds a new C{SettingEntry} to the Settting @param entry: A new SettingEntry that is to be added @type entry: C{SettingEntry} """ if entry.module not in self._entries: self._entries[entry.module] = {} self._entries[entry.module][entry.name] = entry # Make sure the new entry is available if self.get(entry.module, entry.name) is None: print "Updating", self._settings_file, "to the default, it is missing the entry:"\ , entry.name ,"for module", entry.module self.setDefaults() if self.get(entry.module, entry.name) is None: print "WARNING:", entry.module, ":", entry.name, "still not found!" def saveSettings(self, filename=""): """ Writes the settings to the settings file @param filename: Specifies the file to save the settings to. If it is not specified the original settings file is used. @type filename: C{string} """ if self._serializer: if filename == "": self._serializer.save(os.path.join(self._appdata, self._settings_file)) else: self._serializer.save(filename) def get(self, module, name, defaultValue=None): """ Gets the value of a specified setting @param module: Name of the module to get the setting from @param name: Setting name @param defaultValue: Specifies the default value to return if the setting is not found @type defaultValue: C{str} or C{unicode} or C{int} or C{float} or C{bool} or C{list} or C{dict} """ if self._serializer: return self._serializer.get(module, name, defaultValue) else: return None def set(self, module, name, value, extra_attrs={}): """ Sets a setting to specified value. @param module: Module where the setting should be set @param name: Name of setting @param value: Value to assign to setting @type value: C{str} or C{unicode} or C{int} or C{float} or C{bool} or C{list} or C{dict} @param extra_attrs: Extra attributes to be stored in the XML-file @type extra_attrs: C{dict} """ if self._serializer: self._serializer.set(module, name, value, extra_attrs) def setGuiStyle(self, style): """ Set a custom gui style used for the option dialog. @param style: Pychan style to be used @type style: C{string} """ self._gui_style = style def onOptionsPress(self): """ Opens the options dialog box. Usually you would bind this to a button. """ self.changesRequireRestart = False self.isSetToDefault = False if not self.OptionsDlg: self.loadSettingsDialog() self.fillWidgets() self.OptionsDlg.show() def loadSettingsDialog(self): """ Load up the settings xml and return the widget. """ self.OptionsDlg = self._loadWidget(self._settings_gui_xml) self.OptionsDlg.stylize(self._gui_style) self.OptionsDlg.mapEvents({ 'okButton' : self.applySettings, 'cancelButton' : self.OptionsDlg.hide, 'defaultButton' : self.setDefaults }) return self.OptionsDlg def _loadWidget(self, dialog): """Loads a widget. Can load both files and pure xml strings""" if os.path.isfile(self._settings_gui_xml): return pychan.loadXML(dialog) else: return pychan.loadXML(StringIO(dialog)) def fillWidgets(self): for module in self._entries.itervalues(): for entry in module.itervalues(): widget = self.OptionsDlg.findChildByName(entry.settingwidgetname) value = self.get(entry.module, entry.name) if type(entry.initialdata) is list: try: value = entry.initialdata.index(value) except ValueError: raise ValueError("\"" + value + "\" is not a valid value for " + entry.name + ". Valid options: " + str(entry.initialdata)) entry.initializeWidget(widget, value) def applySettings(self): """ Writes the settings file. If a change requires a restart of the engine it notifies you with a small dialog box. """ for module in self._entries.itervalues(): for entry in module.itervalues(): widget = self.OptionsDlg.findChildByName(entry.settingwidgetname) data = widget.getData() # If the data is a list we need to get the correct selected data # from the list. This is needed for e.g. dropdowns or listboxs if type(entry.initialdata) is list: data = entry.initialdata[data] # only take action if something really changed if data != self.get(entry.module, entry.name): self.set(entry.module, entry.name, data) entry.onApply(data) if entry.requiresrestart: self.changesRequireRestart = True self.saveSettings() self.OptionsDlg.hide() if self.changesRequireRestart: self._showChangeRequireRestartDialog() def _showChangeRequireRestartDialog(self): """Shows a dialog that informes the user that a restart is required to perform the changes.""" RestartDlg = self._loadWidget(self._changes_gui_xml) RestartDlg.stylize(self._gui_style) RestartDlg.mapEvents({ 'closeButton' : RestartDlg.hide }) RestartDlg.show() def setAvailableScreenResolutions(self, reslist): """ A list of valid default screen resolutions. This should be called once right after you instantiate Settings. Valid screen resolutions must be strings in the form of: WIDTHxHEIGHT Example: settings.setAvailableScreenResolutions(["800x600", "1024x768"]) """ self._resolutions = reslist def setDefaults(self): """ Overwrites the setting file with the default settings file. """ shutil.copyfile(self._default_settings_file, os.path.join(self._appdata, self._settings_file)) self.changesRequireRestart = True self.initSerializer() #update all widgets with the new data self.fillWidgets() def _getEntries(self): return self._entries def _setEntries(self, entries): self._entries = entries def _getSerializer(self): return self._serializer entries = property(_getEntries, _setEntries) serializer = property(_getSerializer)
def _setup_settings(self, check_file_version=True): _user_config_file = os.path.join( os.getcwd(), PATHS.USER_CONFIG_FILE ) if check_file_version and os.path.exists(_user_config_file): # check if user settings file is the current one # NOTE: SimpleXMLSerializer can't handle relative paths, it fails silently # (although the doc states otherwise) - thus translate paths to absolute ones user_config_parser = SimpleXMLSerializer( _user_config_file ) user_settings_version = user_config_parser.get("meta", "SettingsVersion", -1) _template_config_file = os.path.join( os.getcwd(), PATHS.CONFIG_TEMPLATE_FILE ) template_config_parser = SimpleXMLSerializer( _template_config_file ) template_settings_version = template_config_parser.get("meta", "SettingsVersion") if template_settings_version > user_settings_version: # we have to update the file print 'Discovered old settings file, auto-upgrading: %s -> %s' % \ (user_settings_version, template_settings_version) # create settings so we have a list of all settings self._setup_settings(check_file_version=False) # save settings here entries = [] # need safe default value default_value = object() def update_value(modulename, entryname): # retrieve values from loaded settings file try: value = self._setting.get(modulename, entryname, default_value) except UnicodeEncodeError: # this can happen when unicode data is saved as str value = "default" if value is not default_value: entries.append( (modulename, entryname, value ) ) # collect values from known settings and unreferenced settings for modulename, module in self._setting.entries.iteritems(): for entryname in module.iterkeys(): update_value(modulename, entryname) for modulename, entry_list in self.UNREFERENCED_SETTINGS.iteritems(): for entryname in entry_list: update_value(modulename, entryname) # patch old values if user_settings_version <= 10: old_entries = entries entries = [] for i in old_entries: if i[0] == UH_MODULE and i[1] == "Language": entries.append( (i[0], i[1], LANGUAGENAMES.get_by_value(i[2])) ) else: entries.append(i) # write actual new file shutil.copy( PATHS.CONFIG_TEMPLATE_FILE, PATHS.USER_CONFIG_FILE ) user_config_parser = SimpleXMLSerializer( _user_config_file ) for modulename, entryname, value in entries: user_config_parser.set(modulename, entryname, value) user_config_parser.save() self._setting = SettingsDialog(app_name=UH_MODULE, settings_file=PATHS.USER_CONFIG_FILE, settings_gui_xml="settings.xml", changes_gui_xml="requirerestart.xml", default_settings_file=PATHS.CONFIG_TEMPLATE_FILE) self._setting_handler.add_settings()
class World(EventListenerBase): """ World Class Sets up the map, gui, soundmanager and calls the Actor class to deal with actors Keyword Arguments EventListenerBase - World inherits from EventListenerBase """ def __init__(self, app, engine, setting): """ __init__ Function Starts an instance of the World class Keyword Arguments app - A pointer to the main application engine - A pointer to fife.engine setting - A pointer to a fife settings XML file """ super(World, self).__init__(engine, regKeys=True, regCmd=False, regMouse=True) # Throw values into their variables self._applictaion = app self._engine = engine self._setting = setting self._timemanager = engine.getTimeManager() self._eventmanager = engine.getEventManager() self._model = engine.getModel() self._filename = '' self._keystate = { 'UP': False, 'DOWN': False, 'LEFT': False, 'RIGHT': False, 'CTRL': False, 'SPACE': False, 'Q': False, 'E': False,} self._cameras = {} self._npcs = {} self._npclist = None self._pump_ctr = 0 self._map = None self._scene = None self._paused = True self._pausedtime = 0 self._starttime = 0 self._gamestate = 'NONE' self._quit = False self._player = None self._eventtracker = None self._objects = {} self._contextmenu = contextmenu.ContextMenu('rightclickmenu', self) self._mouseMoved = False # Start pychan pychan.init(self._engine) # Set all GUI types to empty self._hud = None self._mainmenu = None self._pausemenu = None self._loadingmenu = None self._settingsmenu = None self._aboutmenu = None # Start the sound manager self._soundmanager = SoundManager(self._engine) self._sounds = musicmanager.MusicManager(self._engine, self._soundmanager, self._timemanager) def _loadGui(self, type, guifile, imports): """ _loadGui Function Loads a pychan GUI file to one of the four GUI slots, then loads a python package to run to initilise the gui Keyword Arguments type - String, the type of GUI being loaded guifile - String, name of the pychan file being loaded imports - Boolean """ if type == 'MAIN': self._mainmenu = menuhandler.MenuHandler(guifile, self) elif type == 'HUD': self._hud = hudhandler.HUDHandler(guifile, self) elif type == 'SETTINGS': self._settingsmenu = settingshandler.SettingsHandler(guifile, self) elif type == 'ABOUT': self._aboutmenu = abouthandler.AboutHandler(guifile, self) elif type == 'PAUSE': self._pause = pychan.loadXML('gui/' + guifile + '.xml') if imports: guiinit = __import__('scripts.gui.' + guifile) guiinit.run() elif type == 'LOAD': self._loadingmenu = pychan.loadXML('gui/' + guifile + '.xml') if imports: guiinit = __import__('scripts.gui.' + guifile) guiinit.run() else: pass def _hideAllGuis(self): """ _hideAllGuis Function Hides any active GUI elements """ if self._hud != None: self._hud.hide() if self._mainmenu != None: self._mainmenu.hide() if self._pausemenu != None: self._pausemenu.hide() if self._loadingmenu != None: self._loadingmenu.hide() if self._settingsmenu != None: self._settingsmenu.hide() if self._aboutmenu != None: self._aboutmenu.hide() def _loadLevelMapCallback(self, action, percentdone): """ _loadLevelMapCallback Function Acts as a callback for level loading. Keyword Arguments action - String, what has just been loaded percentdone - Float, percentage loaded """ # You have to pump the engine, else it doesn't render anything # until the map has loaded self._engine.pump() # If it's loaded, hide the loading screen and load the HUD if percentdone == 1: self._hideAllGuis() # Otherwise set the loading screens percentage label else: loaded = self._loadingmenu.findChild(name="loading") loaded.text = str(math.floor(percentdone * 100)) + u'% Loaded' def _loadMenuMapCallback(self, action, percentdone): """ _loadMenuMapCallback Function Acts as a callback for level loading. Keyword Arguments action - String, what has just been loaded percentdone - Float, percentage loaded """ # You have to pump the engine, else it doesn't render anything # until the map has loaded self._engine.pump() # If it's loaded, hide the loading screen and load the menu if percentdone == 1: self._hideAllGuis() if self._mainmenu != None: self._mainmenu.show() # Otherwise set the loading screens percentage label else: loaded = self._loadingmenu.findChild(name="loading") loaded.text = str(math.floor(percentdone * 100)) + u'% Loaded' def _loadMap(self, filename, purpose, port=False, location=None, direction=None): """ _loadMap Function Deletes the old map and loads a new one. Also initilises cameras. Keyword Arguments filename - String, path to the map file purpose - String, LEVEL or MENU """ self._model.deleteMap(self._map) self._map = None self._npcs = {} self._npclist = False self._mapsettings = SimpleXMLSerializer(filename=filename +".config") self._eventtracker = None if purpose == 'LEVEL': # Hide any active GUIs self._hideAllGuis() # Pump the engine to force it to move to a new frame self._engine.pump() # If the loading menu is loaded, show it if self._loadingmenu != None: self._loadingmenu.show() loadwindow = self._loadingmenu.findChild(name="loadwindow") autoposition.placeWidget(loadwindow, 'automatic') # Load the map self._map = loadMapFile(filename, self._engine, self._loadLevelMapCallback) elif purpose == 'MENU': # Hide any active GUIs self._hideAllGuis() # Pump the engine to force it to move to a new frame self._engine.pump() # If the loading menu is loaded, show it if self._loadingmenu != None: self._loadingmenu.show() loadwindow = self._loadingmenu.findChild(name="loadwindow") autoposition.placeWidget(loadwindow, 'automatic') # Load the map self._map = loadMapFile(filename, self._engine, self._loadMenuMapCallback) # Start (or clear) the camera array self._cameras = {} # For each camera in the map for cam in self._map.getCameras(): # Get the camera ID camera_id = cam.getId() # Add the camera with that ID to the array self._cameras[camera_id] = cam # Reset the camera cam.resetRenderers() if purpose == 'LEVEL': # Start the player character self._startPlayerActor() if location != None: self._player._agent.setLocation(location) if direction != None: self._player._agent.setFacingLocation(direction) if self._hud != None: self._hud.show() self._loadLevelMapCallback("", 0.775) # Start the floating text renderer renderer = fife.FloatingTextRenderer.getInstance(self._cameras['main']) textfont = self._engine.getGuiManager().createFont('fonts/rpgfont.png', 0, str(self._setting.get("FIFE", "FontGlyphs"))) renderer.changeDefaultFont(textfont) renderer.setDefaultBackground(0,0,0,0) renderer.setDefaultBorder(0,0,0,0) renderer.activateAllLayers(self._map) renderer.setEnabled(True) if purpose == 'LEVEL': self._loadLevelMapCallback("", 0.8) else: self._loadMenuMapCallback("", 0.8) if self._mapsettings.get("map", "usewaypoints", False): self._waypoints = self._mapsettings._deserializeList(self._mapsettings.get("map", "waypoints", "")) else: self._waypoints = None if purpose == 'LEVEL': self._loadLevelMapCallback("", 0.825) else: self._loadMenuMapCallback("", 0.825) if self._mapsettings.get("map", "useobjects", False): self._objects = objectmanager.ObjectManager(self) objlist = self._mapsettings._deserializeList(self._mapsettings.get("map", "objectlist", False)) for file in objlist: self._objects._loadObjects(file) if purpose == 'LEVEL': self._loadLevelMapCallback("", 0.85) else: self._loadMenuMapCallback("", 0.85) if self._mapsettings.get("map", "dynamicnpcs", False): self._npclist = self._mapsettings._deserializeDict(self._mapsettings.get("map", "npclist", False)) if self._npclist != False: for id, name in self._npclist.iteritems(): self._npcs[name] = npc.NPC(self._setting, self._model, id, self._map.getLayer('player'), self, True, name) if purpose == 'LEVEL': self._loadLevelMapCallback("", 0.9) else: self._loadMenuMapCallback("", 0.9) self._eventtracker = eventtracker.EventTracker(self._engine, self._model, self._sounds, self) if self._mapsettings.get("map", "useevents", False): eventlist = self._mapsettings._deserializeList(self._mapsettings.get("map", "eventslist", "")) for file in eventlist: self._eventtracker._addEvent(file) if purpose == 'LEVEL': self._loadLevelMapCallback("", 0.95) else: self._loadMenuMapCallback("", 0.95) self._drift = {} self._drift = self._mapsettings._deserializeDict(self._mapsettings.get("map", "drift", "use : False")) if self._drift["use"] == "True": self._drift["use"] = True self._drift["x"] = float(self._drift["x"]) self._drift["y"] = float(self._drift["y"]) start = self._drift["start"].partition(",") loc = fife.Location(self._map.getLayer('player')) loc.setExactLayerCoordinates(fife.ExactModelCoordinate(float(start[0]), float(start[2]))) self._cameras['main'].setLocation(loc) else: self._drift["use"] = False self._gamestate = purpose def _getLocationAt(self, clickpoint, layer): """ Query the main camera for the Map location (on the agent layer) that a screen point refers to. """ target_mapcoord = self._cameras['main'].toMapCoordinates(clickpoint, False) target_mapcoord.z = 0 location = fife.Location(layer) location.setMapCoordinates(target_mapcoord) return location def _getInstancesAt(self, clickpoint, layer): """ Query the main camera for instances on a given layer. """ return self._cameras['main'].getMatchingInstances(clickpoint, layer) def mousePressed(self, evt): if evt.isConsumedByWidgets() or self._gamestate != 'LEVEL': return clickpoint = fife.ScreenPoint(evt.getX(), evt.getY()) playerinstance = self._getInstancesAt(clickpoint, self._map.getLayer('player')) playerinstance = playerinstance + self._getInstancesAt(clickpoint, self._map.getLayer('waypoints')) if (evt.getButton() == fife.MouseEvent.LEFT): self._player.run(self._getLocationAt(clickpoint, self._map.getLayer('player'))) self._contextmenu._hide() elif (evt.getButton() == fife.MouseEvent.RIGHT): self._contextmenu._show(playerinstance, clickpoint, self) evt.consume() def mouseMoved(self, evt, ext=False, cursor=None): self._mouseMoved = True if self._map == None or self._gamestate != 'LEVEL': return renderer = fife.InstanceRenderer.getInstance(self._cameras['main']) renderer.removeAllOutlines() if ext: pt = fife.ScreenPoint(cursor.getX(), cursor.getY()) else: pt = fife.ScreenPoint(evt.getX(), evt.getY()) instances = self._getInstancesAt(pt, self._map.getLayer('player')) instances = instances + self._getInstancesAt(pt, self._map.getLayer('waypoints')) for i in instances: for name, object in self._objects._objects.iteritems(): if i.getId() == name: renderer.addOutlined(i, random.randint(20,255), random.randint(20,255), random.randint(20,255), 1) for name, object in self._npcs.iteritems(): if i.getId() == object._agentName: renderer.addOutlined(i, random.randint(20,255), random.randint(20,255), random.randint(20,255), 1) def _keyPressed(self, evt): keyval = evt.getKey().getValue() keystr = evt.getKey().getAsString().lower() def _startPlayerActor(self): self._player = Player(self._setting, self._model, "actor-pc", self._map.getLayer('player')) self._cameras['main'].setLocation(self._player._agent.getLocation()) self._cameras['main'].attach(self._map.getLayer('player').getInstance("actor-pc")) if self._cameras['main'].getAttached() == None: def cameraDrift(self): if self._drift["use"]: oldloc = self._cameras['main'].getLocation().getExactLayerCoordinates() border = self._drift["end"].partition(",") if oldloc.x < float(border[0]): self._drift["x"] = (self._drift["x"] + random.randint(-1, 1) * 0.025) * -1 if oldloc.y < float(border[2]): self._drift["y"] = (self._drift["y"] + random.randint(-1, 1) * 0.025) * -1 border2 = self._drift["start"].partition(",") if oldloc.x > float(border2[0]): self._drift["x"] = (self._drift["x"] + random.randint(-1, 1) * 0.025) * -1 if oldloc.y > float(border2[2]): self._drift["y"] = (self._drift["y"] + random.randint(-1, 1) * 0.025) * -1 delta = self._timemanager.getTimeDelta() / 100.0 loc = fife.Location(self._map.getLayer('player')) deltax = round(oldloc.x + self._drift["x"] * delta, 2) deltay = round(oldloc.y + self._drift["y"] * delta, 2) loc.setExactLayerCoordinates(fife.ExactModelCoordinate(deltax, deltay)) self._cameras['main'].setLocation(loc)