|
本帖最后由 战斗的人生 于 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
复制代码 然后敲击回车,等待安装完成
然后,继续在此窗口,分别输入以下命令并回车- pip install python
- pip upgrade python
复制代码 安装和升级python。
这样我们就完成了环境的安装。
3) AoE2ScenarioParser本体安装
依然是在cmd窗口,分别输入以下命令并敲回车- pip install AoE2ScenarioParser
- pip install bidict
复制代码 以上,我们完成了所有环境与工具安装。接下来就是正式使用了。
三、正式使用:
1)测试
首先,我们创建一个文件名后缀为 .py 的文件
然后用VS打开,输入- from AoE2ScenarioParser.aoe2_scenario import AoE2Scenario
复制代码 接着点击“运行”或者键盘上单击F5运行或者ctrl+F5运行,如果得到以下结果,说明工具箱安装完成。如果报错,说明前面安装过程中出了问题,请对照步骤,再安装一次。
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后的双引号内是战役存储路径,比如我设为:- input_path = "D:/Age of emperor2/Mine/Half-work/cooperation/测试0.aoe2scenario"
- output_path = "D:/Age of emperor2/Mine/Half-work/cooperation/测试1.aoe2scenario"
复制代码 就可以读取这个文件夹内名字为“测试0”的场景文件,运行代码后得到的是一个新建的名字为“测试1”的场景文件。这两个文件名也可以设为同一个,但我推荐设为不同的名字,这样方便测试和debug。
文件夹路径可以直接复制粘贴。
其他的部分可以直接复制粘贴。建议将这些代码新建为一个新文件,以后每次要用可以直接使用。
3)代码正文
终于,我们来到了正式使用部分。在文末的压缩包中,我会附上所有可以用到的帮助文档。当然你也可以到最上面的原贴地址中查找。
在开始之前,我要介绍一个VS功能,折叠代码。
- #region 标记文字
- your python code
- #endregion
复制代码 它的效果是这样的,可以极大提升代码可读性。
接下来我将分别介绍触发代码写法和单位代码写法。写好需要的代码后,运行代码,就可以编辑场景文件了。注意,触发代码和地图代码并非都要写。如果你想编辑触发,那就写触发代码;如果想编辑单位,那就写单位代码。因为我还没有用到单位代码的所有功能,所以以下只介绍“新建单位功能”,其他功能以后更新。
注意:当读取路径和存储路径相同时不要多次运行代码,因为每运行一次代码场景文件都会被编辑一次。但读取路径和存储路径不同时就不会有这个问题,因为每次运行代码后者都会被完全覆盖。这也是我推荐两个路径设置不同的原因之一。
a)触发部分
触发部分代码分为三个部分,触发编码库导入、触发声明和触发代码。
(1)触发编码库导入
触发编码库导入部分如下,直接复制粘贴即可,放在正文开头即可
- trigger_manager = scenario.object_manager.trigger_manager # 导入触发编码
复制代码
(2)触发声明
触发声明和触发代码部分有前后关系,触发声明必须放在触发代码之前。
触发声明代码全文如下:
- 替换触发 = 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 = # !不明
复制代码 其中“替换触发”为代码正文的名称,可以自己定义;在游戏中显示的触发名是由 trigger_manager.add_trigger("")中的双引号内部分定义的。
注意:实际使用时,并不需要把以上每一行代码都复制上,只编写自己需要用到的部分即可。例如,我想新建一个默认开启且循环的触发,我只需要这样写:
- 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)
|
评分
-
查看全部评分
|