划时代的工具——python场景工具【AoE2ScenarioParser】
本帖最后由 战斗的人生 于 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)触发代码
定义之后,在代码正文内我们就得到了一个名为“替换触发”的触发,可以在触发代码部分为这个触发新建条件与效果了。
所有条件代码如下,其中“替换条件”为该条件在代码正文内的名称,可以自己定义,每个条件的名字必须独立;“替换触发”为该条件所在的触发的代码正文名。与触发代码一样,条件代码也不需要复制每一行,只复制自己需要的即可。
# 条件:无
替换条件 = 替换触发.add_condition(Condition.NONE)
# 将单位带入指定区域
替换条件 = 替换触发.add_condition(Condition.BRING_OBJECT_TO_AREA)
替换条件.unit_object = # 单位地图 ID
替换条件.area_1_x =
替换条件.area_1_y = # 起始点 xy 坐标
替换条件.area_2_x =
替换条件.area_2_y = # 终止点 xy 坐标
替换条件.inverted = # 反向条件
# 条件:将单位带给指定单位
替换条件 = 替换触发.add_condition(Condition.BRING_OBJECT_TO_OBJECT)
替换条件.unit_object = # 单位地图 ID
替换条件.next_object = # 目标单位地图 ID
替换条件.inverted = # 反向条件
# 条件:拥有物件数目 >=
替换条件 = 替换触发.add_condition(Condition.OWN_OBJECTS)
替换条件.amount_or_quantity = # 数值
替换条件.object_list = # 物件固有 ID
替换条件.player = # 起始玩家
替换条件.object_group = # 物件组
替换条件.object_type = # 物件类型
# 条件:区域内物件数目 <=
替换条件 = 替换触发.add_condition(Condition.OWH_FEWER_OBJECTS)
替换条件.amount_or_quantity = # 数值
替换条件.object_list = # 物件固有 ID
替换条件.player = # 起始玩家
替换条件.area_1_x =
替换条件.area_1_y = # 起始点 xy 坐标
替换条件.area_2_x =
替换条件.area_2_y = # 终止点 xy 坐标
替换条件.object_group = # 物件组
替换条件.object_type = # 物件类型
# 条件:区域内物件数目 >=
替换条件 = 替换触发.add_condition(Condition.OBJECT_IN_AREA)
替换条件.amount_or_quantity = # 数值
替换条件.object_list = # 物件固有 ID
替换条件.player = # 起始玩家
替换条件.area_1_x =
替换条件.area_1_y = # 起始点 xy 坐标
替换条件.area_2_x =
替换条件.area_2_y = # 终止点 xy 坐标
替换条件.object_group = # 物件组
替换条件.object_type = # 物件类型
替换条件.inverted = # 反向条件
# 条件:消灭单位
替换条件 = 替换触发.add_condition(Condition.DESTROY_OBJECT)
替换条件.unit_object = # 单位地图 ID
替换条件.inverted = # 反向条件
# 条件:捕获单位
替换条件 = 替换触发.add_condition(Condition.DESTROY_OBJECT)
替换条件.unit_object = # 单位地图 ID
替换条件.player = # 起始玩家
替换条件.inverted = # 反向条件
# 条件:堆积属性
替换条件 = 替换触发.add_condition(Condition.ACCUMULATE_ATTRIBUTE)
替换条件.amount_or_quantity = # 数值
替换条件.resource_type_or_tribute_list = # 资源ID
替换条件.player = # 起始玩家
替换条件.inverted = # 反向条件
# 条件:研究科技
替换条件 = 替换触发.add_condition(Condition.RESEARCH_TECHNOLOGY)
替换条件.player = # 起始玩家
替换条件.technology = # 科技ID
替换条件.inverted = # 反向条件
# 条件:定时器
替换条件 = 替换触发.add_condition(Condition.TIMER)
替换条件.timer = # 定时器
替换条件.inverted = # 反向条件
# 条件:选择单位
替换条件 = 替换触发.add_condition(Condition.OBJECT_SELECTED)
替换条件.unit_object = # 单位地图 ID
替换条件.inverted = # 反向条件
# 条件:AI 信号
替换条件 = 替换触发.add_condition(Condition.AI_SIGNAL)
替换条件.ai_signal = # AI 信号 ID
替换条件.inverted = # 反向条件
# 条件:玩家被打败
替换条件 = 替换触发.add_condition(Condition.PLAYER_DEFEATED)
替换条件.player = # 起始玩家
替换条件.inverted = # 反向条件
# 条件:单位已有目标
替换条件 = 替换触发.add_condition(Condition.OBJECT_HAS_TARGET)
替换条件.unit_object = # 单位地图 ID
# 替换条件.next_object = # 目标单位地图 ID
# 替换条件.object_list = # 物件固有 ID
# 替换条件.object_group = # 物件组
# 替换条件.object_type = # 物件类型
替换条件.inverted = # 反向条件
# 条件:单位可视
替换条件 = 替换触发.add_condition(Condition.OBJECT_VISIBLE)
替换条件.unit_object = # 单位地图 ID
# 条件:单位不可视
替换条件 = 替换触发.add_condition(Condition.OBJECT_NOT_VISIBLE)
替换条件.unit_object = # 单位地图 ID
# 条件:研究科技中
替换条件 = 替换触发.add_condition(Condition.RESEARCHING_TECH)
替换条件.player = # 起始玩家
替换条件.technology = # 科技ID
替换条件.inverted = # 反向条件
# 条件:已驻扎单位
替换条件 = 替换触发.add_condition(Condition.UNITS_GARRISONED)
替换条件.amount_or_quantity = # 数值
替换条件.unit_object = # 单位地图 ID
替换条件.inverted = # 反向条件
# 条件:难度等级 <=
替换条件 = 替换触发.add_condition(Condition.DIFFICULTY_LEVEL)
#替换条件.condition_type = # ?条件类型?
替换条件.amount_or_quantity = # 数值
替换条件.inverted = # 反向条件
# 条件:概率
替换条件 = 替换触发.add_condition(Condition.CHANCE)
替换条件.amount_or_quantity = # 数值
# 条件:科技研发状态
替换条件 = 替换触发.add_condition(Condition.TECHNOLOGY_STATE)
替换条件.amount_or_quantity = # 数值
替换条件.player = # 起始玩家
替换条件.technology = # 科技ID
替换条件.inverted = # 反向条件
# 条件:检测变量
替换条件 = 替换触发.add_condition(Condition.VARIABLE_VALUE)
替换条件.amount_or_quantity = # 数值
替换条件.inverted = # 反向条件
替换条件.variable = # 变量 ID
替换条件.comparison = # 数值比较
# = 0;< 1;> 2;<= 3;>= 4
# 条件:单位 HP
替换条件 = 替换触发.add_condition(Condition.OBJECT_HP)
替换条件.amount_or_quantity = # 数值
替换条件.unit_object = # 单位地图 ID
替换条件.inverted = # 反向条件
替换条件.comparison = # 数值比较
# = 0;< 1;> 2;<= 3;>= 4
# 条件:同盟关系
替换条件 = 替换触发.add_condition(Condition.DIPLOMACY_STATE)
替换条件.amount_or_quantity = # 数值
# 同盟 = 0;中立 = 2;敌对 = 3
替换条件.player = # 起始玩家
替换条件.target_player = # 对象玩家
效果代码与条件代码一样。全文如下:
# 效果:无
替换效果 = 替换触发.add_effect(Effect.NONE)
# 改变外交态度
替换效果 = 替换触发.add_effect(Effect.CHANGE_DIPLOMACY)
替换效果.diplomacy = # 外交
# 同盟 = 0;中立 = 2;敌对 = 3
替换效果.player_source = # 起始玩家
替换效果.player_target = # 对象玩家
# 研究科技
替换效果 = 替换触发.add_effect(Effect.RESEARCH_TECHNOLOGY)
替换效果.player_source = # 起始玩家
替换效果.technology = # 科技 ID
替换效果.force_research_technology = # 强制研发科技
# 送出聊天
替换效果 = 替换触发.add_effect(Effect.SEND_CHAT)
替换效果.player_source = # 起始玩家
替换效果.string_id = # 文本 ID
替换效果.message = "" # 文本
替换效果.sound_name = # wem 文件名
# 播放音乐
替换效果 = 替换触发.add_effect(Effect.SEND_CHAT)
替换效果.player_source = # 起始玩家
替换效果.location_x =
替换效果.location_y = # 位置坐标 xy
替换效果.sound_name = # wem 文件名
# 贡品
替换效果 = 替换触发.add_effect(Effect.TRIBUTE)
替换效果.quantity = # 数值
替换效果.tribute_list = # 资源 ID
替换效果.player_source = # 起始玩家
替换效果.player_target = # 对象玩家
# 开启城门
替换效果 = 替换触发.add_effect(Effect.UNLOCK_GATE)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.selected_object_id = # 城门地图 ID
# 闭锁城门
替换效果 = 替换触发.add_effect(Effect.LOCK_GATE)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.selected_object_id = # 城门地图 ID
# 激活触发
替换效果 = 替换触发.add_effect(Effect.ACTIVATE_TRIGGER)
替换效果.trigger_id = # 触发 ID
# 关闭触发
替换效果 = 替换触发.add_effect(Effect.DEACTIVATE_TRIGGER)
替换效果.trigger_id = # 触发 ID
# 发送 AI 信号
替换效果 = 替换触发.add_effect(Effect.AI_SCRIPT_GOAL)
替换效果.ai_script_goal = # AI 信号 ID
# 产生物件
替换效果 = 替换触发.add_effect(Effect.CREATE_OBJECT)
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.location_x =
替换效果.location_y = # 位置坐标 xy
替换效果.item_id = # 朝向数字
替换效果.facet = # 开启朝向
# 指派物件
替换效果 = 替换触发.add_effect(Effect.TASK_OBJECT)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.location_x =
替换效果.location_y = # 位置坐标 xy
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.selected_object_id = # 选择单位地图 ID
# 宣布胜利
替换效果 = 替换触发.add_effect(Effect.DECLARE_VICTORY)
替换效果.player_source = # 起始玩家
替换效果.enabled_or_victory = # 胜利或失败
# 杀死物件
替换效果 = 替换触发.add_effect(Effect.KILL_OBJECT)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.selected_object_id = # 选择单位地图 ID
# 移除物件
替换效果 = 替换触发.add_effect(Effect.REMOVE_OBJECT)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.selected_object_id = # 选择单位地图 ID
# 改变视角
替换效果 = 替换触发.add_effect(Effect.CHANGE_VIEW)
替换效果.player_source = # 起始玩家
替换效果.location_x =
替换效果.location_y = # 位置坐标 xy
替换效果.scroll = # 是否瞬移
# 卸下
替换效果 = 替换触发.add_effect(Effect.UNLOAD)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.location_x =
替换效果.location_y = # 位置坐标 xy
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.selected_object_id = # 选择单位地图 ID
# 改变所有权
替换效果 = 替换触发.add_effect(Effect.CHANGE_OWNERSHIP)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.player_target = # 对象玩家
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.selected_object_id = # 选择单位地图 ID
# 巡逻
替换效果 = 替换触发.add_effect(Effect.PATROL)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.location_x =
替换效果.location_y = # 位置坐标 xy
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.selected_object_id = # 选择单位地图 ID
# 显示信息
替换效果 = 替换触发.add_effect(Effect.DISPLAY_INSTRUCTIONS)
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.string_id = # 文本 ID
替换效果.display_time = # 显示时间
替换效果.instruction_panel_position = # 显示位置
替换效果.play_sound = # 是否播放音效
替换效果.message = "" # 文本
替换效果.sound_name = # wem 文件名
# 清除信息
替换效果 = 替换触发.add_effect(Effect.CLEAR_INSTRUCTIONS)
替换效果.instruction_panel_position = # 显示位置
# 冻结单位
替换效果 = 替换触发.add_effect(Effect.FREEZE_OBJECT)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.selected_object_id = # 选择单位地图 ID
# 开启高级按钮
#替换效果 = 替换触发.add_effect(Effect.USE_ADVANCED_BUTTONS)
# 原作者:请不要使用这个效果
# 损害物件
替换效果 = 替换触发.add_effect(Effect.DAMAGE_OBJECT)
替换效果.quantity = # 数值
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.selected_object_id = # 选择单位地图 ID
# 放置地基
替换效果 = 替换触发.add_effect(Effect.PLACE_FOUNDATION)
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.location_x =
替换效果.location_y = # 位置坐标 xy
# 改变物件名字
替换效果 = 替换触发.add_effect(Effect.CHANGE_OBJECT_NAME)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.string_id = # 文本 ID
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.message = "" # 文本
替换效果.selected_object_id = # 选择单位地图 ID
# 改变物件生命值
替换效果 = 替换触发.add_effect(Effect.HANGE_OBJECT_HP)
替换效果.quantity = # 数值
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.operation = # 改变方式
# 设置 = 1;增加 = 2;减少 = 3;相乘 = 4;相除 = 5
替换效果.selected_object_id = # 选择单位地图 ID
# 改变物件攻击力
替换效果 = 替换触发.add_effect(Effect.CHANGE_OBJECT_ATTACK)
替换效果.aa_quantity = # 攻击防御专用数值
替换效果.aa_armor_or_attack_type = # 攻击护甲类型数值
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.operation = # 改变方式
# 设置 = 1;增加 = 2;减少 = 3;相乘 = 4;相除 = 5
替换效果.selected_object_id = # 选择单位地图 ID
# 停止物件
替换效果 = 替换触发.add_effect(Effect.STOP_OBJECT)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.selected_object_id = # 选择单位地图 ID
# 移动攻击
替换效果 = 替换触发.add_effect(Effect.ATTACK_MOVE)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.location_x =
替换效果.location_y = # 位置坐标 xy
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.selected_object_id = # 选择单位地图 ID
# 改变物件护甲
替换效果 = 替换触发.add_effect(Effect.CHANGE_OBJECT_ARMOR)
替换效果.aa_quantity = # 攻击防御专用数值
替换效果.aa_armor_or_attack_type = # 攻击护甲类型数值
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.operation = # 改变方式
# 设置 = 1;增加 = 2;减少 = 3;相乘 = 4;相除 = 5
替换效果.selected_object_id = # 选择单位地图 ID
# 改变物件射程
替换效果 = 替换触发.add_effect(Effect.CHANGE_OBJECT_RANGE)
替换效果.quantity = # 数值
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.operation = # 改变方式
# 设置 = 1;增加 = 2;减少 = 3;相乘 = 4;相除 = 5
替换效果.selected_object_id = # 选择单位地图 ID
# 改变物件移动速度
替换效果 = 替换触发.add_effect(Effect.CHANGE_OBJECT_SPEED)
替换效果.quantity = # 数值
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.selected_object_id = # 选择单位地图 ID
# 治疗物件
替换效果 = 替换触发.add_effect(Effect.HEAL_OBJECT)
替换效果.quantity = # 数值
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.selected_object_id = # 选择单位地图 ID
# 传送物件
替换效果 = 替换触发.add_effect(Effect.TELEPORT_OBJECT)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.location_x =
替换效果.location_y = # 位置坐标 xy
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.selected_object_id = # 选择单位地图 ID
# 改变物件姿态
替换效果 = 替换触发.add_effect(Effect.CHANGE_OBJECT_STANCE)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.location_x =
替换效果.location_y = # 位置坐标 xy
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.attack_stance = # 姿态
# 进攻 = 0;防御 = 1;坚守 = 2;投降 = 3
替换效果.selected_object_id = # 选择单位地图 ID
# 显示定时器
替换效果 = 替换触发.add_effect(Effect.DISPLAY_TIMER)
替换效果.string_id = # 文本 ID
替换效果.display_time = # 定时器时间
替换效果.time_unit = # 时间单位
# 秒 = 0;分 = 1;年 = 2
替换效果.variable_or_timer = # 调用定时器 ID
替换效果.message = "" # 文本
# 启用或禁用单位生产
替换效果 = 替换触发.add_effect(Effect.ENABLE_DISABLE_OBJECT)
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.enabled_or_victory = # 启用或禁用
替换效果.item_id = # 生产位置
# 启用或禁用科技
替换效果 = 替换触发.add_effect(Effect.ENABLE_DISABLE_TECHNOLOGY)
替换效果.player_source = # 起始玩家
替换效果.technology = # 科技 ID
替换效果.enabled_or_victory = # 启用或禁用
替换效果.item_id = # ?
# 修改生产成本
替换效果 = 替换触发.add_effect(Effect.CHANGE_OBJECT_COST)
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.food = # 木材成本
替换效果.wood = # 食物成本
替换效果.stone = # 石料成本
替换效果.gold = # 黄金成本
# 设置玩家可见
替换效果 = 替换触发.add_effect(Effect.SET_PLAYER_VISIBILITY)
替换效果.player_source = # 起始玩家
替换效果.player_target = # 对象玩家
替换效果.visibility_state = # 可见模式
# 改变单位头像
替换效果 = 替换触发.add_effect(Effect.CHANGE_OBJECT_ICON)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.location_x =
替换效果.location_y = # 位置坐标 xy
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.object_list_unit_id_2 = # 头像 ID
替换效果.selected_object_id = # 选择单位地图 ID
# 替换物件
替换效果 = 替换触发.add_effect(Effect.REPLACE_OBJECT)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.player_target = # 对象玩家
替换效果.location_x =
替换效果.location_y = # 位置坐标 xy
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_group = # 物件组
替换效果.object_type = # 物件类型
替换效果.object_list_unit_id_2 = # 目标单位固有 ID
替换效果.selected_object_id = # 选择单位地图 ID
# 改变物件描述
替换效果 = 替换触发.add_effect(Effect.CHANGE_OBJECT_DESCRIPTION)
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.string_id = # 文本 ID
替换效果.message = "" # 文本
# 改变玩家名称
替换效果 = 替换触发.add_effect(Effect.CHANGE_PLAYER_NAME)
替换效果.player_source = # 起始玩家
替换效果.string_id = # 文本 ID
替换效果.message = "" # 文本
# 改变训练位置
替换效果 = 替换触发.add_effect(Effect.CHANGE_TRAIN_LOCATION)
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.object_list_unit_id_2 = # 目标单位固有 ID
替换效果.button_location = # 按钮位置
# 改变训练位置
替换效果 = 替换触发.add_effect(Effect.CHANGE_RESEARCH_LOCATION)
替换效果.player_source = # 起始玩家
替换效果.technology = # 科技 ID
替换效果.object_list_unit_id_2 = # 目标单位固有 ID
替换效果.button_location = # 按钮位置
# 改变文明名称
替换效果 = 替换触发.add_effect(Effect.CHANGE_CIVILIZATION_NAME)
替换效果.player_source = # 起始玩家
替换效果.string_id = # 文本 ID
替换效果.message = "" # 文本
# 产生驻扎单位
替换效果 = 替换触发.add_effect(Effect.CREATE_GARRISONED_OBJECT)
# 替换效果.number_of_units_selected = # ?选择单位数目
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
替换效果.area_1_x =
替换效果.area_1_y = # 起始范围坐标 xy
替换效果.area_2_x =
替换效果.area_2_y = # 终止范围坐标 xy
替换效果.object_list_unit_id_2 = # 目标单位固有 ID
替换效果.selected_object_id = # 选择单位地图 ID
# 应答 AI 信号
替换效果 = 替换触发.add_effect(Effect.ACKNOWLEDGE_AI_SIGNAL)
替换效果.ai_signal_value = # 应答 AI 信号
# 修改属性
替换效果 = 替换触发.add_effect(Effect.MODIFY_ATTRIBUTE)
替换效果.quantity = # 数值(攻击护甲修改需*256)
替换效果.object_list_unit_id = # 物件固有 ID
替换效果.player_source = # 起始玩家
# 替换效果.item_id = # 物件ID
替换效果.operation = # 改变方式
# 设置 = 1;增加 = 2;减少 = 3;相乘 = 4;相除 = 5
替换效果.object_attributes = # 物件属性
# 修改资源
替换效果 = 替换触发.add_effect(Effect.MODIFY_RESOURCE)
替换效果.quantity = # 数值
替换效果.tribute_list = # 资源 ID
替换效果.player_source = # 起始玩家
替换效果.operation = # 改变方式
# 设置 = 1;增加 = 2;减少 = 3;相乘 = 4;相除 = 5
# 根据变量修改资源
替换效果 = 替换触发.add_effect(Effect.MODIFY_RESOURCE_BY_VARIABLE)
替换效果.tribute_list = # 资源 ID
替换效果.player_source = # 起始玩家
替换效果.operation = # 改变方式
# 设置 = 1;增加 = 2;减少 = 3;相乘 = 4;相除 = 5
替换效果.from_variable = # 变量 ID
# 修改变量
替换效果 = 替换触发.add_effect(Effect.CHANGE_VARIABLE)
替换效果.quantity = # 数值
替换效果.operation = # 改变方式
# 设置 = 1;增加 = 2;减少 = 3;相乘 = 4;相除 = 5
替换效果.from_variable = # 变量 ID
替换效果.message = "" # 文本
# 清除定时器
替换效果 = 替换触发.add_effect(Effect.CLEAR_TIMER)
替换效果.variable_or_timer = # 调用定时器 ID
接下来,我用一个示例,来帮助大家理解条件和效果代码写法。
首先定义一个触发:
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大典查找。
class DiplomacyState(IntEnum): # 外交信息
ALLY = 0 # 盟友=0
NEUTRAL = 1 # 中立=1
ENEMY = 3 # 敌人=3
class Operator(IntEnum): # 数值运算
SET = 1 # 设置=1
ADD = 2 # 增加=2
SUBTRACT = 3 # 减少=3
MULTIPLY = 4 # 相乘=4
DIVIDE = 5 # 相除=5
class ButtonLocation(IntEnum): # 建筑内位置编号
LOCATION_0_0 = 0 # 0
LOCATION_1_0 = 2 # 2
LOCATION_2_0 = 3 # 3
LOCATION_3_0 = 4 # 4
LOCATION_4_0 = 5 # 5
LOCATION_0_1 = 6 # 6
LOCATION_1_1 = 7 # 7
LOCATION_2_1 = 8 # 8
LOCATION_3_1 = 9 # 9
LOCATION_4_1 = 10 # 10
LOCATION_0_2 = 11 # 11
LOCATION_1_2 = 12 # 12
LOCATION_2_2 = 13 # 13
LOCATION_3_2 = 14 # 14
# LOCATION_4_2 = 15? (Actually placed at 0_0 at the moment)
class PanelLocation(IntEnum): #显示信息位置
TOP = 0 # 0
"""Panel at the top of the screen. ~13% from the top"""
BETWEEN = 1 # 1
"""Panel between the top and the center of the screen. ~33% from the top"""
CENTER = 2 # 2
"""Panel close to the center of the screen. ~45% from the top"""
class TimeUnit(IntEnum): # 时间类型
YEARS = 2 # 年(游戏)=2
"""In-Game years. A year is 5 seconds in-game time."""
MINUTES = 1 # 分=1
"""In-Game minutes."""
SECONDS = 0 # 秒=0
"""In-Game seconds."""
class VisibilityState(IntEnum): # 是否可视
VISIBLE = 0 # 可视=0
EXPLORED = 1 # 已探索=1
INVISIBLE = 2 # 不可视=2
class DifficultyLevel(IntEnum): # 游戏难度
EASIEST = 4 # 最易=4
STANDARD = 3 # 标准=3
MODERATE = 2 # 中等=2
HARD = 1 # 困难=1
HARDEST = 0 # 极难=0
# EXTREME = 5# ???
class TechnologyState(IntEnum): # 科技属性
DISABLED = 4 # 不可用=4
NOT_READY = 3 # 暂时不可研发=3
READY = 2 # 可研发=2
RESEARCHING = 1 # 研发中=1
DONE = 0 # 研发完毕=0
# QUEUED = 5# ???
class Comparison(IntEnum): # 数值比较
EQUAL = 0 # 相等 =0
LESS = 1 # < =1
LARGER = 2 # > =2
LESS_OR_EQUAL = 3 # <= =3
LARGER_OR_EQUAL = 4 # >= =4
class ObjectAttribute(IntEnum): # 单位属性
HIT_POINTS = 0 # 生命值
LINE_OF_SIGHT = 1 # 视野
GARRISON_CAPACITY = 2 # 驻扎容量
UNIT_SIZE_X = 3 # 单位尺寸(碰撞体积X)
UNIT_SIZE_Y = 4 # 单位尺寸(碰撞体积Y)
MOVEMENT_SPEED = 5 # 移动速度
ROTATION_SPEED = 6 # 旋转速度
ARMOR = 8 # 护甲(或许有特殊计算方法?)
ATTACK = 9 # 攻击力(或许有特殊计算方法?)
ATTACK_RELOAD_TIME = 10 # 攻击间隔(攻击重新加载时间)
ACCURACY_PERCENT = 11 # 准确度百分比(命中率百分比)
MAX_RANGE = 12 # 最大射程
WORK_RATE = 13 # 工作效率
CARRY_CAPACITY = 14 # 运载能力(资源携带能力)
BASE_ARMOR = 15 # 基础护甲(默认1000点)
PROJECTILE_UNIT = 16 # 投射物 ID
ICON_GRAPHICS_ANGLE = 17 # 图标角度
TERRAIN_DEFENSE_BONUS = 18 # 地形防御奖励(地形伤害加成 ID)
ENABLE_SMART_PROJECTILES = 19 # 启用智能炮弹(弹道学模式)
MINIMUM_RANGE = 20 # 最小射程
ARNOUNT_OF_1ST_RESOURCES = 21 # 资源储备(首位资源储存)
BLAST_WIDTH = 22 # 爆炸广度(溅射半径)
SEARCH_RADIUS = 23 # 搜索半径
HERO_STATUS = 40 # 英雄状态
FRAME_DELAY = 41 # 帧延迟
TRAIN_LOCATION = 42 # 训练位置
TRAIN_BUTTON = 43 # 训练按钮
BLAST_LEVEL = 44 # 爆炸等级(攻击伤害等级)
OBJECT_NAME_ID = 50 # 单位名称(字符串 ID)
SHORT_DESCRIPTION_ID = 51 # 简短介绍(字符串 ID)
TERRAIN_RESTRICTION_ID = 53 # 地形限制 ID
DEAD_UNIT_ID = 57 # 死亡单位 ID
RESOURCE_COSTS = 100 # 花费成本
TRAIN_TIME = 101 # 训练时间
TOTAL_MISSILES = 102 # 投射单位总数(投射单位初数量)
FOOD_COSTS = 103 # 食物成本
WOOD_COSTS = 104 # 木材成本
GOLD_COSTS = 105 # 黄金成本
STONE_COSTS = 106 # 石料成本
MAX_TOTAL_MISSILES = 107 # 最大投射物数量
REGENERATION_RATE = 109 # 再生率(再生间隔)
class Attribute(IntEnum): # 资源ID
FOOD_STORAGE = 0
WOOD_STORAGE = 1
STONE_STORAGE = 2
GOLD_STORAGE = 3
POPULATION_HEADROOM = 4
CONVERSION_RANGE = 5
CURRENT_AGE = 6
RELICS_CAPTURED = 7
UNUSED_RESOURCE_008 = 8
TRADE_GOODS = 9
UNUSED_RESOURCE_010 = 10
CURRENT_POPULATION = 11
CORPSE_DECAY_TIME = 12
REMARKABLE_DISCOVERY = 13
MONUMENTS_CAPTURED = 14
MEAT_STORAGE = 15
BERRY_STORAGE = 16
FISH_STORAGE = 17
UNUSED_RESOURCE_018 = 18
TOTAL_UNITS_OWNED = 19
UNITS_KILLED = 20
TECHNOLOGY_COUNT = 21
PERCENT_MAP_EXPLORED = 22
CASTLE_AGE_TECH_ID = 23
IMPERIAL_AGE_TECH_ID = 24
FEUDAL_AGE_TECH_ID = 25
ATTACK_WARNING_SOUND_ID = 26
ENABLE_MONK_CONVERSION = 27
ENABLE_BUILDING_CONVERSION = 28
UNUSED_RESOURCE_029 = 29
UNUSED_RESOURCE_030 = 30
UNUSED_RESOURCE_031 = 31
BONUS_POPULATION_CAP = 32
FOOD_MAINTENANCE = 33
FAITH = 34
FAITH_RECHARGING_RATE = 35
FARM_FOOD_AMOUNT = 36
CIVILIAN_POPULATION = 37
UNUSED_RESOURCE_038 = 38
ALL_TECHS_ACHIEVED = 39
MILITARY_POPULATION = 40
CONVERSIONS = 41
STANDING_NDERS = 42
RAZINGS = 43
KILL_RATIO = 44
SURVIVAL_TO_FINISH = 45
TRIBUTE_INEFFICIENCY = 46
GOLD_MINING_PRODUCTIVITY = 47
TOWN_CENTER_UNAVAILABLE = 48
GOLD_COUNTER = 49
REVEAL_ALLY = 50
UNUSED_RESOURCE_051 = 51
MONASTERIES = 52
TRIBUTE_SENT = 53
ALL_MONUMENTS_CAPTURED = 54
ALL_RELICS_CAPTURED = 55
ORE_STORAGE = 56
KIDNAP_STORAGE = 57
DARK_AGE_TECH_ID = 58
UNUSED_RESOURCE_059 = 59
UNUSED_RESOURCE_060 = 60
UNUSED_RESOURCE_061 = 61
BUILDING_HOUSING_RATE = 62
TAX_GATHER_RATE = 63
GATHER_ACCUMULATOR = 64
SALVAGE_DECAY_RATE = 65
UNUSED_RESOURCE_066 = 66
CAN_CONVERT = 67
HIT_POINTS_KILLED = 68
KILLED_P1 = 69
KILLED_P2 = 70
KILLED_P3 = 71
KILLED_P4 = 72
KILLED_P5 = 73
KILLED_P6 = 74
KILLED_P7 = 75
KILLED_P8 = 76
CONVERSION_RESISTANCE = 77
TRADE_VIG_RATE = 78
STONE_MINING_PRODUCTIVITY = 79
QUEUED_UNITS = 80
TRAINING_COUNT = 81
START_WITH_UNIT_444_PTWC = 82
BOARDING_RECHARGE_RATE = 83
STARTING_VILLAGERS = 84
RESEARCH_COST_MODIFIER = 85
RESEARCH_TIME_MODIFIER = 86
CONVERT_BOATS = 87
FISH_TRAP_FOOD_AMOUNT = 88
HEAL_RATE_MODIFIER = 89
HEALING_RANGE = 90
STARTING_FOOD = 91
STARTING_WOOD = 92
STARTING_STONE = 93
STARTING_GOLD = 94
ENABLE_PTWC_KIDNAP_LOOT = 95
BERSERKER_HEAL_TIMER = 96
DOMINANT_SHEEP_CONTROL = 97
BUILDING_COST_SUM = 98
TECH_COST_SUM = 99
RELIC_INCOME_SUM = 100
TRADE_INCOME_SUM = 101
P1_TRIBUTE = 102
P2_TRIBUTE = 103
P3_TRIBUTE = 104
P4_TRIBUTE = 105
P5_TRIBUTE = 106
P6_TRIBUTE = 107
P7_TRIBUTE = 108
P8_TRIBUTE = 109
P1_KILL_VALUE = 110
P2_KILL_VALUE = 111
P3_KILL_VALUE = 112
P4_KILL_VALUE = 113
P5_KILL_VALUE = 114
P6_KILL_VALUE = 115
P7_KILL_VALUE = 116
P8_KILL_VALUE = 117
P1_RAZINGS = 118
P2_RAZINGS = 119
P3_RAZINGS = 120
P4_RAZINGS = 121
P5_RAZINGS = 122
P6_RAZINGS = 123
P7_RAZINGS = 124
P8_RAZINGS = 125
P1_RAZING_VALUE = 126
P2_RAZING_VALUE = 127
P3_RAZING_VALUE = 128
P4_RAZING_VALUE = 129
P5_RAZING_VALUE = 130
P6_RAZING_VALUE = 131
P7_RAZING_VALUE = 132
P8_RAZING_VALUE = 133
STANDING_CASTLES = 134
HIT_POINTS_RAZED = 135
KILLS_BY_P1 = 136
KILLS_BY_P2 = 137
KILLS_BY_P3 = 138
KILLS_BY_P4 = 139
KILLS_BY_P5 = 140
KILLS_BY_P6 = 141
KILLS_BY_P7 = 142
KILLS_BY_P8 = 143
RAZINGS_BY_P1 = 144
RAZINGS_BY_P2 = 145
RAZINGS_BY_P3 = 146
RAZINGS_BY_P4 = 147
RAZINGS_BY_P5 = 148
RAZINGS_BY_P6 = 149
RAZINGS_BY_P7 = 150
RAZINGS_BY_P8 = 151
VALUE_KILLED_BY_OTHERS = 152
VALUE_RAZED_BY_OTHERS = 153
KILLED_BY_OTHERS = 154
RAZED_BY_OTHERS = 155
TRIBUTE_FROM_P1 = 156
TRIBUTE_FROM_P2 = 157
TRIBUTE_FROM_P3 = 158
TRIBUTE_FROM_P4 = 159
TRIBUTE_FROM_P5 = 160
TRIBUTE_FROM_P6 = 161
TRIBUTE_FROM_P7 = 162
TRIBUTE_FROM_P8 = 163
VALUE_CURENT_UNITS = 164
VALUE_CURRENT_BUILDINGS = 165
FOOD_TOTAL = 166
WOOD_TOTAL = 167
STONE_TOTAL = 168
GOLD_TOTAL = 169
TOTAL_VALUE_OF_KILLS = 170
TOTAL_TRIBUTE_RECEIVED = 171
TOTAL_VALUE_OF_RAZINGS = 172
TOTAL_CASTLES_BUILT = 173
TOTAL_WONDERS_BUILT = 174
TRIBUTE_SCORE = 175
CONVERT_MIN_ADJUSFIENT = 176
CONVERT_MAX_ADJUSTMENT = 177
CONVERT_RESIST_MIN_ADJUSTMENT = 178
CONVERT_RESIST_MAX_ADJUSTMENT = 179
CONVERT_BUILDING_MIN = 180
CONVERT_BUILDING_MAX = 181
CONVERT_BUILDING_CHANCE = 182
REVEAL_ENEMY = 183
VALUE_WONDERS_CASTLES = 184
FOOD_SCORE = 185
WOOD_SCORE = 186
STONE_SCORE = 187
GOLD_SCORE = 188
CHOPPING_PRODUCTIVITY = 189
FOOD_GATHERING_PRODUCTIVITY = 190
RELIC_GOLD_PRODUCTION_RATE = 191
CONVERTED_UNITS_DIE = 192
THEOCRACY = 193
CRENELLATIONS = 194
CONSTRUCTION_RATE_MODIFIER = 195
HUN_WONDER_DISCOUNT = 196
SPIES_DISCOUNT = 197
UNUSED_RESOURCE_198 = 198
UNUSED_RESOURCE_199 = 199
UNUSED_RESOURCE_200 = 200
UNUSED_RESOURCE_201 = 201
UNUSED_RESOURCE_202 = 202
UNUSED_RESOURCE_203 = 203
UNUSED_RESOURCE_204 = 204
FEITORIA_FOOD_PRODUCTIVITY = 205
FEITORIA_WOOD_PRODUCTIVITY = 206
FEITORIA_STONE_PRODUCTIVITY = 207
FEITORIA_GOLD_PRODUCTIVITY = 208
REVEAL_ENEMY_TOWN_CENTERS = 209
RELICS_VISIBLE_ON_MAP = 210
ELEVATION_HIGHER_BONUS = 211
ELEVATION_LOWER_BONUS = 212
RAIDING_PRODUCTIVITY = 213
MERCENARY_KIPCHAK_COUNT = 214
MERCENARY_KIPCHAK_LIMIT = 215
SHEPHERD_PRODUCTIVITY = 216
SHARED_LINE_OF_SIGHT = 217
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)
好,很有精神!(指用上这个工具以后可以大量制造触发,完成以前受限于工作量而难以完成的各种富有创新精神的触发群) 本帖可称目前撅腚版最牛B教程,甚至不输cly的json教程,是撅腚版技术层面的一次核心突破,即使是新人也能很快上手,运用这些技术做出有亮点的战役。 好,很有精神!(当c++帝国遇上python的奇妙反应) DE大典里没有单位属性,我就整理了一下注释。希望你可以补充进帖子里~
(搜索“单位属性”即可快速定位到你帖子里的相应位置)
HIT_POINTS = 0 # 生命值
LINE_OF_SIGHT = 1 # 视野
GARRISON_CAPACITY = 2 # 驻扎容量
UNIT_SIZE_X = 3 # 单位尺寸(碰撞体积X)
UNIT_SIZE_Y = 4 # 单位尺寸(碰撞体积Y)
MOVEMENT_SPEED = 5 # 移动速度
ROTATION_SPEED = 6 # 旋转速度
ARMOR = 8 # 护甲(或许有特殊计算方法?)
ATTACK = 9 # 攻击力(或许有特殊计算方法?)
ATTACK_RELOAD_TIME = 10 # 攻击间隔(攻击重新加载时间)
ACCURACY_PERCENT = 11 # 准确度百分比(命中率百分比)
MAX_RANGE = 12 # 最大射程
WORK_RATE = 13 # 工作效率
CARRY_CAPACITY = 14 # 运载能力(资源携带能力)
BASE_ARMOR = 15 # 基础护甲(默认1000点)
PROJECTILE_UNIT = 16 # 投射物 ID
ICON_GRAPHICS_ANGLE = 17 # 图标角度
TERRAIN_DEFENSE_BONUS = 18 # 地形防御奖励(地形伤害加成 ID)
ENABLE_SMART_PROJECTILES = 19 # 启用智能炮弹(弹道学模式)
MINIMUM_RANGE = 20 # 最小射程
ARNOUNT_OF_1ST_RESOURCES = 21 # 资源储备(首位资源储存)
BLAST_WIDTH = 22 # 爆炸广度(溅射半径)
SEARCH_RADIUS = 23 # 搜索半径
HERO_STATUS = 40 # 英雄状态
FRAME_DELAY = 41 # 帧延迟
TRAIN_LOCATION = 42 # 训练位置
TRAIN_BUTTON = 43 # 训练按钮
BLAST_LEVEL = 44 # 爆炸等级(攻击伤害等级)
OBJECT_NAME_ID = 50 # 单位名称(字符串 ID)
SHORT_DESCRIPTION_ID = 51 # 简短介绍(字符串 ID)
TERRAIN_RESTRICTION_ID = 53 # 地形限制 ID
DEAD_UNIT_ID = 57 # 死亡单位 ID
RESOURCE_COSTS = 100 # 花费成本
TRAIN_TIME = 101 # 训练时间
TOTAL_MISSILES = 102 # 投射单位总数(投射单位初数量)
FOOD_COSTS = 103 # 食物成本
WOOD_COSTS = 104 # 木材成本
GOLD_COSTS = 105 # 黄金成本
STONE_COSTS = 106 # 石料成本
MAX_TOTAL_MISSILES = 107 # 最大投射物数量
REGENERATION_RATE = 109 # 再生率(再生间隔)
newtonerdai 发表于 2020-11-2 01:16
DE大典里没有单位属性,我就整理了一下注释。希望你可以补充进帖子里~
(搜索“单位属性”即可快速定位到 ...
好,明天我添加进常数列表里~ 一脸懵懂进来然后一脸懵懂地走开{:158:} 不错(*๓´╰╯`๓)♡可以拿来解读文件格式 很具有潜力的触发工具,关于最后的使用单位绘图,我之前做过一些,也有一些经验,不过是在红警里的。
比如在地图上绘制迷宫、图案、文字、图像等。但红警2的单位不能像帝国那样密铺,只能按tile来排列,比较遗憾。
我是谁004 发表于 2020-11-2 07:17
不错(*๓´╰╯`๓)♡可以拿来解读文件格式
{:164:}这工具得在程序员手里才能开发得好,我就只会最基础的应用 戴子玲 发表于 2020-11-2 10:53
很具有潜力的触发工具,关于最后的使用单位绘图,我之前做过一些,也有一些经验,不过是在红警里的。
比如 ...
我也想到了读取图片像素点,得到位置矩阵,然后输出代码,但我不会就没写上去……
我还没测试过他的坐标可以精确到多少,我输出的时候就直接把f%输出上去了,也不知道精确到几位小数 戴子玲 发表于 2020-11-2 10:53
很具有潜力的触发工具,关于最后的使用单位绘图,我之前做过一些,也有一些经验,不过是在红警里的。
比如 ...
这种以前也做过,不算很完善
https://www.hawkaoe.net/bbs/forum.php?mod=viewthread&tid=135073&highlight=rio {:149:}学习一下,代工绘图的时代来临了么 本帖最后由 砖烧白开水 于 2020-12-30 01:25 编辑
好了,在用了 太牛了,完全看不懂,没基础。
页:
[1]