def _Build_Engine_Objects(): ''' Returns a list of Edit_Objects for 'assets/props/Engines'. Meant for calling from the Live_Editor. ''' File_System.Load_Files('*assets/props/Engines/*.xml') game_files = File_System.Get_Asset_Files_By_Class('macros', 'engine') return Create_Objects_From_Asset_Files(game_files, engine_item_macros)
def Color_Text(*page_t_colors): ''' Applies coloring to selected text nodes, for all versions of the text found in the current X4 files. Note: these colors will override any prior color in effect, and will return to standard text color at the end of the colored text node. * page_t_colors - One or more groups of (page id, text id, color code) to apply. Example: <code> Color_Text( (20005,1001,'B'), (20005,3012,'C'), (20005,6046,'Y'), ) </code> ''' # TODO: add a list of support colors to the doc. # TODO: verify input. # Load all text files. game_files = File_System.Load_Files('t/*.xml') # Loop over them. for game_file in game_files: xml_root = game_file.Get_Root() # Loop over the colorings. change_found = False for page, text, color in page_t_colors: # Look up the node. node = xml_root.find('./page[@id="{}"]/t[@id="{}"]'.format( page, text)) # Skip on missing node. if node == None: continue # Prefix and suffix it with color. node.text = r'\033{}{}\033X'.format(color, node.text) change_found = True # TODO: delay this until after all loops complete, in # case a later one has an error, to safely cancel the # whole transform. if change_found: game_file.Update_Root(xml_root) return # TODO: develop this further to support text searching, coloring only # selected words, maybe; that wouldn't be as robust across languages # though.
def _Build_Bullet_Objects(): ''' Returns a list of Edit_Objects for all found bullets. Meant for calling from the Live_Editor. ''' # Make sure engines are loaded for the missiles. Live_Editor.Get_Category_Objects('engines') # Look up bullet files. # These can be in two locations. File_System.Load_Files('*assets/props/WeaponSystems/*.xml') File_System.Load_Files('*assets/fx/weaponFx/*.xml') # Split out proper bullets from missiles and similar. bullet_game_files = File_System.Get_Asset_Files_By_Class( 'macros', 'bullet') missile_game_files = File_System.Get_Asset_Files_By_Class( 'macros', 'missile', 'bomb', 'mine', 'countermeasure') objects = [] objects += Create_Objects_From_Asset_Files(bullet_game_files, bullet_item_macros) objects += Create_Objects_From_Asset_Files(missile_game_files, missile_item_macros) return objects
def _Build_DockingBay_Objects(): File_System.Load_Files('*assets/props/SurfaceElements/*.xml') game_files = File_System.Get_Asset_Files_By_Class('macros', 'dockingbay') return Create_Objects_From_Asset_Files(game_files, dockingbay_item_macros)
def _Build_Scanner_Objects(): File_System.Load_Files('*assets/props/SurfaceElements/*.xml') game_files = File_System.Get_Asset_Files_By_Class('macros', 'scanner') return Create_Objects_From_Asset_Files(game_files, scanner_item_macros)
def Adjust_Mission_Reward_Mod_Chance(new_chance=2, ): ''' Adjusts generic mission chance to reward a mod instead of credits. The vanilla chance is 2% for a mod, 98% for credits. Pending update for x4 3.0+. * mod_chance - Int, the new percent chance of rewarding a mod. - Should be between 0 and 100. ''' ''' Many generic missions repeat this bit of code: <do_any> <do_if value="not $RewardCr" weight="98"> ... </do_if> <do_if value="not $RewardObj" weight="2"> ... </do_if> </do_any> Can hunt down the appropriate nodes to make the edit. Update: X4 3.0 adjusts all of the missions to have a seminar reward as well, and they vary in chances (90/2/8, 91/2/7, etc.). ''' # Validate the mod_chance range. mod_chance = int(new_chance) if mod_chance < 0: mod_chance = 0 elif mod_chance > 100: mod_chance = 100 # Want the various generic mission scripts. # These all are prefixed with GM_ game_files = File_System.Load_Files('md/GM_*') for game_file in game_files: xml_root = game_file.Get_Root() # Find the parent reward node. reward_nodes = xml_root.xpath('//do_if[@value="$GenerateReward"]') if len(reward_nodes) != 1: continue # Pick out the two nodes of interest. high_nodes = reward_nodes[0].xpath( 'do_any/do_if[@value="not $RewardCr"][@weight="98"]') low_nodes = reward_nodes[0].xpath( 'do_any/do_if[@value="not $RewardObj"][@weight="2"]') # 1 of each should have been found. if len(high_nodes) != 1 or len(low_nodes) != 1: continue # Make the edits. high_nodes[0].set('weight', str(100 - mod_chance)) low_nodes[0].set('weight', str(mod_chance)) game_file.Update_Root(xml_root) return