import os import csv from io import StringIO import re import shutil g_ai_cfg_dict = [] # function: read_text_file def read_text_file(file_path, read_mode='r'): """ 兼容 UTF-8 和 GBK 编码的文件读取函数 :param file_path: 文件路径 :param read_mode: 读取模式(默认 'r',文本模式) :return: 文件内容(字符串) """ # 先尝试 UTF-8 编码 try: with open(file_path, read_mode, encoding='utf-8-sig') as f: return f.read() except UnicodeDecodeError: # UTF-8 失败,尝试 GBK 编码 try: with open(file_path, read_mode, encoding='gbk') as f: return f.read() except UnicodeDecodeError: # 两种编码都失败,抛出异常 raise Exception(f"文件 {file_path} 不支持 UTF-8 和 GBK 编码") # function: parse_csv_to_dict def parse_csv_to_dict(csv_str): """将CSV字符串解析为字典列表""" string_io = StringIO(csv_str) csv_reader = csv.DictReader(string_io) data = [] for row in csv_reader: if has_content(row) and is_row_empty(row) == False: data.append(dict(row)) # 转换为普通字典 return data def remove_first_line_find(text): """ 使用 find 方法找到第一个换行符并切片 """ first_newline = text.find('\n') if first_newline == -1: return "" # 没有换行符,说明只有一行 return text[first_newline + 1:] # function: parse_csv_to_dict2 def parse_csv_to_dict2(csv_str): """将CSV字符串解析为字典列表""" csv_str = remove_first_line_find(csv_str) string_io = StringIO(csv_str) csv_reader = csv.DictReader(string_io) data = [] idx = 0 for row in csv_reader: if idx > 0 and has_content(row) and is_row_empty(row) == False: data.append(dict(row)) # 转换为普通字典 idx = idx + 1 return data def has_content(s): return s is not None and len(s) > 0 def is_row_empty(row): is_empty = True for key, value in row.items(): if value != '': is_empty = False break return is_empty # function: calc_story_end_idx def calc_story_range_list(csv_data): story_ranges = [] for i, item_data in enumerate(csv_data): if has_content(item_data['关卡']): story_ranges.append(i) story_ranges.append(len(csv_data)) story_range_list = [] for i in range(len(story_ranges)-1): story_range_list.append({'start': story_ranges[i], 'end': story_ranges[i+1]}) return story_range_list # functino: make_story_data def make_story_data(csv_data, start_idx, end_idx): start_csv_line = csv_data[start_idx] story_type = start_csv_line['剧情分类'] story_data = { 'id': start_csv_line['ID'], 'map_level': start_csv_line['关卡'], 'task_title': start_csv_line['任务标题'], 'story_type': story_type, 'story_intro': [], #'B1_add_heart': start_csv_line['分支1好感度'], #'B1_reward': start_csv_line['分支1奖励'], 'B1_scripts': [], #'B2_add_heart': start_csv_line['分支2好感度'], #'B2_reward': start_csv_line['分支2奖励'], 'B2_scripts': [], #'B3_add_heart': start_csv_line['分支3好感度'], #'B3_reward': start_csv_line['分支3奖励'], 'B3_scripts': [], } story_intro = [] idx = 0 for i in range(start_idx, end_idx): csv_line = csv_data[i] if has_content(csv_line['聊天前要']): story_intro.append(csv_line['聊天前要']) # 分支1 story_data['B1_scripts'].append({'idx': idx, 'name': csv_line['分支1角色'], 'script': csv_line['分支1台词'], 'story_intro':csv_line['聊天前要']}) # if csv_line['分支1角色'] != '' and csv_line['分支1台词'] != '': # story_data['B1_scripts'].append({'idx': idx, 'name': csv_line['分支1角色'], 'script': csv_line['分支1台词']}) # 分支2 story_data['B2_scripts'].append({'idx': idx, 'name': csv_line['分支2角色'], 'script': csv_line['分支2台词'], 'story_intro':csv_line['聊天前要']}) # if csv_line['分支2角色'] != '' and csv_line['分支2台词'] != '': # story_data['B2_scripts'].append({'idx': idx, 'name': csv_line['分支2角色'], 'script': csv_line['分支2台词']}) # 分支3 story_data['B3_scripts'].append({'idx': idx, 'name': csv_line['分支3角色'], 'script': csv_line['分支3台词'], 'story_intro':csv_line['聊天前要']}) # if csv_line['分支3角色'] != '' and csv_line['分支3台词'] != '': # story_data['B3_scripts'].append({'idx': idx, 'name': csv_line['分支3角色'], 'script': csv_line['分支3台词']}) idx = idx + 1 story_data['story_intro'] = story_intro return story_data # functino: make_language_key g_language_strs = {} def make_language_key(idx, str): if str == '': return '' key = "ST%s"%(idx) if key in g_language_strs: print("ERR: in g_language_strs key %s:%s:%s exist!!!!"%(key,g_language_strs[key], str)) exit() if has_content(str): g_language_strs[key] = str return key def make_language_story_opt_key(idx, str): if str == '': return '' key = "SOPT%s"%(idx) if key in g_language_strs: print("ERR: in g_language_strs key %s:%s:%s exist!!!!"%(key,g_language_strs[key], str)) exit() if has_content(str): g_language_strs[key] = str return key def make_language_story_intro_key(idx, str): # if str == '': # return '' # key = "SINTRO%s"%(idx) # if key in g_language_strs: # print("ERR: in g_language_strs key %s:%s:%s exist!!!!"%(key,g_language_strs[key], str)) # exit() # if has_content(str): # g_language_strs[key] = str # return key return str def make_language_story_title_key(idx, str): if str == '': return '' key = "STITLE%s"%(idx) if key in g_language_strs: print("ERR: in g_language_strs key %s:%s:%s exist!!!!"%(key,g_language_strs[key], str)) exit() if has_content(str): g_language_strs[key] = str return key def make_language_key2(key, str): if str == '': return '' if has_content(str): g_language_strs[key] = str return key # functino: get_language_name_key # g_actor_info_dict = [ # {'StoryNpcId': 20000, 'NameKey': 'system', 'Name': '系统', 'Img': 'system', 'Head': 'PlayerHeads/player_head_1'}, # {'StoryNpcId': 20001, 'NameKey': 'player', 'Name': '玩家', 'Img': 'player', 'Head': 'PlayerHeads/player_head_1'}, # {'StoryNpcId': 20002, 'NameKey': 'actor_nvshen', 'Name': '女神', 'Img': 'HeroDraw/Npc_01', 'Head': 'PlayerHeads/player_head_nvshen'}, # {'StoryNpcId': 20003, 'NameKey': 'actor_weier', 'Name': '薇儿', 'Img': 'HeroDraw/Npc_02', 'Head': 'PlayerHeads/player_head_weier'}, # {'StoryNpcId': 20004, 'NameKey': 'actor_xifu', 'Name': '希芙', 'Img': 'HeroDraw/Npc_03', 'Head': 'PlayerHeads/player_head_xifu'}, # {'StoryNpcId': 20005, 'NameKey': 'actor_furuiya', 'Name': '芙蕾雅', 'Img': 'HeroDraw/Npc_04', 'Head': 'PlayerHeads/player_head_furuiya'}, # {'StoryNpcId': 20006, 'NameKey': 'actor_yideng', 'Name': '伊登', 'Img': 'HeroDraw/Npc_05', 'Head': 'PlayerHeads/player_head_yideng'}, # {'StoryNpcId': 20007, 'NameKey': 'actor_haila', 'Name': '海拉', 'Img': 'HeroDraw/Npc_06', 'Head': 'PlayerHeads/player_head_haila'}, # {'StoryNpcId': 20008, 'NameKey': 'actor_waerjili', 'Name': '瓦尔基里', 'Img': 'HeroDraw/Npc_07', 'Head': 'PlayerHeads/player_head_waerjili'} # ] g_actor_info_dict = [] def get_actor_info(name): for value in g_actor_info_dict: if value['Name'] == name: return value print("[get_actor_info] no find actor info name: " + name) return None g_StoryRewardCfg = [] # functino: create_story_cfg def create_story_cfg(story_id, task_title, story_type, story_npc_id, map_level, story_intro, story_selection_texts, story_selection_next, story_force_guide_group, story_condition): task_title_key = make_language_story_title_key(story_id, task_title) return { 'Id': int(story_id), 'StoryId': int(story_id), 'TaskTitle': task_title_key, 'Type': int(story_type), 'StoryNpcId': int(story_npc_id), 'MapLevel': int(map_level), 'StoryIntro': story_intro, 'SelectionTexts': story_selection_texts, 'SelectionNext': story_selection_next, 'NeedBg': False, 'HideUi': False, 'Transition': False, 'TransitionType': 3, 'Skip': False, 'PlayInterval': 5, 'ProgramControl': True, 'NeedSave': len(story_selection_texts) > 0, 'ForceGuideGroup': story_force_guide_group, 'Condition': story_condition, 'Group': '', 'DataCheck': '' } # function: create_stroyPerformCfg, act_type: 'RoleMovein', 'RoleSpeaking', 'RoleMoveout' def create_stroyPerformCfg(script_info_list, story_id, story_type, start_idx, end_idx): cfgs = [] idx = 0 type_idx = 0 if start_idx <= end_idx: for script_info in script_info_list[start_idx:end_idx+1]: if has_content(script_info['script']): idx += 1 story_perform_id = str(int(story_id)*100 + idx) SpeakSite = 1 SpeakId = make_language_key(story_perform_id, script_info['script']) LeftName = '' LeftImg = '' LeftAct = '' RightName = '' RightImg = '' RightAct = '' actor_info = get_actor_info(script_info['name']) if has_content(script_info['story_intro']): type_idx += 1 print(script_info['story_intro']) if actor_info == None: print("ERR: not find actor name, story_id=" + story_id) if actor_info['NameKey'] == 'player': if idx == 1: SpeakSite = 2 LeftName = '' LeftImg = '' LeftAct = '' RightImg = actor_info['Img'] RightName = actor_info['NameKey'] if story_type == 0: RightImg = actor_info['Img'] else: RightImg = actor_info['Head'] RightAct = '' else: SpeakSite = 2 LeftName = '' LeftImg = '' LeftAct = 'RoleMoveout' RightImg = actor_info['Img'] RightName = actor_info['NameKey'] if story_type == 0: RightImg = actor_info['Img'] else: RightImg = actor_info['Head'] RightAct = 'RoleMovein' else: if idx == 1: SpeakSite = 1 LeftName = actor_info['NameKey'] LeftImg = actor_info['Img'] if story_type == 0: LeftImg = actor_info['Img'] else: LeftImg = actor_info['Head'] LeftAct = '' RightName = '' RightImg = '' RightAct = '' else: SpeakSite = 1 LeftName = actor_info['NameKey'] LeftImg = actor_info['Img'] if story_type == 0: LeftImg = actor_info['Img'] else: LeftImg = actor_info['Head'] LeftAct = 'RoleMovein' RightName = '' RightImg = '' RightAct = 'RoleMoveout' cfgs.append({ 'Id': story_perform_id, 'StoryId': story_id, 'Type': type_idx, 'LeftAct': LeftAct, 'LeftActBgTime': 0, 'RightAct': RightAct, 'RightActBgTime': 0, 'LeftName': LeftName, 'LeftNameColour': 'title02', 'LeftImg': LeftImg, 'RightName': RightName, 'RightNameColour': 'title01', 'RightImg': RightImg, 'SpeakSite': SpeakSite, 'SpeakId': SpeakId, 'SpeakTime': 0, 'WordTime': 10, 'Camp': '', 'CfgId': '', 'Dir': '', 'DirStartTime': '', 'AniName': '', 'AniStartTime': '', 'Eff': '', 'EffStartTime': '', 'OverTime': 0 }) # 如果是对话框对话,就要在首尾添加入场配置和退场配置 ''' 这个是以前的RO对话剧情,必须在首位添加配置,现在暂时屏蔽了,用漫画剧情 if story_type == 0: story_perform_id = str(int(story_id)*100 + 0) LeftName = cfgs[0]['LeftName'] LeftImg = cfgs[0]['LeftImg'] RightName = cfgs[0]['RightName'] RightImg = cfgs[0]['RightImg'] LeftAct = "" RightAct = "" if LeftName != "": LeftAct = "RoleMovein" if RightName != "": RightAct = "RoleMovein" cfgs.insert(0, { 'Id': story_perform_id, 'StoryId': story_id, 'Type': 0, 'LeftAct': LeftAct, 'LeftActBgTime': 0, 'RightAct': RightAct, 'RightActBgTime': 0, 'LeftName': LeftName, 'LeftNameColour': 'title02', 'LeftImg': LeftImg, 'RightName': RightName, 'RightNameColour': 'title01', 'RightImg': RightImg, 'SpeakSite': 0, 'SpeakId': '', 'SpeakTime': 0, 'WordTime': 0, 'Camp': '', 'CfgId': '', 'Dir': '', 'DirStartTime': '', 'AniName': '', 'AniStartTime': '', 'Eff': '', 'EffStartTime': '', 'OverTime': 0 }) story_perform_id = str(int(story_id)*100 + len(cfgs)) LeftName = cfgs[-1]['LeftName'] LeftImg = cfgs[-1]['LeftImg'] RightName = cfgs[-1]['RightName'] RightImg = cfgs[-1]['RightImg'] cfgs.append({ 'Id': story_perform_id, 'StoryId': story_id, 'Type': 0, 'LeftAct': 'RoleMoveout', 'LeftActBgTime': 0, 'RightAct': 'RoleMoveout', 'RightActBgTime': 0, 'LeftName': LeftName, 'LeftNameColour': 'title02', 'LeftImg': LeftImg, 'RightName': RightName, 'RightNameColour': 'title01', 'RightImg': RightImg, 'SpeakSite': 0, 'SpeakId': '', 'SpeakTime': 0, 'WordTime': 0, 'Camp': '', 'CfgId': '', 'Dir': '', 'DirStartTime': '', 'AniName': '', 'AniStartTime': '', 'Eff': '', 'EffStartTime': '', 'OverTime': 0 }) ''' for i, cfg_item in enumerate(cfgs): if cfg_item == None: print("----cfg_item is None-----") #print(cfg_item) return cfgs # function: make_story_cfg def make_story_cfg(story_cfgs, stroyPerformCfgV2_cfgs, story_data): ID = story_data['id'] level = story_data['map_level'] task_title = story_data['task_title'] story_type = 0 story_npc_id = 0 if '对话' in story_data['story_type']: story_type = 0 elif '聊天' in story_data['story_type']: story_type = 1 strs = story_data['story_type'].split(':') if len(strs) == 2: story_type = 0 if strs[0] == '对话': story_type = 0 elif strs[0] == '聊天': story_type = 1 actor_info = get_actor_info(strs[1]) story_npc_id = int(actor_info['StoryNpcId']) story_force_guide_group = 0 story_condition = '' has_multi_options = False for i in range(len(story_data['B1_scripts'])): if has_content(story_data['B1_scripts'][i]['script']) and has_content(story_data['B2_scripts'][i]['script']) and has_content(story_data['B3_scripts'][i]['script']): story_id = "%s0" % (ID) story1_id = "%s1" % (ID) story2_id = "%s2" % (ID) story3_id = "%s3" % (ID) story1_opt_1 = make_language_story_opt_key(story1_id, story_data['B1_scripts'][i]['script']) story1_opt_2 = make_language_story_opt_key(story2_id, story_data['B2_scripts'][i]['script']) story1_opt_3 = make_language_story_opt_key(story3_id, story_data['B3_scripts'][i]['script']) story_intro_keys = [] for story_intro_i in range(len(story_data['story_intro'])): story_intro_keys.append(make_language_story_intro_key(int(story_id)*100+story_intro_i, story_data['story_intro'][story_intro_i])) story_intro_str = ';'.join(story_intro_keys) story1_selection_texts = "%s;%s;%s" % (story1_opt_1, story1_opt_2, story1_opt_3) story1_selection_next = "%s;%s;%s" % (story1_id, story2_id, story3_id) story_cfgs.append(create_story_cfg(story_id, task_title, story_type, story_npc_id, level, story_intro_str, story1_selection_texts, story1_selection_next, story_force_guide_group, story_condition)) story_cfgs.append(create_story_cfg(story1_id, task_title, story_type, story_npc_id, level, '', '', '', 0, '')) story_cfgs.append(create_story_cfg(story2_id, task_title, story_type, story_npc_id, level, '', '', '', 0, '')) story_cfgs.append(create_story_cfg(story3_id, task_title, story_type, story_npc_id, level, '', '', '', 0, '')) if story_type == 1: stroyPerformCfgV2_cfgs.extend(create_stroyPerformCfg(story_data['B1_scripts'], story_id, story_type, 0, i-1)) stroyPerformCfgV2_cfgs.extend(create_stroyPerformCfg(story_data['B1_scripts'], story1_id, story_type, i+1, len(story_data['B1_scripts'])-1)) stroyPerformCfgV2_cfgs.extend(create_stroyPerformCfg(story_data['B2_scripts'], story2_id, story_type, i+1, len(story_data['B2_scripts'])-1)) stroyPerformCfgV2_cfgs.extend(create_stroyPerformCfg(story_data['B3_scripts'], story3_id, story_type, i+1, len(story_data['B3_scripts'])-1)) has_multi_options = True break if has_content(story_data['B1_scripts'][i]['script']) and has_content(story_data['B2_scripts'][i]['script']) and has_content(story_data['B3_scripts'][i]['script']) == False: story_id = "%s0" % (ID) story1_id = "%s1" % (ID) story2_id = "%s2" % (ID) story1_opt_1 = make_language_story_opt_key(story1_id, story_data['B1_scripts'][i]['script']) story1_opt_2 = make_language_story_opt_key(story2_id, story_data['B2_scripts'][i]['script']) story_intro_keys = [] for story_intro_i in range(len(story_data['story_intro'])): story_intro_keys.append(make_language_story_intro_key(int(story_id)*100+story_intro_i, story_data['story_intro'][story_intro_i])) story_intro_str = ';'.join(story_intro_keys) story1_selection_texts = "%s;%s" % (story1_opt_1, story1_opt_2) story1_selection_next = "%s;%s" % (story1_id, story2_id) story_cfgs.append(create_story_cfg(story_id, task_title, story_type, story_npc_id, level, story_intro_str, story1_selection_texts, story1_selection_next, story_force_guide_group, story_condition)) story_cfgs.append(create_story_cfg(story1_id, task_title, story_type, story_npc_id, level, '', '', '', 0, '')) story_cfgs.append(create_story_cfg(story2_id, task_title, story_type, story_npc_id, level, '', '', '', 0, '')) if story_type == 1: stroyPerformCfgV2_cfgs.extend(create_stroyPerformCfg(story_data['B1_scripts'], story_id, story_type, 0, i-1)) stroyPerformCfgV2_cfgs.extend(create_stroyPerformCfg(story_data['B1_scripts'], story1_id, story_type, i+1, len(story_data['B1_scripts'])-1)) stroyPerformCfgV2_cfgs.extend(create_stroyPerformCfg(story_data['B2_scripts'], story2_id, story_type, i+1, len(story_data['B2_scripts'])-1)) has_multi_options = True break if has_multi_options == False: story_id = "%s0" % (ID) story_intro_keys = [] for story_intro_i in range(len(story_data['story_intro'])): story_intro_keys.append(make_language_story_intro_key(int(story_id)*100+story_intro_i, story_data['story_intro'][story_intro_i])) story_intro_str = ';'.join(story_intro_keys) story_cfgs.append(create_story_cfg(story_id, task_title, story_type, story_npc_id, level, story_intro_str, '', '', story_force_guide_group, story_condition)) if story_type == 1: stroyPerformCfgV2_cfgs.extend(create_stroyPerformCfg(story_data['B1_scripts'], story_id, story_type, 0, len(story_data['B1_scripts'])-1)) # function: generate_StoryCfgV2 def generate_StoryCfgV2(out_path, data): with open(out_path+'/StoryCfgV2.csv', 'w', newline='', encoding='utf-8') as file: fieldnames = ['序列ID', '触发剧情ID', '剧情标题', '剧情类型(0是对话,其他ChatNpcId)', '剧情NpcId', '关卡', '剧情介绍', '选项显示', '继续下一个剧情', '是否底图', '是否隐藏UI', '是否转场', '转场类型', '是否可跳过', '剧情播放间隔时间(s)', '是否需要程序驱动', '是否存盘', '强制引导', '触发条件', '同组', '数据判断'] row1 = ['Id', 'StoryId', 'StoryTitle', 'Type', 'StoryNpcId', 'MapLevel', "StoryIntro", 'SelectionTexts', 'SelectionNext', 'NeedBg', 'HideUi', 'Transition', 'TransitionType', 'Skip', 'PlayInterval', 'ProgramControl', 'NeedSave', 'ForceGuideGroup', 'Condition', 'Group', 'DataCheck'] row2 = ['int', 'int', 'string', 'int', 'int', 'int', 'list', 'list', 'list', 'bool', 'bool', 'bool', 'int', 'bool', 'int', 'bool', 'bool', 'int', 'list', 'list', 'list'] csv_data = [] csv_data.append(fieldnames) csv_data.append(row1) csv_data.append(row2) for i, data_item in enumerate(data): csv_data.append(data_item.values()) writer = csv.writer(file) writer.writerows(csv_data) #print("\n--- StoryCfgV2.csv ---") #print(csv_data) # function: generate_StroyPerformCfgV2 def generate_StroyPerformCfgV2(out_path, data): with open(out_path+'/StroyPerformCfgV2.csv', 'w', newline='', encoding='utf-8') as file: fieldnames = ['序列ID', '剧情ID', '类型', '左侧行为', '左侧行为开始时间', '右侧行为', '右侧行为时间', '左侧姓名', '左侧姓名颜色', '左侧半身像', '右侧姓名', '右侧姓名颜色', '阵营', '配置ID', '面向', '面向开始时间', '动作名字', '动作开始时间', '特效ID', '特效开始时间', '结束时间'] row1 = ['Id', 'StoryId', 'Type', 'LeftAct', 'LeftActBgTime', 'RightAct', 'RightActBgTime', 'LeftName', 'LeftNameColour', 'LeftImg', 'RightName', 'RightNameColour', 'RightImg', 'SpeakSite', 'SpeakId', 'SpeakTime', 'WordTime', 'Camp', 'CfgId', 'Dir', 'DirStartTime', 'AniName', 'AniStartTime', 'Eff', 'EffStartTime', 'OverTime'] row2 = ['int', 'int', 'int', 'string', 'int', 'string', 'int', 'string', 'string', 'string', 'string', 'string', 'string', 'int', 'string', 'int', 'int', 'list', 'list', 'list', 'list', 'list', 'list', 'list', 'list', 'int'] csv_data = [] csv_data.append(fieldnames) csv_data.append(row1) csv_data.append(row2) print("\n--- StroyPerformCfgV2.csv ---") for i, data_item in enumerate(data): if data_item == None: print("data_item: None " + str(i)) csv_data.append(data_item.values()) writer = csv.writer(file) writer.writerows(csv_data) # function: generate_StoryNpcCfgV2 def generate_StoryNpcCfgV2(out_path, storyNpcCfg): with open(out_path+'/StoryNpcCfgV2.csv', 'w', newline='', encoding='utf-8') as file: fieldnames = ['序列ID', 'Story NPC ID', '类型(1妻子,2情人,3陌生人,4群聊,0其他)', '昵称Key', '昵称', '头像', '对话框半身像', '地点', '年龄', '民族', '婚姻状况', '签名', '发现动态内容', '发现动态图片', '发现动态点赞数', '发现动态评论数', '关卡解锁', '主角等级解锁', '爬塔层数解锁', '撩一撩剧情'] row1 = ['Id', 'StoryNpcId', 'Type', 'NameKey', 'Name', 'Head', 'Img', 'Location', 'Age', 'Nation', 'Marry', 'Sign', 'Post', 'Photos', 'Upvote', 'Comment', 'MapLevel', 'PlayerLevel', 'TowerLevel', 'StoryId'] row2 = ['int', 'int', 'int', 'string', 'string', 'string', 'string', 'string', 'int', 'string', 'string', 'string', 'string', 'list', 'int', 'int', 'int', 'int', 'int', 'int'] csv_data = [] csv_data.append(fieldnames) csv_data.append(row1) csv_data.append(row2) print("\n--- StoryNpcCfgV2.csv ---") for i, data_item in enumerate(storyNpcCfg): if data_item == None: print("data_item: None " + str(i)) data_item['Location'] = data_item['Location'] data_item['Nation'] = data_item['Nation'] data_item['Marry'] = data_item['Marry'] data_item['Sign'] = make_language_key2("NPCSign%s"%(data_item['Id']), data_item['Sign']) data_item['Post'] = make_language_key2("NPCPost%s"%(data_item['Id']), data_item['Post']) csv_data.append(data_item.values()) #print(data_item.values()) writer = csv.writer(file) writer.writerows(csv_data) # function: generate_StoryRewards, data is storyData # def generate_StoryRewards(out_path, data): # with open(out_path+'/StoryRewards.csv', 'w', newline='', encoding='utf-8') as file: # fieldnames = ['剧情Id', '关卡条件', '增加好感度NPC', '增加好感度', '剧情奖励1', '剧情奖励2', '剧情奖励3', # '剧情奖励4', '剧情奖励5', '剧情奖励6', '剧情奖励7', '剧情奖励8'] # row1 = ['StoryId', 'MapLevel', 'AddHeartNpc', 'AddHeart', 'Reward1', 'Reward2', 'Reward3', 'Reward4', # 'Reward5', 'Reward6', 'Reward7', 'Reward8'] # row2 = ['int', 'int', 'int', 'int', 'list', 'list', 'list', 'list', # 'list', 'list', 'list', 'list'] # csv_data = [] # csv_data.append(fieldnames) # csv_data.append(row1) # csv_data.append(row2) # for i, data_item in enumerate(data): # story_id = data_item['StoryId'] # map_level = data_item['MapLevel'] # reward_text = data_item['Reward'] # pattern = r'\{([^}]+)\}' # matches = re.findall(pattern, reward_text) # row = {'StoryId': story_id, 'MapLevel': map_level, 'AddHeartNpc': data_item['StoryNpcId'], 'AddHeart': data_item['AddHeart']} # for i in range(8): # row[f"Reward{i+1}"] = '' # for i in range(len(matches)): # row[f"Reward{i+1}"] = matches[i] # csv_data.append(row.values()) # writer = csv.writer(file) # writer.writerows(csv_data) # function: generate_LanguagePackageV2_cn def generate_LanguagePackageV2_cn(out_path, data): with open(out_path+'/../../../Assets/Content/Config/LanguagePackageV2_cn.csv', 'w', newline='', encoding='utf-8') as file: fieldnames = ['key', '内容'] row1 = ['key', 'Language'] row2 = ['string', 'string'] csv_data = [] csv_data.append(fieldnames) csv_data.append(row1) csv_data.append(row2) for actor_info in g_actor_info_dict: csv_data.append([actor_info['NameKey'], actor_info['Name']]) for key, value in data.items(): csv_data.append([key, value]) writer = csv.writer(file) writer.writerows(csv_data) print("\n--- LanguagePackageV2_cn.csv ---") #print(csv_data) def generate_StoryAICfgV2(out_path, storyAICfg): with open(out_path+'/StoryAICfgV2.csv', 'w', newline='', encoding='utf-8') as file: fieldnames =['序号', '剧情NPC', '剧情ID', '类型(1-发送,2-响应)', '消息'] row1 = ['Id', 'StoryNpcId', 'StoryId', 'Type', 'Message'] row2 = ['int', 'int', 'int', 'int', 'string'] csv_data = [] csv_data.append(fieldnames) csv_data.append(row1) csv_data.append(row2) print("\n--- StoryAICfgV2.csv ---") for i, data_item in enumerate(storyAICfg): if data_item == None: print("data_item: None " + str(i)) data_item['Message'] = make_language_key2("AIT%s"%(data_item['Id']), data_item['Message']) csv_data.append(data_item.values()) writer = csv.writer(file) writer.writerows(csv_data) # function: generate_config def generate_config(story_data_list, out_path): StoryCfgV2_lines = [] StroyPerformCfgV2_lines = [] LanguagePackage_cn_lines = [] for i, story_data in enumerate(story_data_list): make_story_cfg(StoryCfgV2_lines, StroyPerformCfgV2_lines, story_data) generate_StoryAICfgV2(out_path, g_ai_cfg_dict) generate_StoryNpcCfgV2(out_path, g_actor_info_dict) generate_StoryCfgV2(out_path, StoryCfgV2_lines) #generate_StoryRewards(out_path, StoryCfgV2_lines) generate_StroyPerformCfgV2(out_path, StroyPerformCfgV2_lines) generate_LanguagePackageV2_cn(out_path, g_language_strs) # main入口 if __name__ == "__main__": g_script_dir = os.path.dirname(os.path.abspath(__file__)) g_input_dir = os.path.join(g_script_dir, 'input') g_out_dir = os.path.join(g_script_dir, 'output') g_input_dir = g_input_dir.replace('\\', '/') g_out_dir = g_out_dir.replace('\\', '/') print('g_input_dir: ' + g_input_dir) print('g_out_dir: ' + g_out_dir) g_story_data_list = [] # 1. Read StoryNpcCfg.csv file_path = os.path.join(g_input_dir, 'StoryNpcCfg.csv') file_content = read_text_file(file_path) g_actor_info_dict = parse_csv_to_dict2(file_content) #shutil.copy(file_path, g_out_dir) # 2. Read StoryAICfg.csv file_path = os.path.join(g_input_dir, 'StoryAICfg.csv') file_content = read_text_file(file_path) g_ai_cfg_dict = parse_csv_to_dict2(file_content) #shutil.copy(file_path, g_out_dir) # 3. Read StoryRewardCfg.csv file_path = os.path.join(g_input_dir, 'StoryRewardCfg.csv') file_content = read_text_file(file_path) g_StoryRewardCfg = parse_csv_to_dict2(file_content) shutil.copy(file_path, g_out_dir) file_path = os.path.join(g_input_dir, 'StoryItemCfg.csv') file_content = read_text_file(file_path) g_StoryRewardCfg = parse_csv_to_dict2(file_content) shutil.copy(file_path, g_out_dir) # 4. Read StoryText.csv file_path = os.path.join(g_input_dir, 'StoryText.csv') file_content = read_text_file(file_path) if file_content is not None: # 解析csv数据为Dict csv_data = parse_csv_to_dict(file_content) # 把csv数据分隔为一段段剧情,并生成剧情数据列表:story_data_list story_range_list = calc_story_range_list(csv_data) for i, story_range in enumerate(story_range_list): story_data = make_story_data(csv_data, story_range['start'], story_range['end']) g_story_data_list.append(story_data) # 根据story_data_list生成配置文件 generate_config(g_story_data_list, g_out_dir) ''' for filename in os.listdir(g_input_dir): if filename.endswith('.csv'): file_path = os.path.join(g_input_dir, filename) file_content = read_text_file(file_path) if file_content is not None: print(f"=== {filename} ===") # 解析csv数据为Dict csv_data = parse_csv_to_dict(file_content) # 把csv数据分隔为一段段剧情,并生成剧情数据列表:story_data_list story_range_list = calc_story_range_list(csv_data) for i, story_range in enumerate(story_range_list): story_data = make_story_data(csv_data, story_range['start'], story_range['end']) g_story_data_list.append(story_data) #print("--- story_data ---") #print(story_data) #print() # 根据story_data_list生成配置文件 generate_config(g_story_data_list, g_out_dir) else: print(f"无法读取文件: {filename}") '''