|  | 
 
| 本帖最后由 战斗的人生 于 2020-11-9 01:15 编辑 
 工具原贴地址:https://github.com/KSneijders/AoE2ScenarioParser/blob/master/README.md#aoe2scenarioparser
 
 这是一个可以编辑后缀为.aoe2scenario的帝国时代2DE战役文件的工具。原作者ID:KSneijders。
 我暂且给他命名为:python场景工具
 
 一、功能与介绍:
 
 | 
 | 查看 | 添加 | 编辑 | 移除 |  | 触发 | √ | √ | √ | √ |  | 条件 | √ | √ | √ | √ |  | 效果 | √ | √ | √ | √ |  | 单位 | 
 | √ | √ | √ | 
 这个工具是一个python工具箱,可以通过编写代码,编辑帝国时代2DE的场景文件。写好代码后,运行代码,就可以编辑文件了。
 
 二、工具安装:
 此部分十分重要,请务必严格按照步骤来。
 本部分教程由木匠大佬Carpenter提供,强烈推荐大家去模组下载他的联机场景金特~
 
 1)   基本工具需求
 Python 3.7 (或以上版本,经过实测这个辣鸡包要用到3.7以上的函数。他简介里要求的3.6根本跑不起来)
 Python IDE (综合配置环境),建议选择Visual Studio(强烈建议)
 
 命令行控制工具,没有则建议使用电脑自带的cmd,菜单-任务-运行“cmd”即可打开,也就是下面这玩意儿
 
 python3.7和Visual Studio可以在软件官网上安装,cmd则是电脑自带。
 
 2) 命令行配置系统
 使用命令行能快速配置,防止手工点击各种辣鸡下载站收获各种安装捆绑全家桶。
 首先,为了完成系统环境的配置,我们对系统内置包进行升级。需要升级的包括pip,python。
 首先,打开cmd(或者Anaconda Prompt),在窗口输入
 
 然后敲击回车,等待安装完成复制代码python -m pip install --upgrade pip
 然后,继续在此窗口,分别输入以下命令并回车
 安装和升级python。复制代码pip install python
pip upgrade python
这样我们就完成了环境的安装。
 
 3) AoE2ScenarioParser本体安装
 依然是在cmd窗口,分别输入以下命令并敲回车
 以上,我们完成了所有环境与工具安装。接下来就是正式使用了。复制代码pip install AoE2ScenarioParser
pip install bidict
 三、正式使用:
 
 1)测试
 首先,我们创建一个文件名后缀为 .py 的文件
 
 然后用VS打开,输入
 接着点击“运行”或者键盘上单击F5运行或者ctrl+F5运行,如果得到以下结果,说明工具箱安装完成。如果报错,说明前面安装过程中出了问题,请对照步骤,再安装一次。复制代码from AoE2ScenarioParser.aoe2_scenario import AoE2Scenario
 
 2)通用代码
 通用代码如下:
 其中,“#”后面的是注释。复制代码from AoE2ScenarioParser.aoe2_scenario import AoE2Scenario
# Information about the conditions & effects and their attributes
from AoE2ScenarioParser.datasets.conditions import Condition
from AoE2ScenarioParser.datasets.effects import Effect
from AoE2ScenarioParser.datasets.trigger_lists import DiplomacyState, Operator, ButtonLocation, PanelLocation, \
    TimeUnit, VisibilityState, DifficultyLevel, TechnologyState, Comparison, ObjectAttribute, Attribute
# Information of unit/tech/terrain name and their ID
from AoE2ScenarioParser.datasets.buildings import Building, GaiaBuilding
from AoE2ScenarioParser.datasets.techs import Tech
from AoE2ScenarioParser.datasets.heroes import Hero
from AoE2ScenarioParser.datasets.terrains import Terrain
from AoE2ScenarioParser.datasets.units import Unit, GaiaUnit
# Enum of players
from AoE2ScenarioParser.datasets.players import Player, PlayerColor
input_path = " "
output_path = " "
scenario = AoE2Scenario(input_path)
# 代码正文开始
# 代码正文结尾
scenario.write_to_file(output_path)
需要重点说明的是这两句:
 input_path后的双引号内是战役读取路径,output_path后的双引号内是战役存储路径,比如我设为:复制代码input_path = " "
output_path = " "
就可以读取这个文件夹内名字为“测试0”的场景文件,运行代码后得到的是一个新建的名字为“测试1”的场景文件。这两个文件名也可以设为同一个,但我推荐设为不同的名字,这样方便测试和debug。复制代码input_path = "D:/Age of emperor2/Mine/Half-work/cooperation/测试0.aoe2scenario"
output_path = "D:/Age of emperor2/Mine/Half-work/cooperation/测试1.aoe2scenario"
文件夹路径可以直接复制粘贴。
 
 其他的部分可以直接复制粘贴。建议将这些代码新建为一个新文件,以后每次要用可以直接使用。
 
 3)代码正文
 终于,我们来到了正式使用部分。在文末的压缩包中,我会附上所有可以用到的帮助文档。当然你也可以到最上面的原贴地址中查找。
 在开始之前,我要介绍一个VS功能,折叠代码。
 
 它的效果是这样的,可以极大提升代码可读性。复制代码#region 标记文字
your python code
#endregion
 接下来我将分别介绍触发代码写法和单位代码写法。写好需要的代码后,运行代码,就可以编辑场景文件了。注意,触发代码和地图代码并非都要写。如果你想编辑触发,那就写触发代码;如果想编辑单位,那就写单位代码。因为我还没有用到单位代码的所有功能,所以以下只介绍“新建单位功能”,其他功能以后更新。
 注意:当读取路径和存储路径相同时不要多次运行代码,因为每运行一次代码场景文件都会被编辑一次。但读取路径和存储路径不同时就不会有这个问题,因为每次运行代码后者都会被完全覆盖。这也是我推荐两个路径设置不同的原因之一。
 
 a)触发部分
 触发部分代码分为三个部分,触发编码库导入、触发声明和触发代码。
 
 (1)触发编码库导入
 触发编码库导入部分如下,直接复制粘贴即可,放在正文开头即可
 
 复制代码trigger_manager = scenario.object_manager.trigger_manager                # 导入触发编码
(2)触发声明
 触发声明和触发代码部分有前后关系,触发声明必须放在触发代码之前。
 触发声明代码全文如下:
 
 其中“替换触发”为代码正文的名称,可以自己定义;在游戏中显示的触发名是由 trigger_manager.add_trigger("")中的双引号内部分定义的。复制代码替换触发 = trigger_manager.add_trigger("")
替换触发.enabled =                                 # 是否开启
替换触发.looping =                                 # 是否循环
替换触发.description_stid =                         # 触发文本描述 ID
替换触发.display_as_objective =                 # 在任务栏显示
替换触发.display_on_screen =                         # 在屏幕上显示
替换触发.short_description_stid =                 # 简短描述顺序 ID
替换触发.header =                                 # 是否作为标题
替换触发.description_order =                         # 触发任务栏描述顺序
替换触发.mute_objectives =                         # 禁止发出提示音
替换触发.description = ""                        # 触发文本描述
替换触发.name =                                 # 触发名
替换触发.short_description = ""                        # 简短描述
替换触发.trigger_id =                         # 触发ID ?用于python代码,无效
替换触发.condition_order =                         # !不明
替换触发.conditions =                         # !不明
替换触发.effect_order =                         # !不明
替换触发.effects =                                 # !不明
 注意:实际使用时,并不需要把以上每一行代码都复制上,只编写自己需要用到的部分即可。例如,我想新建一个默认开启且循环的触发,我只需要这样写:
 
 复制代码t1_1 = trigger_manager.add_trigger("【勇者 S +1 】")
t1_1.enabled = 1            # 是否开启
t1_1.looping = 1            # 是否循环
就可以了。这个触发的代码正文名为“ t1_1 ”,为它新建条件与效果时引用的就是这个名字。
 
 (3)触发代码
 定义之后,在代码正文内我们就得到了一个名为“替换触发”的触发,可以在触发代码部分为这个触发新建条件与效果了。
 
 所有条件代码如下,其中“替换条件”为该条件在代码正文内的名称,可以自己定义,每个条件的名字必须独立;“替换触发”为该条件所在的触发的代码正文名。与触发代码一样,条件代码也不需要复制每一行,只复制自己需要的即可。
 
 效果代码与条件代码一样。全文如下:
 
 接下来,我用一个示例,来帮助大家理解条件和效果代码写法。
 首先定义一个触发:
 
 然后为它创建条件与效果:复制代码t1_1 = trigger_manager.add_trigger("【勇者 S +1 】")
t1_1.enabled = 1            # 是否开启
t1_1.looping = 1            # 是否循环
 这样,我们就得到了一个完整的触发。复制代码# 区域内物件数目 >=
c1_1_1 = t1_1.add_condition(Condition.OBJECT_IN_AREA)
c1_1_1.amount_or_quantity = 1            # 数值
c1_1_1.object_list = 1304                # 物件固有 ID
c1_1_1.player = 1                        # 起始玩家
c1_1_1.area_1_x = 200
c1_1_1.area_1_y = 222                        # 起始点 xy 坐标
c1_1_1.area_2_x = 200
c1_1_1.area_2_y = 222                        # 终止点 xy 坐标
# 传送物件
e1_1_1 = t1_1.add_effect(Effect.TELEPORT_OBJECT)
e1_1_1.object_list_unit_id = 1304                        # 物件固有 ID
e1_1_1.player_source = 1                        # 起始玩家
e1_1_1.location_x = 239
e1_1_1.location_y = 239                        # 位置坐标 xy
e1_1_1.area_1_x = 200
e1_1_1.area_1_y = 222                                # 起始范围坐标 xy
e1_1_1.area_2_x = 200
e1_1_1.area_2_y = 222                                # 终止范围坐标 xy
# 移除物件
e1_1_2 = t1_1.add_effect(Effect.REMOVE_OBJECT)
e1_1_2.object_list_unit_id = 1304                        # 物件固有 ID
e1_1_2.player_source = 1                        # 起始玩家
e1_1_2.area_1_x = 239
e1_1_2.area_1_y = 239                                # 起始范围坐标 xy
e1_1_2.area_2_x = 239
e1_1_2.area_2_y = 239                                # 终止范围坐标 xy
# 修改变量
e1_1_3 = t1_1.add_effect(Effect.CHANGE_VARIABLE)
e1_1_3.quantity = 1                                # 数值
e1_1_3.operation = 2                        # 改变方式
                # 设置 = 1;增加 = 2;减少 = 3;相乘 = 4;相除 = 5
e1_1_3.from_variable = 11                        # 变量 ID
e1_1_3.message = "勇者力量"                        # 文本
# 修改变量
e1_1_4 = t1_1.add_effect(Effect.CHANGE_VARIABLE)
e1_1_4.quantity = 15                                # 数值
e1_1_4.operation = 2                        # 改变方式
                # 设置 = 1;增加 = 2;减少 = 3;相乘 = 4;相除 = 5
e1_1_4.from_variable = 15                        # 变量 ID
e1_1_4.message = "勇者力量增加值"                        # 文本
 (4)触发组写法
 可能写到这里,读者会问:我为了简便操作而来,可你写一个触发的时间够我在地编做二十个了!
 这自然。只做一两个触发,根本用不到这个工具。因此,我要介绍一个新概念——触发组。
 触发是达成条件,发动效果。而单个触发往往不能满足我们的需求,所以我们需要多个触发共同作用,这就是触发组。在RPG战役和联机场景中,触发组就更常见了,RPG战役中往往一个技能就需要包含几十个触发的触发组。而一个写好的触发组复制粘贴,肯定是要比地编的单个触发复制粘贴要方便很多的。
 借用我正在制作的战役的示例。首先,我们定义一组触发,并折叠起来,这样方便阅读:
 
 之后,我们为每一个触发新建条件、效果,并把每一个触发折叠起来,
 
 这样,就得到了一组触发,如图。
 
 需要类似触发组,就复制粘贴,然后运用VScode的替换功能,选取复制部分替换。注意:一定要同时替换触发代码正文名、条件代码正文名和效果代码正文名。
 最后,我们得到了数组类似的触发组,如图。(注意图片左边的代码行数)
 
 这是我正在设计的一个战役的其中一个主角的技能。大概是90个触发。而技能与他类似的角色还有9个。这900+触发运用代码编写,可以节省大量工作量。而联机场景中动辄2、3000重复触发,使用这个工具的意义就更大了。
 
 最后是条件和效果中可能运用到的常数列表,也会附加在文末压缩包内。其中单位属性、资源ID和攻击防御类型,建议通过DE大典查找。
 
 b)单位部分
 本工具可以对单位执行新建、查找、编辑和移除。十分抱歉,我目前只使用和测试过了新建功能,因此无法对后三项功能进行介绍。大家有需要的可以自行到原地址学习。以下只介绍新建单位功能。但请相信我,这是一个十分十分强大的功能。
 单位部分代码分为两部分,单位编码导入和单位代码。
 单位编码导入代码如下,复制粘贴到代码正文开头即可:
 
 单位代码全文如下,除非标注出来,否者只能填写整数:复制代码unit_manager = scenario.object_manager.unit_manager
 与触发代码一样,以上代码也可以只取所需部分。复制代码unit = unit_manager.add_unit(
        player = ,                        # 玩家 ID
        unit_id = ,                        # 单位固有 ID,请查找DE大典
        x = ,                        # 单位 x 坐标,可填写小数
        y = ,                        # 单位 y 坐标,可填写小数
        z = ,                        # 单位 z 坐标,可填写小数
        rotation = ,                        # 单位的朝向,有 0-15 共16个方向
        garrisoned_in_id = ,                        # 单位所驻扎的位置,需要填写地图 ID
        animation_frame = ,                        # 单位初始动画帧数,绝大多数情况用不到
        reference_id =                         # 单位地图 ID,不填则由地编自动分配
)                                # 注意:后括号前不加“ , ”其余每一行末尾必须加半角“ , ” 
 接下来,我将向大家介绍这个功能的一种神奇的应用,我称之为“二阶导式新建单位”。
 我先放出效果图:
 
 以上只是我为了测试效果而随意画的。理论上,这个工具可以画出任何形状的图形——不用你一个一个单位地手点。
 做法很简单。首先,我们使用任何编程软件,比如C++,matlab,推荐使用matlab。
 
 然后编辑代码来进行运算,得到需要的单位的坐标。
 
 然后,输出要写在python场景工具里的代码,注意一定要严格按照格式
 
 最后,将得到的代码复制粘贴到python场景工具的代码正文部分,记得前面要加上单位编码导入。
 运行工具,我们就得到了所需的图形。
 这种方法,我们写的代码是“输出文件的代码的代码”,因此我将之命名为“二阶导式新建单位”。
 虽然这种方法十分复杂,但是熟练掌握之后,你可以绘制任何图形,拥有无限的可能性。当然,如果你有什么新的应用,也欢迎分享给大家。
 
 最后,感谢木匠,游戏ID:Carpenter,提供的环境安装教程。
 最后的最后,感谢本工具原作者:KSneijders!
 
 帮助文档下载:(其中DE大典来自夜游神的原贴:https://www.hawkaoe.net/bbs/thread-146061-1-1.html)
 
 
 
 | 
 评分
查看全部评分
 |